查询语法

日志服务Project支持使用查询语句对存储在Logstore中的日志进行筛选。筛选结果可独立使用,也可以用于分析语句,进行更复杂的分析处理。本文介绍查询语句的语法结构,以及应用场景和具体示例。

基础语法

查询语句和分析语句以|分割。其格式为:

查询语句|分析语句

查询语句可单独使用,分析语句必须与查询语句一起使用。即分析功能是基于查询结果或全量数据进行的。

重要
  • 查询语句中建议不超过30个条件。

  • 分析语句中无需填写FROM子句和WHERE子句,默认分析当前Logstore中的数据。分析语句不支持使用offset,不区分大小写,末尾无需加分号。

语句类型

说明

查询语句

查询条件,可以为关键词、数值、数值范围、空格、星号(*)等。

如果为空格或星号(*),表示无过滤条件。

分析语句

对查询结果或全量数据进行计算和统计。日志服务支持的分析函数和语法,请参见:

查询和分析语句示例:

* | SELECT status, count(*) AS PV GROUP BY status
说明

本文中涉及的查询示例的原始日志请参见调试

查询语句编写思路

image

查询语句的编写流程可分为以下三步:

步骤一:确定查询方式

重要
  • 如需对Logstore中的日志进行查询,则必须首先创建索引。如需要对某个字段进行分析(SELECT语句),则必须创建字段索引。创建字段索引和全文索引的步骤,请参见字段索引

  • 不同的索引配置,会产生不同的查询和分析结果,如果同时创建了全文索引和字段索引,以字段索引的配置为准。

根据索引类型的不同,日志服务Project查询可分为全文查询和字段查询。全文查询和字段查询区别如下:

  • 如果只创建全文索引,则只能使用全文查询。

  • 如果已创建字段索引,则按以下规则查询:

    • doublelong类型:只能根据字段查询语法进行查询。

    • text类型:如您知晓关键词属于某个已创建索引的text类型字段,建议使用字段查询语法。如果不确定关键词的具体字段,请使用全文查询语法。

      • 如果没有创建全文索引,全文查询语法仅在字段索引是text类型的字段中查询。

      • 如果已创建全文索引,全文查询语法会从所有text类型索引中查询。

全文查询

全文查询不针对具体的字段进行查询,其查询语法为: keywords1 [ [ and | or | not ] keywords2 ] ...

keywords1 是需要查询的关键词,可以使用 *进行模糊匹配,也可以结合运算符如 andor 等联合其他查询条件一起查询。

  • 示例1

    如果您希望查询关键词为GET相关的日志。则查询语法:GET

  • 示例2

    如果您查询关键词为GETPOST相关的日志。则查询语法:GET or POST

字段查询

字段查询对应的字段类型包含textlongdoublejson,且针对具体的字段进行查询,其查询语法为:

indexname1 [ : | > | >= | < | <= | = | in ] keyword1 [ [ and | or | not ] indexname2 ... ]

重要
  • indexname1 是需要查询的字段名,当字段名、表名等专有名词中存在特殊字符(空格、中文等)、语法关键词(andor等)等内容时,则需要使用""(双引号)包裹。在查询中使用引号,请参见如何在查询和分析语句中使用引号

  • 字段索引涉及longdouble类型,可以使用比较运算符>>=<<==in

  • 示例1

    如果您希望查询 request_methodGET 相关的日志,则查询语法为:request_method: GET

  • 示例2

    如果您希望查询 request_time_msec 大于 50 相关的日志,则查询语法为request_time_msec>50(该字段索引类型为double)。

  • 示例3

    如果您希望查询 request_method GET request_time_msec 大于50 相关的日志。则查询语法为:request_method: GET and request_time_msec>50

步骤二:确定字段类型

编写查询语句时需要考虑字段类型的特点,合理使用运算符,快速、精准地锁定目标日志。

字段类型

字段类型

说明

可用运算符

text类型

字符串类型的字段。开启全文索引后,日志服务默认将整条日志(除__time__以外所有字段)设置为text类型。

andornot():""\*?

long和double类型

只有设置字段的数据类型为longdouble后,才能通过数值范围查询该字段的值。

  • 如果字段的数据类型不被设置为doublelong或者查询时数值范围的语法错误,那么日志服务会按照全文查询方式进行查询,这样查询到的结果可能与您期望的结果不同。

    例如字段owner_id不是doublelong类型,则执行查询语句owner_id>100时,会返回同时包含owner_id>(非分词符)、100这三个词的日志。

  • 如果将字段的类型从text类型改成doublelong类型,则只支持等号=查询。如果需要使用范围查询、大于号(>)、小于号(<)等运算符,必须重建索引

andornot()>>=<<==in

JSON类型

