高级搜索 -凯发k8国际|首页

j

spl

高级搜索

日志易提供高级搜索模式,您可以通过直接在搜索框输入命令,实现较为复杂的关联分析、建立新字段、对字段进行数值运算等。

使用方法

在搜索框中填入query串之后追加管道命令。

比如:apache.status:200 eval host=…. stats count by host

命令行功能

提供如下基本命令,在一定约束条件下可以组合使用。

1. eval
2. transaction
3. stats
4. sort
5. bucket
6. rename
7. where
8. limit
9. fields
10. 子查询
11. join
12. lookup
13. rollingstd
14. movingavg
15. save
16. top
17. parse
18. append
19. autoregress

1.eval

eval在原有日志中添加一个新的field,新字段将根据已有字段进行逻辑运算生成,如通过算术运算、字符串运算等方式。

命令行格式:

 eval field=eval_func(field_list)

支持操作符(按照优先级由低到高排列)

1)   (逻辑或) 二元操作符,操作数必须为布尔类型

2) &&(逻辑与) 二元操作符,操作数必须为布尔类型

3) !=(不等于)、==(等于)

4) >=、>、<=、<

5) 、- 算术加、减,支持数值类型, 另支持字符串

6) *、/、% 算术乘、除、余,支持整数类型

括号的支持:

支持(),小括号

支持函数

函数名 含义 使用方法
empty(x) 判断某个field是否为空 empty(field)
field:带检查字段名
如果存在返回false,否则返回true
比如:empty(apache.status)
abs(x) 返回某个field的绝对值 abs(field)
field:待检查字段名,必须是数值类型
比如:abs(apache.resp_len)
ceil(x) 向上取整 ceil(field)
field:待检查字段名,必须是数值类型
比如:ceil(apache.resp_len)
floor(x) 向下取整 floor(field)
field:待检查字段名,必须是数值类型
比如:floor(apache.resp_len)
min(x, y) 取两个field中较小的值 min(field1, field2)
field1、field2:待检查字段名,必须是数值类型
比如:min(apache.status, apache.resp_len)
max(x, y) 取两个field中较大的值 max(field1, field2)
field1、field2:待检查字段名,必须是数值类型
比如:max(apache.status, apache.resp_len)
log(x) 计算某个field的对数 log(field)
field:待检查字段名,必须是数值类型
比如:log(apache.resp_len)
coalesce(x, ...) 可以有任意个数的参数
依照参数的顺序选定结果值
如果参数存在,取其值;否则判断下一个参数;如果都不存在,返回null
coalesce(field1, field2, ...)
field1、field2:可以是任意字段
比如:coalesce(apache.status, apache.resp_len, apache.method)
if(x, y, z) 类似if else语句判断 if(field bool_operator value, result1, result2)
如果field的值与value通过布尔比较为真,返回result1,否则返回result2
result可以设置为数值类型或者字符串
bool_operator:== | != | > | >= | < | <=
比如:if(apache.status>200, "error", "ok")
result设置为字符串
if (apache.status>200, 1, 0)
result设置为数值
case(x, y, ... [, default, z]) 类似switch case,根据判断条件生成返回多个枚举值中的一个 case(field bool_operator value1, result1, field bool_operator value2, result2, ... [, default, default_result])
default_result可以不设置,如果不设置相当于null
比如:case(apache.status==200, "c1", apache.status==404, "c2", default, "c3")

例如使用以下语句进行搜索:

* | eval evalres=case(apache.status==200, 200, apache.status==301, 301, apache.status==302, 302, apache.status>=304, 304) 

可以看到以下结果:

该命令将建立新字段evalres,建立规则为根据日志中字段apache.status的值分类,大于304即为304,等于200即为200,等于301即为301,等于302即为302。选择表格视图,即可查看新建立的evalres字段。

2.transaction

