SLS 查询新范式:使用 SPL 对日志进行交互式探索

作者:无哲

引言

在构建现代数据和业务系统的过程中,可观测性已经变得至关重要,日志服务(SLS)为 Log/Trace/Metric 数据提供了大规模、低成本、高性能的一站式平台服务,并提供数据采集、加工、投递、分析、告警、可视化等功能,从而全面提升企业在研发、运维、运营和安全等各种场景的数字化能力。

日志数据天然是非结构化的

日志(Log)数据作为可观测场景中最基础的数据类型之一,其最大的特点在于,日志数据是天然是非结构化的,具体与多种因素有关:

  • 来源多样性:日志数据种类繁多,不同来源的数据难以具有统一的 Schema
  • 数据随机性:比如异常事件日志、用户行为日志,往往天然就是随机的,难以预测的
  • 业务复杂度:不同的参与方对数据的理解不同,比如开发流程中打日志的一般是开发者,但分析日志的往往是运营和数据工程师,写日志过程中难以预见到后期具体的分析需求

图片

这些因素导致很多情况下可能并不存在一个理想的数据模型可以用来预先处理好日志数据,更常见的做法往往是直接存储原始数据,这可以称为是一种 Schema-on-Read 的做法,或者是所谓的寿司原则(The Sushi Principle:Raw data is better than cooked, since you can cook it in as many different ways as you like)。而这种“杂乱无章”的原始日志数据也给分析人员增加了难度,因为往往是需要对数据模型具有一定的先验知识,才能对数据进行比较好的结构化分析。

来自 Unix 管道的启发:交互式探查

在各种日志分析系统与平台出现之前,开发运维人员最传统的日志分析方式,是直接登录到日志文件所在的机器上去 grep 日志,并配合一系列 Unix 命令对日志进行分析处理。

比如要查看访问日志中 404 的来源 host,可能就会用到这样的命令:

grep 404 access.log | tail -n 10 | awk '{print $2}' | tr a-z A-Z

这条命令中通过 3 个管道操符,将 4 个 unix 命令行工具(关键词查找、日志截断、字段提取、大小写转换)连成了一条完整的处理栈。

值得注意的是,在使用这样的命令的时候,我们往往并不是一次性就写出完整的命令,而是写完一个命令之后就按下回车,观察执行输出的结果,然后再通过管道追加下一步的处理命令,继续执行,如此一直进行下去。

图片

这个过程中充分体现了 Unix 的设计哲学,通过管道将一个个小而美工具组合成强大的程序。同时从日志分析的角度看,我们可以获得这样的启发:

1)交互式、递进式的探查,每次在上一次的基础上叠加执行

2)探查的过程中往往不会处理全量数据,而是截取一小部分样本数据进行分析

3)探查过程中进行的各种处理操作,只影响本次查询的输出,并不改变原始数据

可以感受到,这种交互式探查的操作,对于日志数据是一种很好的探索方式,那么在 SLS 这样的云上日志平台,当面对海量的原始日志数据的时候,我们期望也能使用类似 Unix 管道这样的方式,在查询时先通过多级管道对数据一步步递进式的探查处理,帮助我们在杂乱无序的日志中挖掘出数据的规律,进而就可以更加带有目的性的去完成后续的加工清洗、消费投递、SQL 聚合分析等操作。

SPL-日志的统一处理语法

SPL(详见 SPL 概览 [ 1] ),即 SLS Processing Language,是 SLS 对日志查询、流式消费、数据加工、Logtail 采集、以及数据 Ingestion 等需要数据处理的场景,提供的统一的数据处理语法,这种统一性使得 SPL 可以在整个日志处理的生命周期内,实现 “Write Once,Run Anywhere” 的效果。

图片

SPL 基本语法如下:

<data-source> | <spl-expr> ... | <spl-expr> ...

其中< data-source >是数据源,对于日志查询的场景,指的就是索引查询语句。

< spl-expr >是 SPL 指令,支持正则取值、字段分裂、字段投影、数值计算等多种操作,具体参考 SPL 指令介绍 [ 2]

从语法定义上可以看到,SPL 天然是支持多级管道的。对于日志查询的场景来说,在索引查询语句之后,可以根据需要通过管道符不断追加 SPL 指令,每一步都可以点击查询查看当前的处理结果,从而获得类似 Unix 管道处理的体验。并且相比于 Unix 指令,SPL 具备更丰富的算子和函数,可以对日志进行更为灵活的调试分析和探索分析。

使用 SPL 查询日志