针对JSON对象中的字段,您可根据其值,将数据类型设置为longdoubletext,并开启统计功能。

根据JSON对象中的字段的类型使用不同的运算符。

运算符

重要
  • in运算符只能小写,其他运算符不区分大小写。

  • 日志服务保留以下运算符的使用权,如果您需要使用以下运算符作为查询关键字,请使用""(双引号)包裹:sortascdescgroup byavgsumminmaxlimit

  • 运算符的优先级由高到低排序如下所示:

    1. 冒号(:)

    2. 双引号("")

    3. 圆括号()

    4. and、not

    5. or

运算符

说明

:

用于字段查询(Key:Value),例如request_method:GET

如果字段名称或者字段值内有空格、冒号(:)、连字符(-)等特殊字符,请使用双引号("")包裹字段名称或者字段值,例如"file info":apsara

and

and运算符。例如request_method:GET and status:200

如果多个关键词之间没有语法关键词,默认为and关系,例如GET 200 cn-shanghai等同于GET and 200 and cn-shanghai

or

or运算符。例如request_method:GET or status:200

not

not运算符。例如request_method:GET not status:200not status:200

( )

用于提高括号内查询条件的优先级。例如(request_method:GET or request_method:POST) and status:200

""

使用""(双引号)包裹一个语法关键词,可以将该语法关键词转换成普通字符。在字段查询中""内的所有词被当成一个整体。

  • 当字段名或字段值中存在特殊字符(空格、中文、:-等)、语法关键词(andor等)等内容时,需要使用""包裹。例如"and"表示查询包含and的日志,此处的and不代表运算符。

  • 日志服务保留以下运算符的使用权,如果您需要使用以下运算符作为查询关键字,请使用""包裹:sortascdescgroup byavgsumminmaxlimit

  • 通过数据加工或者Logtail插件处理的日志,其tag中的key会被转换成普通key,即查询时需使用""包裹字段名,例如"__tag__:__client_ip__":192.0.2.1,此处的__tag__:__client_ip__为日志服务保留字段,表示日志所在主机的IP地址。更多信息,请参见保留字段

\

转义符号,用于转义""(双引号),转义后的双引号表示符号本身。例如日志内容为instance_id:nginx"01",您可以使用instance_id:nginx\"01\"进行查询。

*

通配符查询,匹配零个、单个、多个字符。例如host:www*com

说明

日志服务会在所有日志中为您查询到符合条件的100个词,返回包含这100个词并满足查询条件的所有日志。

?

通配符查询,匹配单个字符。例如host:aliyund?c

>

查询某字段值大于某数值的日志。例如request_time>100

>=

查询某字段值大于或等于某数值的日志。例如request_time>=100

<

查询某字段值小于某数值的日志。例如request_time<100

<=

查询某字段值小于或等于某数值的日志。例如request_time<=100

=

查询某字段值等于某数值的日志。针对double、long类型的字段,=:作用相同。例如request_time=100等同于request_time:100

in

查询某字段值处于某数值范围内的日志,中括号表示闭区间,小括号表示开区间,两个数字之间使用空格分隔。例如request_time in [100 200]request_time in (100 200]

重要

in只能为小写字母。

__source__

查询某个日志源的日志,支持通配符。例如__source__:192.0.2.*

重要

日志服务中的__source__为保留字段,可缩写为source。如果您自定义的字段中存在source字段,则会与日志服务保留字段source冲突,此时您需要使用SourceSOURCE等词查询自定义的字段。

__tag__

通过元数据信息查询日志。例如__tag__:__receive_time__:1609837139

__topic__

查询某日志主题下的日志。例如__topic__:nginx_access_log

步骤三:确定匹配模式

您可根据掌握的关键词信息及实际业务场景的需要灵活控制使用精准查询还是模糊查询。若无法找到想要的日志,可参见文档进行排查:查询不到日志的排查思路

查询方式

说明

示例

精确查询

使用完整的词进行查询。

日志服务查询采用的是分词法,精确查询时并不能完全匹配关键词。例如查询语句为abc def,查询结果将包含所有abcdef的日志,无法完全匹配目标短语。如果您要完全匹配短语abc def,可以使用短语查询或者Like语法。更多信息,请参见短语查询如何精准查询日志

  • host:example.com表示查询host字段值包含example.com的日志。

  • PUT and cn-shanghai表示查询同时包含关键字PUTcn-shanghai的日志。

  • * | Select * where http_user_agent like '%like Gecko%'表示查询http_user_agent字段值中包含短语like Gecko的日志。

  • #"redo_index/1"表示查询包含短语redo_index/1的日志。

模糊查询

在查询语句中指定一个64个字符以内的词,在词的中间或者末尾加上模糊查询关键字,即星号(*)或问号(?),日志服务会在所有日志中为您查询到符合条件的100个词,返回包含这100个词并满足查询条件的所有日志。指定的词越精确,查询结果越精确。