一个transaction由一组相关的log组成,比如用户的一次搜索过程对应在整个系统中的所有日志等,transaction命令将具有相同字段的值组合成一个group,并在单个group内进行transaction的识别。

语法

transaction field_list [maxspan=] [maxevents=int] [maxopentxn=int] [maxopenevents=int] startswith=] [endswith=] [contains=]

field-list :: field [,field]*

timespan :: [s|m|h|d]

filterstring :: | eval_expression

eval_expression :: eval(bool_expression)

参数

maxspan:transaction第一条日志和最后一条日志的最大时间间隔

maxevents:单个transaction的最大日志条数

maxopentxn:用于控制内存使用,获取的最多分组,用于过滤的计算

maxopenevents:用于控制内存使用,单个transaction最多从es取的log的条数

note:maxopentxn和maxopenevents不应设置过大,可以减小查询时间间隔

startswith : 满足的条件的日志为一个新的transaction的第一条日志

endswith : 满足条件的记录为transaction最后一条日志

contains: 如果transaction中的任何一条日志包含或者满足bool-expression将保留该transaction,否则丢弃

示例

1)

* | transaction apache.clientip startswith="receive" endswith="response" maxevents=10 maxspan=5s

通过apache.clientip对日志进行分组,按照时间戳排序,包含receive的日志为一个新的transaction的第一条日志,包含response的为最后一日志,最多包含10条日志,日志的时间跨度最大为5s

2)

* | transaction apache.clientip endswith=eval(a_field == 200) maxevents=10 contains="error"

表示满足a_field == 200的日志为transaction的最后一条日志,每个transaction最多包含10条日志。如果transaction中的任意一条日志包含error字符串,则该transaction将被返回,否则该transaction被丢弃

3.stats

stats提供统计功能,可以根据设定字段进行group操作。

命令行格式:

stats stats_function(field) [as field] [by field_list]

field可以是event中已经提取的字段,也可以是eval命令生成的新字段。

比如:eval c=a b stats avg(c)

目前支持的函数为:

函数名 使用方法&含义 返回值
sum sum(apache.status)
参数只有一个,可以是已经解析的field,也可以是eval生成的新字段,field必须是数值型

统计field对应值的累加和
"sum(apache.status)":{
"as\_field":"",
"value":2.0057305165e10
}
如果设置了as\_field,返回值里就不在为空,比如命令行为“sum(apache.status) as sum_of\_status",返回值中会将as\_field设置为sum\_of\_status
min 使用方法同上

统计field对应值的最小值
同上
max 使用方法同上

统计field对应值的最大值
同上
avg 使用方法同上

统计field对应值的平均值
同上
count 使用方法同上

统计field的出现次数
同上
distinct\_count or dc 使用方法同上

统计field对应值去重之后的个数
同上
extend\_stat or es 使用方法同上

一次性计算出基于field的avg/count/max/min/sum/std\_deviation/variance/sum\_of\_squares值
"extended\_stat(apache.status)":{
"as\_field":"",
"avg":226.76832896353707,
"count":88448441,
"max":502,
"min":200,
"std\_deviation":68.74379972321682,
"sum":2.0057305165e10,
"sum\_of\_squares":4.966343257931e12,
"variance":4725.710000385745
}
top top(field, count)
field: 待统计的字段
count:返回个数

统计field内最多出现的若干个值
"top(apache.status)":{
    "as\_field":"top\_status",
    "buckets":[{
        "doc\_count":79473063,
        "key":"200"
     }, {
       "doc\_count":10397265,
       "key":"405"
     }],
   "total":91796729
}}]
histogram or hg hg(field, interval)
field: 待统计字段,必须为数值型
interval: 直方图间隔

直方图统计
"histogram(apache.status)":{
"as\_field":"",
"buckets":[
{
"doc\_count":80274444,
"key":200
},
{
"doc\_count":11522285,
"key":400
}
],
"interval":200
},
date\_histogram or dhg dhg(field, interval)
field: 待统计字段,数值当做以毫秒为单位的时间戳
interval: 时间间隔,描述方式如1m, 1d... 后缀有以下几种:y|m|w|d|h|m|s