在日志查询场景中,SPL 是工作在扫描模式下的,可以直接针对非结构化的原始数据进行处理,不受是否创建索引以及索引类型的限制。扫描的时候按照实际扫描的数据量计费,详见扫描查询概述 [ 3]

统一的查询交互

扫描查询和索引查询虽然背后是不同的工作原理,但是在对用户的界面(控制台查询、GetLogs API)上,都是完全统一的交互。

在查询日志的时候,当输入索引查询语句的时候,就是通过索引查询。

图片

再继续输入管道符和 SPL 指令,就会直接自动按照扫描模式对索引过滤的结果进行处理(无须再通过一个“扫描模式”的按钮来额外指定),并且会提示当前处于 SPL 输入模式。

图片

更友好的语法提示

此外,在控制台查询的时候,会自动识别当前所处的语法模式,并对 SPL 相关指令和函数进行智能提示。

随着输入,下拉框自动提示相应的语法关键词、函数。

图片

图片

如果你一时忘记了某个语法怎么写,不用离开当前界面再去查找文档。直接移动光标放在某个关键词上,就会弹出详细的帮助信息。

图片

筛选字段获得更精简的视图

在打日志的时候,为了将来潜在的分析需求,我们一般会尽量多打一些相关信息到日志里,因此往往会发现最终单条日志中会存在比较多的字段。

这种情况下,在 SLS 控制台查询的时候,一条日志占据的空间太多,即使将顶部的柱状图和侧边的快速分析栏都折叠起来,在日志原文区域也只能同时看到一两条日志,要不断地滚动鼠标翻页才能看其他日志,使用起来较为不便。

图片

然而实际上我们在查询日志的时候,往往是带着某个目的去检索,这个时候一般是只关心其中的部分字段。这时就可以使用 SPL 中的 project 指令,只保留自己关心的字段(或者使用 project-away 指令,移除不需要看到的字段。这样不仅可以移除干扰,将注意力集中在当前要关注的字段上,而且由于字段精简了,也可以同时预览到更多条的日志。)

图片

实时计算出新的字段

前面提到过,由于写入日志的时候无法完全预见分析的需求,因此分析日志的时候,常常会需要对已有字段加工提取出新的字段,这可以通过 SPL 的 Extend 指令实现。

使用 Extend 指令,可以调用丰富的函数(这些大部分是和 SQL 语法通用的)进行标量处理。

Status:200 | extend urlParam=split_part(Uri, '/', 3)

同时也可以根据多个字段计算出新的字段,比如计算两个数字字段的差值。(注意字段默认是被视为 varchar,进行数字类型计算的时候要先通过 cast 转换类型)