重要
  • 星号(*)或问号(?)不能用在词的开头。

  • long数据类型和double数据类型不支持使用星号(*)或问号(?)进行模糊查询。您可以使用数值范围进行模糊查询,例如status in [200 299]。

模糊查询是一种采样查询,查询机制如下所示:

  • 当您开启字段索引,且指定某个字段进行查询时,日志服务从该字段的索引数据中随机采样,返回部分结果并不是全量扫描底层数据。

  • 当您开启全文索引,且没有指定某个字段进行查询时,日志服务从全文索引数据中随机采样,返回部分结果并不是全量扫描底层数据。

  • request_time>60 and request_method:Ge*表示查询request_time字段值大于60request_method字段值以Ge开头的日志。

  • addr*表示在所有日志中查找以addr开头的100个词,并返回包含这些词的日志。

  • host:www.yl*表示在所有日志中查找host字段值以www.yl开头的100个词,并返回包含这些词的日志。

更多信息,请参见如何模糊查询日志?

查询语句示例

同一条查询语句,针对不同的日志内容和索引配置时,会有不同的查询结果。本文基于如下日志样例和索引介绍查询语句示例。

日志样例

本文以Nginx访问日志为例,介绍常见的查询语句。

日志样例

索引配置

在查询日志前,请确保已配置索引。更多信息,请参见创建索引。检查索引配置的步骤,如下所示:

  1. 在Logstore的查询/分析页面,选择查询分析属性 > 属性image

  2. 在打开的查询分析页面,查看是否已配置字段索引。索引

普通查询示例

查询需求

查询语句

调试

查询GET请求成功(状态码为200~299)的日志。

request_method:GET and status in [200 299]

调试

查询来自非杭州地域的GET请求的日志。

request_method:GET not region:cn-hangzhou

查询GET请求或POST请求的日志。

request_method:GET or request_method:POST

调试

查询非GET请求的日志。

not request_method:GET

调试

查询GET请求或POST请求成功的日志。

(request_method:GET or request_method:POST) and status in [200 299]

调试

查询GET请求或POST请求失败的日志。

(request_method:GET or request_method:POST) not status in [200 299]

调试

查询GET请求成功(状态码为200~299)且请求时间小于60秒的日志。

request_method:GET and status in [200 299] not request_time>=60

调试

查询请求时间为60秒的日志。

request_time:60

调试

request_time=60

调试

查询请求时间大于等于60秒,并且小于200秒的日志。

request_time>=60 and request_time<200

调试

request_time in [60 200)

调试

查询request_time字段值为空或非法数字的日志。

request_time:* not request_time > -10000000000
说明

request_time:*用于判断request_time字段是否存在。此处的星号(*)不代表模糊查询。

调试

查询包含request_time字段且字段值为数字的日志。

request_time > -1000000000

调试

查询包含and的日志。

"and"
说明

此处的and为普通字符串,不代表运算符。

调试

查询request method字段值是PUT的日志。

"request method":PUT
重要

字段名request method中存在空格,在查询时需使用双引号("")包裹。

查询日志主题为HTTPS或HTTP的日志。

__topic__:HTTPS or __topic__:HTTP

查询采集于192.0.2.1主机的日志。

__tag__:__client_ip__:192.0.2.1

此处的__tag__:__client_ip__为日志服务保留字段,表示日志所在主机的IP地址。更多信息,请参见保留字段

重要

通过数据加工或者Logtail插件处理的日志,其tag中的key会被转换成普通key,即查询时需使用双引号("")包裹字段名,例如"__tag__:__client_ip__":192.0.2.1

查询包含192.168.XX.XX的日志。

* | select * from log where key like '192.168.%.%'

更多信息,请参见通过SQL的like语法进行精确的模糊查询

查询remote_user字段值不为空的日志。

not remote_user:""

调试

查询remote_user字段值为空的日志。

remote_user:""

调试

查询remote_user字段值不为null的日志。

not remote_user:"null"

调试

查询不存在remote_user字段的日志。

not remote_user:*

调试

查询存在remote_user字段的日志。

remote_user:*

调试

查询城市字段值不为上海的日志。

not 城市:上海
说明

当您要查询中文字符串时,您需要在配置索引时,打开包含中文开关。更多信息,请参见创建索引