时间直方图统计,可以认为是直方图统计的一种特殊形式
同上
range\_bucket or rb rb(field, (start, end), (start,end), ....)
field: 待统计字段,数值型
(start,end): 待统计区间,可以设置多个统计区间

区间统计
"range(apache.status)":{
    "as\_field":"",
    "buckets":[{
        "doc\_count":400,
        "from":205,
        "key":"205.0-302.0",
        "to":302
    },{
        "doc\_count":2450465,
        "from":402,
        "key":"402.0-500.0",
        "to":500
    }]}
pct pct(field, value1, value2...)
field: 待统计字段,必须是数值型

统计百分位为value1,value2时所对应的field值
"percentiles(apache.status)":{
"as\_field":"",
"values":{
"10.0":200,
"20.0":200,
"30.0":200
}
}
百分位为10%时,对应的值为200
管道命令样例:
* | stats pct(apache.status,1,5,25,50,75,95,99)
pct\_ranks pct\_ranks(field, value1, value2,....)

百分位统计,统计value值在整个field数值区间中的百分位
"percentile\_ranks(apache.status)":{
"as\_field":"",
"values":{
"249.0":86.57802705984146,
"308.0":87.20943559126225,
"401.0":88.03192145410496
}
}
管道命令样例:
* | stats pct\_ranks(apache.status,199,200,302,500)

例如使用以下语句搜索

   * | stats es(apache.status)

会得到以下统计数据:

通过表格可以看到apache.status的计数、最大值、最小值、求和、平均值、方差、平方和标准偏差。

4.sort

语法

sort by sort_item[, sort_item]*

sort_item :: [ -]field

表示增序,-表示降序,默认为降序

实现限制

sort命令在query之后,则by可以支持多个字段,不允许对query之后的eval字段做sort

sort命令在stats或者transaction之后,则by仅支持一个字段

示例

* | sort by  apache.status, raw_message_length
* | stats avg(raw_message_length) as avg_length, count(apache.clientip) as ip_count by appname | sort by ip_count
5.bucket

对字段进行分桶,将字段的连续值转换为离散的多个值集合,属于同一个集合的字段值将拥有同一个值,目前支持三种分桶方式:

1、 按照固定时间段切分

2、 指定ranges进行切分

3、 指定时间ranges进行切分

语法

bucket  span= [as ]
bucket  ranges= [as ]
bucket  timeranges= [as ]

示例

* | bucket timestamp span=1h as ts | stats avg(success_count) as avg_sucess_count by hostname, ts

对每个host,以小时为单位,统计成功数的平均值,按时间分桶之后,同一个桶内共享的值为这个桶的开始时间 注意:

1) 当时间为1s,1m,1h, 1d, 1w时,时间的切分是按照整秒,整分钟,整小时,整天,整星期方式分桶,如搜索时间为11:29-13:29,分桶单位为1h,则时间切分为三个桶,分别为[11:29:00-12:00:00),[12:00:00-13:00:00),[13:00, 13:29)

2) 其他情况,以起点时间开始时间段捉个切分,比如搜索时间为11:29-14:29,分桶单位为2h,则被分为两个桶,分别为[11:29-13:19),[13:19-14:29)

* | bucket apache.status ranges=((0, 200), (200, 400), (400, max)) as rs | stats count(apache.status) by rs

将apache.status按照左闭右开的区间[0,200), [200, 400), [400, )进行分桶,并分别统计status的个数。

* | bucket timestamp timeranges=((2015-12-20 18:00:00, 2015-12-20 19:00:00), (2015-12-21 18:00:00, 2015-12-21 19:00:00)) as trs | stats avg(latency) by trs