Status:200 | extend timeRange = cast(BeginTime as bigint) - cast(EndTime as bigint

灵活的进行多维度过滤

索引查询只能根据进行关键词、多个关键词组成的短语、关键词末尾模糊等搜索方式,在扫描模式下,可以通过 where 质量可以按照各种条件过滤,这个是当前扫描查询已经具备的能力,在升级到 SPL 之后,where 可以放在任意一级管道,对计算出的新字段进行过滤,从而具备更灵活更强大的过滤能力。

比如,根据 BeginTime 和 EndTime 计算出 TimeRange 之后,可以再对这个计算后的值进行判断过滤。

Status:200 
| where UserAgent like '%Chrome%'
| extend timeRange = cast(BeginTime as bigint) - cast(EndTime as bigint)
| where timeRange > 86400

自由的展开半结构化数据

我们的日志中有的时候会存在某个字段本身是 json、csv 这种半结构化数据的情况,我们可以使用 extend 指令去提取其中某个子字段,但是如果要分析的子字段比较多,就会需要写大量的 json_extract_scalar 或者 regexp_extract 这样的字段提取函数,较为不便。

SPL 提供了 parse-json、parse-csv 这样的指令,可以将 json、csv 类型的字段,直接完全展开出为独立的字段,之后就可以直接对这些字段进行操作。省去了书写字段提取函数的开销,在交互式查询场景中这种写法是更为便捷的。

图片

所思即所见的沉浸式探索体验

让我们再通过一张动图来感受下,在探索日志的过程中,通过管道随着 SPL 指令的不断输入,对数据进行抽丝剥茧的逐级处理,每一步都可以将脑海中思考的处理步骤,物化在查询结果页面视图上,所思即所见,所见即所得,在一步步的交互式探索中,最终提取出我们需要分析的结构化信息。

图片

总结

由于数据来源的多样性和分析需求的不确定性,日志数据往往是直接以非结构化的原始数据存储,这为查询分析带来了一定挑战。

SLS 推出日志统一处理语言 SPL,在日志查询场景下,可以通过多级管道对数据进行交互式、递进式的探索,从而更便捷的发现数据特征,并更好的进行后续的结构化分析和加工消费等处理流程。

目前查询支持 SPL 的功能已经在各个地域上线,欢迎大家使用。如果有任何问题和需求,可以通过工单和支持群反馈给我们。SLS 将持续不断努力,打造一个更易用、更稳定、更强大的可观测分析平台。

相关链接:

[1] SPL 概览

https://help.aliyun.com/zh/sls/user-guide/spl-overview

[2] SPL 指令介绍

https://help.aliyun.com/zh/sls/user-guide/spl-instruction?spm=a2c4g.11186623.0.0.197c59d4pRrjml

[3] 扫描查询概述

https://help.aliyun.com/zh/sls/user-guide/scan-based-query-overview

参考链接:

[1] The Sushi Principle

https://www.datasapiens.co.uk/blog/the-sushi-principle

[2] Unix Commands, Pipes, and Processes

https://itnext.io/unix-commands-pipes-and-processes-6e22a5fbf749

[3] SPL 概述

https://help.aliyun.com/zh/sls/user-guide/spl-overview

[4] 扫描查询概述

https://help.aliyun.com/zh/sls/user-guide/scan-based-query-overview

[5] SLS 架构升级-更低成本、更高性能、更稳定和易用

https://login.alibaba-inc.com/ssoLogin.htm?APP_NAME=ata&BACK_URL=https%3A%2F%2Fata.atatech.org%2Farticles%2F11020158038&CONTEXT_PATH=%2F

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/564702.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

合约X—314协议系统开发

随着区块链技术的不断发展&#xff0c;越来越多的协议被提出和应用&#xff0c;其中X314协议就是其中之一。该协议旨在通过去中心化、安全性和可扩展性等方面&#xff0c;为区块链应用提供更好的支持。本文将从多个角度对X314协议进行深度解析&#xff0c;探讨其优势和不足&…

牛客NC162 二叉树中和为某一值的路径(三)【中等 dfs C++、Java、Go、PHP】

题目 题目链接&#xff1a; https://www.nowcoder.com/practice/965fef32cae14a17a8e86c76ffe3131f 思路 既然要找所有路径上节点和等于目标值的路径个数&#xff0c;那我们肯定先找这样的路径起点啊&#xff0c; 但是我们不知道起点究竟在哪里&#xff0c; 而且任意节点都有…

【机器学习】《机器学习建模基础》笔记

文章目录 单元0 前言单元1 数学建模与机器学习学习目标&#xff08;一&#xff09;什么是模型&#xff08;二&#xff09;数学模型的分类&#xff08;三&#xff09;数学建模的一般步骤&#xff08;四&#xff09;机器学习的概念&#xff08;五&#xff09;机器学习的分类&…

CTF-reverse-simpleRE(base64变表逆向)

题目链接 NSSCTF | 在线CTF平台 题目详情 [HUBUCTF 2022 新生赛]simple_RE 解题报告 下载得到的文件使用ida64分析&#xff0c;如果报错就换ida32&#xff0c;得到分析结果&#xff0c;有main函数就先看main main函数分析 main函数的逻辑看下来十分简单&#xff0c;因此关键…

机器学习(三)之监督学习2

前言&#xff1a; 本专栏一直在更新机器学习的内容&#xff0c;欢迎点赞收藏哦&#xff01; 笔者水平有限&#xff0c;文中掺杂着自己的理解和感悟&#xff0c;如果有错误之处还请指出&#xff0c;可以在评论区一起探讨&#xff01; 1.支持向量机&#xff08;Support Vector Ma…

混淆原理与实践指南

引言 &#x1f680; 在当今的软件开发领域&#xff0c;保护代码的安全性和保密性变得越来越重要。混淆&#xff08;Obfuscation&#xff09;技术作为一种保护代码的手段&#xff0c;在应对逆向工程和代码盗用方面发挥着关键作用。本文将深入探讨混淆的原理&#xff0c;以及如何…

【Flutter】One or more plugins require a higher Android SDK version.

问题描述 项目里多个组件需要更高版本的Android SDK One or more plugins require a higher Android SDK version.解决方案&#xff1a; 报错提示requires Android SDK version 34 按提示修改android项目app里build.gradle的compileSdkVersion 为34 android {compileSdkVe…

16.哀家要长脑子了!

目录 1. 707. 设计链表 - 力扣&#xff08;LeetCode&#xff09; 2.203. 移除链表元素 - 力扣&#xff08;LeetCode&#xff09; 3.206. 反转链表 - 力扣&#xff08;LeetCode&#xff09; 4.237. 删除链表中的节点 - 力扣&#xff08;LeetCode&#xff09; 5. 19. 删除链…

实测数据的功率谱估计

目录 1.脉搏数据1.1 数据1的结果1.2 数据2的结果 2.振动加速度数据 1.脉搏数据 1.1 数据1的结果 1.2 数据2的结果 2.振动加速度数据

宏基因组|使用CheckM2评估分箱质量

简介 CheckM2使用机器学习快速评估基因组bin质量 与CheckM1不同&#xff0c;CheckM2采用通用训练的机器学习模型&#xff0c;无论分类学谱系如何&#xff0c;均可用于预测基因组bin的完整性和污染情况。这使得它能够在训练集中纳入许多仅具有少数&#xff08;甚至只有一个&am…

WSL安装-问题解决

WslRegisterDistribution failed with error: 0x8004032d WslRegisterDistribution failed with error: 0x80080005 Error: 0x80080005 ??????? 解决&#xff1a; 1、 winr输入&#xff1a;optionalfeatures.exe 2、打开这两项

Navicat 干货 | 掌握 PostgreSQL 规则语法

PostgreSQL 规则提供了一种强大的机制&#xff0c;控制查询执行并在数据库内部实施数据操作。理解规则的语法和用法对于有效利用其功能至关重要。在上周的文章中&#xff0c;我们探讨了 PostgreSQL 规则的工作原理及其与触发器的区别。今天的文章将使用免费的 “dvdrental”示例…

​Game Maker 0.10:让创作、协作和游戏变得更简单

继去年 12 月成功发布 Game Maker 0.9 之后&#xff0c;我们又隆重推出 Game Maker 0.10。在 0.9 更新的主要增强功能基础上&#xff0c;该版本为创作者实现其愿景提供了更多改进和工具。 为此&#xff0c;The Sandbox 还正式启动了全球范围的创作者训练营&#xff0c;以帮助我…

初学python记录:力扣377. 组合总和 Ⅳ

题目&#xff1a; 给你一个由 不同 整数组成的数组 nums &#xff0c;和一个目标整数 target 。请你从 nums 中找出并返回总和为 target 的元素组合的个数。 题目数据保证答案符合 32 位整数范围。 提示&#xff1a; 1 < nums.length < 2001 < nums[i] < 1000nu…

双周总结#008 - AIGC

本周参与了公司同事对 AIGC 的分享会&#xff0c;分享了 AIGC 在实际项目中的实践经验&#xff0c;以及如何进行 AIGC 的落地。内容分几项内容&#xff1a; 什么是 AIGCAIGC 能做什么AIGC 工具 以年终总结为例&#xff0c;分享了哪些过程应用了 AIGC&#xff0c;以及 AIGC 落地…

一款pdf工具

下载链接&#xff1a;点击跳转&#xff1b; 它是一个installer&#xff0c;下好它之后&#xff0c;把网断掉&#xff0c;然后双击它&#xff0c;他会默认安装在C盘&#xff0c;安装时&#xff0c;浏览器可能会有一个弹窗&#xff0c;直接关掉并进入任务管理器杀掉所有smallerp…

go语言实现心跳机制样例

1、服务端代码&#xff1a; package mainimport ("fmt""net" )func handleClient(conn net.Conn) {defer conn.Close()fmt.Println("Client connected:", conn.RemoteAddr())// 读取客户端的数据buffer : make([]byte, 1024)for {n, err : conn…

如果备份了oradata文件,该如何还原Oracle数据呢?

程序员的公众号&#xff1a;源1024&#xff0c;获取更多资料&#xff0c;无加密无套路&#xff01; 最近整理了一波电子书籍资料&#xff0c;包含《Effective Java中文版 第2版》《深入JAVA虚拟机》&#xff0c;《重构改善既有代码设计》&#xff0c;《MySQL高性能-第3版》&…

C语言结构体,枚举,联合

系列文章目录 第一章 C语言基础知识 第二章 C语言控制语句 第三章 C语言函数详解 第四章 C语言数组详解 第五章 C语言操作符详解 第六章 C语言指针详解 第七章 C语言结构体详解 第八章 详解数据在内存中的存储 第九章 C语言指针进阶 文章目录 1. 结构体 1.1 声明结构…

URL解析

目录 URIURLURL语法相对URLURL中的转义 现在与未来PURL 在 URL出现之前&#xff0c;人们如果想访问网络中的资源&#xff0c;就需要使用不同的 应用程序&#xff0c;如共享文件需要使用 FTP程序&#xff0c;想要发送邮件必须使用 邮件程序&#xff0c;想要看新闻那只能使用…