进阶查询示例

  • 模糊查询

    查询需求

    查询语句

    调试

    查询包含以cn开头的词的日志。

    cn*

    调试

    查询region字段值是以cn开头的日志。

    region:cn*

    查询region字段值包含cn*的日志。

    region:"cn*"
    说明

    此处的cn*为一个独立词。例如:

    • 如果日志内容为region:cn*,en,分词符为半角逗号(,),则该日志内容被拆分为regioncn*en,您可以通过上述语句查询到该日志。

    • 如果日志内容为region:cn*hangzhou,则cn*hangzhou为一个整体,您执行上述语句无法查询到该日志。

    查询包含以mozi开头,以la结尾,中间还有一个字符的词的日志。

    mozi?la

    调试

    查询包含以mo开头,以la结尾,中间包含零个、单个或多个字符的词的日志。

    mo*la

    调试

    查询包含以moz开头的词和以sa开头的词的日志。

    moz* and sa*

    调试

    查询region字段值以hai结尾的所有日志。

    目前使用查询语句无法查询到对应的日志,您可以使用SQL分析中的Like语法进行查询。更多信息,请参见通过SQL的like语法进行精确的模糊查询

    * | select * from log where region like '%hai'

  • 基于分词符的查询

    日志服务会根据分词符,将日志内容拆分成多个词。日志服务默认配置的分词符为, '";=()[]{}?@&<>/:\n\t\r。如果设置分词符为空,则字段值将被当成一个整体,您只能通过完整字符串或模糊查询查找对应的日志。如何设置分词符,请参见创建索引

    例如http_user_agent字段值为Mozilla/5.0 (Windows NT 6.1) AppleWebKit/537.2 (KHTML, like Gecko) Chrome/192.0.2.0 Safari/537.2

    • 设置分词符为空时,该字段值将被当成一个整体,则您使用http_user_agent:Chrome查询语句进行查询时,无法查询到日志。

    • 设置分词符, '";=()[]{}?@&<>/:\n\t\r后,该字段值为拆分为Mozilla5.0WindowsNT6.1AppleWebKit537.2KHTMLlikeGeckoChrome192.0.2.0Safari537.2。您可以使用http_user_agent:Chrome等查询语句进行查询。

    重要

    当查询关键字中包含分词符时,您可以使用短语查询或者Like语法。例如:

    • 短语查询:#"redo_index/1"。更多信息,请参见短语查询

    • Like语法:* | select * from log where key like 'redo_index/1'

    查询需求

    查询语句

    调试

    查询http_user_agent字段值中包含Chrome的日志。

    http_user_agent:Chrome

    调试

    查询http_user_agent字段值中包含LinuxChrome的日志。

    http_user_agent:Linux and http_user_agent:Chrome

    调试

    http_user_agent:"Linux Chrome"

    调试

    查询http_user_agent字段值中包含FirefoxChrome的日志。

    http_user_agent:Firefox or http_user_agent:Chrome

    调试

    查询request_uri字段值包含/request/path-2的日志。

    request_uri:/request/path-2

    调试

    查询request_uri字段值以/request开头,但不包含/file-0的日志。

    request_uri:/request* not request_uri:/file-0

    调试

    完全匹配包含短语redo_index/1的日志。

    • #"redo_index/1"

    • * | select * from log where key like 'redo_index/1'

    说明

    通过短语查询或者Like语法,可完全匹配目标短语。使用普通的精确查询,将匹配redo_index1等词。

特殊场景查询示例

  • 在查询语句中

    使用""(双引号)包裹一个语法关键词,可以将该语法关键词转换成普通字符。在字段查询中""内的所有词被当成一个整体。

    • 当字段名或字段值中存在特殊字符(空格、中文、:-等)、语法关键词(andor等)等内容时,需要使用""包裹。例如"and"表示查询包含and的日志,此处的and不代表运算符。

    • 日志服务保留以下运算符的使用权,如果您需要使用以下运算符作为查询关键字,请使用""包裹:sortascdescgroup byavgsumminmaxlimit

    • 通过数据加工或者Logtail插件处理的日志,其tag中的key会被转换成普通key,即查询时需使用""包裹字段名,例如"__tag__:__client_ip__":192.0.2.1,此处的__tag__:__client_ip__为日志服务保留字段,表示日志所在主机的IP地址。更多信息,请参见保留字段

    查询需求

    查询语句

    查询request method字段值中包含PUT的日志。字段名request method中存在空格。

    "request method":PUT

    查询采集于192.0.2.1主机的日志。

    "__tag__:__client_ip__":192.0.2.1
  • 在分析语句中

    • 当字段名、表名等专有名词中存在特殊字符(空格、中文、:-等)、语法关键词(andor等)等内容时,需要使用""包裹。

    • 表示字符串的字符必须使用''(单引号)包裹。无符号包裹或被""(双引号)包裹的字符表示字段名或列名。例如:'status'表示字符串status,status"status"表示日志字段status。

    查询需求

    查询语句

    查询包含192.168.XX.XX的日志。

    * | select * from log where key like '192.168.%.%'

    在查询中使用引号,如何在查询和分析语句中使用引号?

相关文档