统计2015年,12月20日的18点到19点,和12月21日18点到19点两个时间段的latency的平均值

 * | bucket timestamp timeranges=((-2d, -1d), (-1d, max)) as trs | stats avg(latency) by trs

统计之前两天的latency的平均值。

6.rename

将src-name的字段,重命名为dest-name。

语法

rename  as 
       可以为field名,或者双引号字符串 **示例**
    ... | rename apache.status as "status from apache"
    ... | rename apache.status as status
7.where

针对单个结果执行表达式计算,如果表达式计算结果为true,则保留,否则丢弃。

**语法 **

where 

注意: 如果表达式执行的expression返回非bool的结果,或者执行过程中出错,则被认为是false

示例 … | where apache.status > 200 && apache.status < 400

8.limit命令

搜索结果中,保留前n条结果

语法 limit

示例 … | limit 10

搜索结果中仅返回前10条结果

9.fields

对搜索结果的字段进行挑选

语法 fields ...

注意: 暂时不支持通配符和 -修饰符

10.子查询

一个子查询常用于作为另外一个spl命令的参数,子查询被包含在双方括号中,将在外部命令执行之前被执行,执行的结果将作为外部spl的参数,大体上存在如下两种用途:

1) 参数化一个搜索(可以理解为query),使用子查询的结果作为query的搜索条件

2) 执行一个独立的搜索,将子查询的结果append(或者join等)到主查询的结果中

举例 查找apache日志中访问次数最多的ip地址的所有事件,可以采用如下写法

logtype:apache and [[ logtype:apache  | stats count(apache.clientip) as count_ by apache.clientip | sort by count_ | limit 1 | fields apache.clientip ]]

子查询返回结果为二维表格形式,行之间采用or关系,行中的列之间采用and关系。 假设子查询

 [[ logtype:apache  | stats count(xx) by apache.clientip, apache.method | fields apache.clientip apache.method ]] 

返回的结果为

apache.clientipapache.method
192.168.1.92   get
192.168.1.33   post

则表示的查询条件为

(apache.client:192.168.1.92 and apache.method:get) or (apache.client:192.168.1.33 and apache.method:post)

注意:

子查询的结果数对查询的性能影响非常大,目前默认的行限制为100条,列未做限制(后续会加上)

1) 子查询结果中的字段仅支持: 字符串类型和数值类型

2) 子查询中不允许出现以下命令:transaction,join

11.join

对查询的结果和子查询的结果进行类似sql的join

语法

join [type=inner|left|outer] [max=] [overwrite=false|true]  

注意:

1) 子查询的结果数决定了资源的消耗量,对于join的子查询的结果数默认限制为50000,可以通过配置文件修改,join.subsearch.max_count

2) join之后不能使用stats和transaction等统计命令。

示例

logtype:apache | stats avg(apache.status) by apache.clientip | join type=left apache.clientip [[ logtype:apache | stats sum(apache.status) by apache.clientip ]]
logtype:apache | fields apache.method apache.clientip | join type=left apache.clientip [[ logtype:apache | stats sum(apache.status) by apache.clientip ]]

12.lookup命令

使用lookup命令,可以将搜索结果中的一些字段映射为有意义的值,比如将搜索结果中的userid映射为username。

语法

lookup   on 

参数:

注意:

1)http和https地址不支持重定向

2)文件默认的大小限制为8m,配置项为lookup.max_download_size

3)下载超时为8s,配置项为:lookup.download_timeout

示例

假设外部csv文件有以下字段:userid, username, email, phone

 lookup email,username http://192.168.1.11/user.csv on id = userid

将搜索结果中的id字段和csv文件的userid进行关联,在搜索结果中增加userid, email, username字段

13.rollingstd

rollingstd命令提供了在一个指定的window下计算某个数值字段的标准差,默认情况rollingstd将创建一个字段_rolling_std(可通过命令指定)

语法

 rollingstd [,] [as ] [by ]

示例

