择维士日志查询和处理语法采用流行的类似Splunk或Sumologic的流式查询语法,一个查询语句可以分为以下几大部分
- 日志过滤部分:对日志标签或日志内容进行过滤
- 日志处理部分:对过滤的日志进行转换、分析和归集处理等
- 日志显示选项:对处理后的数据进行合理展示
以下将详细介绍我们的日志查询和处理语法,如果想快速使用我们的日志查询语法,可以直接查看或下载以下链接:
基本语法
择维士日志查询通过函数式的语法,使用流式处理函数完成对日志的处理,其基本语法格式如下
{label='label1'} "keyword1" and "keyword2" | processorFunc1 [args...] | processorFunc2 [args...] /as displayType
在详细介绍各种过滤方式和处理函数之前,我们需要看看我们语法中可能出现的各种字符串。在我们的语法中,无论是标签值,关键字还是处理函数参数中都会用到字符串,我们支持三种类型的基本字符串格式和专门用于正则表达式的字符串,用户可以根据实际情况选用合适的字符串格式来构造日志查询和处理语句。
双引号字符串
这是最基本的字符串,也是最常用的格式。字符串用双引号进行引用,中间不应该出现双引号。 以下为合法的双引号字符串
"error"
"Error"
"He's great"
"/api/ping"
以下双引号字符串为非法格式
"invalid "double quote""
单引号字符串
如果字符串中有双引号出现,为了方便,我们可以使用单引号来定义字符串,但此时中间不应该出现单引号。 以下为合法的单引号字符串
‘Error’
‘The "test" string is OK'
'/api/ping'
以下为非法的单引号字符串
'invalid 'single quote''
反引号字符串
当字符串中即有双引号又有单引号出现时,我们可以使用反引号来定义字符串。与双引号或单引号字符串一样,此时字符串不能包含反引号。 以下为合法的反引号字符串
`Error`
`The "double quoted" string and 'single quoted' string`
`/api/ping`
以下反引号字符串为非法格式
`Illegal `back quote``
正则表达式字符串
为了方便定义正则表达式,我们支持用’/’符合定义的满足RE2语法格式的正则表达式。所有的正则表达式都应该用这种方式进行定义。
例如
/.*mysql.*/
/192\.168\.3\.\d{1,3}/
具体RE2语法格式请参看 https://github.com/google/re2/wiki/Syntax。
日志过滤
日志过滤时为了方便在查看或处理日志时,将不需要的日志进行排除,以提高查询和处理效率。
日志过滤有两种类型
- 日志流过滤:每行日志都具有一组标签,具有相同标签和标签值的日志叫做一个日志流。我们可以通过对标签取值进行匹配来过滤掉不需要的日志流。
- 关键字过滤:关键字包含在每行日志的消息中,我们可以通过指定一个或多个关键字来对日志消息内容进行匹配,过滤掉不符合关键字要求的日志记录
每个查询都应该尽可能的使用日志过滤以减少需要查询或处理的日质量,从而提升日志查询和分析性能。
日志流过滤
日志流过滤又称为标签过滤,即对日志流中的标签和取值进行过滤。其基本过滤语法为
标签名 <操作符> 标签值操作符>
其中操作符可以为:
- = : 标签取值为给定的字符串
- !=: 标签取值与给定字符串不符
- ~ : 标签取值匹配给定的RE2表达式
- !~: 标签取值与给定的RE2表达式不匹配
多个条件可以通过or或and关键字进行组合,从而完成更复杂的标签过滤,如
_instanceName ~ "prod.*" and _category="database"
关键字过滤
与日志流过滤不同,关键字过滤作用于日志消息,通过一个或多个关键字,可以根据日志消息内容进一步降低日志处理量。
关键字可以是一个有单引号或双引号限定的字符串,也可以是有“/”字符限定的RE2正则表达式,即一个关键可以为下列形式之一:
- 单引号字符串:’keyword’
- 双引号字符串:”keyword”
- RE2正则表达式:/key?word/
我们同样可以通过or或and来组合关键字过滤条件,实现复杂的关键字过滤,此外可以在关键字前附加 not 用来对关键字进行反义,如
"Error" or "Exception"
或
/.*mysql.*/ and not "database"
语法支持
在对日志过滤时,我们有两种不同的语法
- 便捷语法:在语法开头直接定义日志流和关键字过滤条件
- 函数语法:通过使用一个或多个过滤函数完成日志流和关键字过滤
两种语法的处理效率在具体实现上没有差异,用户可以根据自身需要灵活使用。
快捷语法
快捷语法往往用于日志查询语句的最开头,此时用户可以简单快捷的对想过滤的日志进行出理,其语法格式如下
{ <日志流过滤> } <关键字过滤>
上述语法中,每个部分都是可选的,即
- 用户可以只对日志流进行过滤,此时只提供大括号内的日志流过滤语句即可
- 用户可以只对日志关键字进行过滤,无需大括号部分,只需要提供关键字过滤语法即可
- 用户也可以不用提供任何部分,直接开始使用函数对日志进行过滤或处理
以下为一些快捷过滤语法的实例:
{_source~/.*prod-\d+/ and _cagetory="webserver"} "Error" or "Warn"
{level="error" or level="warn"}
"/api/ping" and "error"
函数语法
使用函数语法,我们可以通过使用一系列过滤函数逐步定义日志过滤条件。这些函数语句可以出现在语法的开头或中间(在开始数值处理之前),从而更容易理解和使用。
我们支持的函数参加下面的”日志过滤函数“章节,以下为一些示例:
grep "Error" | grep -v "website"
match "Error" or "Warn" | filter _category="database"
filter _source!~/.*mysql.*/ and _level="error" | grep -v "test"
日志处理与展示
一般情况下,我们往往通过日志过滤即可完成日志查询和查找操作,但日志中有可能包含一些特殊的信息,需要我们做进一步加工、分析和处理才能方便的查看和展示,此时我们就需要 如果需要对日志做进一步分析处理时,我们则需要使用我们语法中的日志处理和展示语法。
日志处理和展示是通过日志处理函数和展示选项完成,我们在下面的日志函数章节中会有更详细的介绍。
日志函数
为了支持上述语法中的不同功能部分,我们的日志函数可大致分为以下几类:
- 日志过滤函数:用于对日志按标签或内容进行过滤
- 标签扩展函数:用于对日志内容进行各种变换或信息提取,方便后续处理
- 日志处理函数:用于将日志或日志标签转化为时序指标数据并进行各种归集操作,方便产生相关报表或进行内容展示
日志过滤函数
我们支持一下两个个函数对日志进行进一步过滤
- grep:用于对日志内容进一步用当个关键字过滤. 可以使用-v选项反向过滤关键字(即不包含关键字)
- grep 12345 - 找出日志中含有12345串的日志
- grep -v 12345 - 找出日志中不包含12345的日志
- match:用于对日志内容进行关键字过滤,与grep不同的是,它接受一个如前所述的复杂关键字过滤语法,从而能提供更丰富的处理能力。
- match (“Failed” or “failed”) and /192.168.\d{1,3}.\d{1,3}/
- match “error” and “network”
- filter: 用于对标签进行过滤和。它与match类似,预期用户输入一个上述日志流过滤语句对日志按标签行复杂过滤:
- filter service = “finance” - 过滤标签名service的值为finance的日志条目
- filter location != “chengdu” - 过滤标签名location取值不为chengdu的日志条目
- filter name~/Instance .*/ and _category=”website” - 过滤name标签取值匹配指定RE2正则表达式的日志条目且日志类型标签为website的日志
标签扩展函数
这类函数用于对日志进行变换或转换,从而能提取出更多的信息(如标签)方便后续过滤或处理。
我们目前支持以下函数
- json:如果日志内容为JSON格式的,可以用json将其进行解析,并将每一个field转换为一个标签
- pattern: 用来快速从日志中提取满足模式的部分并存储为一个标签。其语法为简单的从左自由匹配,用空白键做分隔符,对关心的部分通过用”<name>“模式进行命名,对不关心部分可以用特殊的”<_>"进行替代
pattern “\<ip\> - - <_> "\<method\> \<uri\> <_>" \<status\> \<size\> <_>"
- regexp:用满足RE2语法格式的正则表达式进行标签提取和扩展,正则表达式中应包含一个或多个模式提取语句,用于识别和提取标签。
regexp /POST (?P<uri>.*) .* (?P<code>\d+) (?P<size>\d+)/
- logfmt: 如果日志内容为logfmt格式,可以使用此函数将内容转换为按key=value格式的标签。关于logfmt格式,可参看这个链接:https://www.brandur.org/logfmt
日志处理函数
日志处理函数时可以对日志或其某个标签进行进一步分析和处理。为了便于理解和使用,在我们的语法中,我们将这个处理分为以下几步:
- 日志向量化:作为日志处理的第一步,我们需要将日志或其某个标签的值转换为数据向量(指标时序数据)
- 向量数据处理:在有了初始数据向量后,我们可以通过各种向量处理和归集函数对数据进行所需要的处理
- 数据展现:在获得最终的处理结果后,我们可以选择一种更合理且便于理解的方式呈现数据
日志向量化函数
择维士数象云通过range函数将日志或日志的某个指标按转换为指标时序数据,其语法格式如下:
range <向量时间间隔> use 转换函数 [<转换参数> ...]
range <标签> <向量时间间隔> use 转换函数 [<转换参数> ...] [without|by (标签集合)]
在上面语法中
- 向量时间间隔:用于指定将日志或标签进行向量化的时间间隔大小,可以设置为auto让系统自己决定或遵循通常的时间描述格式,用数字加单位表示制定时间间隔,如5m代表5分钟,1h代表1小时,1h30m代表一小时30分钟
- 转换函数:用于决定用什么样的方式对日志进行向量化,参见以下章节。
其中第一种格式用于将整个日志按其出现次数、评率进行指标数据化,用户可以在 ‘use’ 关键字后指定如下的处理方式:
- rate:每秒产生日志的条数(速率)
- count:指定单位时间范围中产生的日志条数
- bytes_rate: 每秒产生的日志字节数(速率)
- bytes_count:指定单位时间范围中产生的日志字节数
- absent:如果在指定时间范围内对应标签集合没有值,则返回一个值为1的向量集合,否则返回空向量。
第二种格式则是用于将日志中的某个数值指标(即指标值为数字或可转化为数字信息的内容)进行指标向量数据化,此时在 ‘use’ 关键字后可以使用如下的方式
- rate:标签值在单位时间范围内累加后的每秒变化速率
- sum:标签值在单位时间范围内累加的结果
- avg:标签值在单位时间范围内的平均值
- max:标签值在单位时间范围内的最大值
- min:标签值在单位时间范围内的最小值
- first:标签值在单位时间范围内的第一个非空值
- last:标签值在单位时间范围内的最后一个非空值
- stdvar:标签值在单位时间范围内的标准偏差
- stddev:标签值在单位时间范围内的标准方差
- quantile:标签值在单位时间范围内的指定百分位值,百分位通过第一个参数指定,缺省为90
- absent:如果在指定时间范围没有值,返回值为1的向量,否则返回空向量
在这种格式下,用户可以指定一个标签集合,用于对数据按指定标签集合进行过滤或归集后再进行数据向量化。
向量数据处理函数
在产生向量数据后,我们可以通过以下向量处理函数对数据进行进一步归集处理:
- sum:将指定标签集合的标签值进行累加
- avg:将指定标签集合的标签值求平均
- min:取指定标签集合的标签值的最小值
- max:取指定标签集合的标签值的最大值
- stdvar:求指定标签集合的标签值的平均偏差
- stddev:求指定标签集合的标签值的平均方差
- count:返回指定标签集合中的总标签值数量
- top:返回从高低排序中最大的前N个序列,N通过第一个参数进行指定,缺省为3
- bottom:返回从高低排序中最小的后N个序列,N通过第一个参数进行指定,缺省为3
这些函数统一的使用格式为
<函数名> [<函数参数> ...] (without|by) (标签集合)
数据展示选项
缺省情况下,我们对生成的向量数据按其指标集合通过线条进行展示,但用户可以根据数据特征和需要使用一下语句确定展示方式:
/as <显示方式>
其中,显示方式支持一下方式
- line或lines:将结果按线条方式展示,这是缺省指标数据的展示选项。
- pie或pies:将结果按饼图方式显示。
- bar或bars:将结果按柱状图方式显示。
- area或areas:将结果按重叠区域图方式显示。
- stack或stacks:将结果按堆积区域图方式显示。
在我们下一篇文档中,我们将通过分析一组所采集的nginx日志进一步熟悉上述语法。