7/15/2016 6:50:38 pm ... | bucket timestamp sum_resp_len by ts  | rollingstd sum_resp_len,10 as resp_len_rolling_std span=1m as ts | stats sum(apache.resp_len) as 

以分钟为单位统计apache返回的réponse的长度的和,以10为窗口计算rolling的标准差。以观察resp_len的波动情况。

14.movingavg

movingavg命令提供了在一个指定的window下计算某个数值字段的移动平均值,默认情况movingavg将创建一个字段_moving_avg

语法

movingavg [,window] [as ] [by ]

示例

 ... | bucket timestamp span=1m as ts | stats sum(apache.resp_len) as sum_resp_len by ts  | movingavg sum_resp_len,10 as moving_avg_resp_len

以分钟为单位统计apache返回的réponse的长度的和,以10为窗口计算移动平均值。得到一个每分钟的响应长度和的平滑后的值

15.save

可以将搜索的结果保存为文件,目前仅支持csv

语法

save 

示例

  *| stats avg(apache.latency) by hostname | save shared_directory/apache_latency.csv

按照hostname分别统计平均的latency,并输出到csv文件。

16.top

获取字段出现次数前n的值的集合,输出字段包括field

语法

 top   [by ] [countfield=] [percentfield=]

示例

 *| top 3 apache.clientip  countfield=clientip_count  percent=clientip_percent

返回top 3的clientip,同时clientip_count字段表示出现次数,clientip_percent表示所占百分比

 *| top 3 apache.clientip by apache.request_path

搜索结果按照request_path进行分组,每个分组内返回top 3的apache.clientip。

17.parse命令

parse命令用于搜索时支持动态抽取字段 语法

 pase [field=] ""

-:该字段将用于正则表达式匹配抽取,如果未指定field参数,默认为:raw_message

-:支持java的正则表达式语法,应该包括(?x)形式的named-capturing group,否则该正则表达式将被忽略

示例

 *| parse "(?\d \.\d \.\d \.\d )" | eval ip_str = "ip:"   ip_addr  | stats count(appname) by ip_str

从日志的原文中抽取ip地址,通过eval计算ip_str,并且按照ip_str分组并计算appname的个数。

logtype:apache | parse field=apache.request_path "^(?/[^/]*)" | stats count(appname) by outer_path

抽取request_path的第一级目录outer_path,并按照outer_path分组统计appname的个数 注意

由于抽取是在搜索的过程中实时进行,消耗资源大,耗时长,因此对于很常用的搜索字段不要使用parse命令抽取,考虑在入库前抽取。

18.append命令

将子查询的结果附加在主查询的结果后面

语法

append 

注意暂不允许对query的结果进行append

示例

starttime="-1w-1d/d" endtime="-1w/d"  logtype:apache | stats avg(apache.resp_len) as avg_resp_len | append [[ starttime="-1d/d" endtime="now/d" logtype:apache | stats avg(apache.resp_len) as avg_resp_len]]

假定今天为周三,则该语句表示,将上周二和本周二的apache.resp_len字段的平均值合并在一个表格中展示。

logtype:apache | stats count(apache.clientip)  | append [[ index=schedule * | stats count(apache.clientip) ]]

统计yotta索引中的apache.clientip的个数,结果表格中附加上schedule索引中的apache.clientip的个数,

19.autoregress命令

将当前事件之前的事件中的字段值拷贝到当前事件,改字段可以用于后续的表达式计算等。

语法

 autoregress [ as  ] p=|-

注意

autoregress产生的字段不可以用于统计

示例

 *| autoregress avg_resp_len p=1-2 | eval avg_ = (avg_resp_len   avg_resp_len_p2   avg_resp_len_p1) / 3

计算窗口为3的平均值

带有约束条件的命令行组合

1、transaction之后不能追加stats命令,同样stats命令之后不能追加transaction命令

2、transaction和stats之后可以追加eval和sort命令