SPL指令

本文介绍SPL指令的详细信息。

参数类型说明

SPL指令中的参数类型说明如下表所示。

参数类型

说明

Bool

布尔类型参数。使用SPL时,该参数为开关参数。

Char

ASCII字符类型参数,需使用单引号('')包裹,例如'a'表示字符a,'\t'表示制表符、'\11'表示序号为八进制数11对应的ASCII字符、'\x09'表示序号为十六进制数09对应的ASCII字符。

Integer

整数类型参数。

String

字符串类型参数,需使用单引号('')包裹,例如'this is a string'

RegExp

RE2正则表达式类型参数,需使用单引号('')包裹,例如'([\d.]+)'

语法定义,请参见Syntax

JSONPath

JSON路径类型参数,需使用单引号('')包裹,例如'$.body.values[0]'

语法定义,请参见JsonPath

Field

字段名类型参数,例如| project level, content

如果字段名中包含字母、数字、下划线以外的特殊字符,需使用双引号("")包裹,例如 | project "a:b:c"

说明

关于字段名称大小写敏感详情,请参见SPL在不同场景的功能定义

FieldPattern

字段名和通配符组合或者字段名类型参数。支持通配符号*,表示匹配0个或多个任意字符。需使用双引号("")包裹,例如| project "__tag__:*"

说明

关于字段名称大小写敏感详情,请参见SPL在不同场景的功能定义

SPLExp

SPL表达式类型参数。

SQLExp

SQL表达式类型参数。

SPL指令列表

指令类别

指令名称

说明

控制指令

.let

定义命名数据集,SPL数据集详情请参见SPL数据集

字段操作指令

project

保留与给定模式相匹配的字段、同时可重命名指定字段。指令执行过程中,先完成所有字段保留表达式的执行,再执行重命名表达式。

project-away

移除与给定模式相匹配的字段,原样保留其他所有字段。

project-rename

重命名指定字段,并保留其他所有字段原样。

expand-values

展开指定字段的第一层JSON对象,生成多条结果。

结构化数据SQL计算指令

extend

通过SQL表达式计算结果产生新字段。支持的SQL函数列表,请参见SPL支持的SQL函数列表

where

根据SQL表达式过滤数据,保留满足SQL表达式的数据条目。where指令支持的SQL函数列表,请参见SPL支持的SQL函数列表

弱结构化数据提取指令

parse-regexp

提取指定字段中的正则表达式分组匹配信息。

parse-csv

提取指定字段中的CSV格式的信息。

parse-json

提取指定字段中的第一层JSON信息。

parse-kv

提取指定字段中的键值对信息。

数据加工(新版)指令

pack-fields

将日志字段进行打包,以JSON序列化输出到新字段,适用于需要结构化传输的场景(如API请求体构建)。

log-to-metric

将日志格式转化为时序存储的格式。

metric-to-metric

对已有时序数据进一步加工(如添加/修改/删除标签)。

聚合指令

stats

用于统计分析日志的指令,类似 SQL 中的聚合函数(如 COUNTSUMAVG 等)。对日志数据中的特定字段进行统计、分组和聚合操作。

sort

对查询结果进行排序,支持对字段值或统计结果进行升序(asc)或降序(desc)排序。它是日志分析中快速定位关键数据、生成有序报表的重要工具。

limit

用于限制查询结果返回的日志行数,是控制数据量的核心指令之一。通过 limit 可有效防止查询结果过大导致的性能问题或资源浪费,适用于日志分析、实时监控等多种场景。

控制指令

.let

定义命名数据集,作为后续SPL表达式的输入。SPL数据集详情请参见SPL数据集

语法

.let <dataset>=<spl-expr>

参数说明

参数

类型

必填

说明

dataset

String

数据集名称,包含字母、数字和下划线,并且以字母开头,区分大小写。

spl-expr

SPLExp

生成数据集的SPL表达式。

示例

  • 示例1:将访问日志基于状态码进行过滤和分类处理,然后将其输出。

    • SPL语句

      -- SPL处理结果定义为命名数据集src,作为后续SPL表达式的输入
      .let src = * 
      | where status=cast(status as BIGINT);
      
      -- 以命名数据集src作为输入,筛选status字段为5xx的数据,定义数据集err,不输出
      .let err = $src
      | where status >= 500
      | extend msg='ERR';
      
      -- 以命名数据集src作为输入,筛选status字段为2xx的数据,定义数据集ok,不输出
      .let ok = $src
      | where status >= 200 and status < 300
      | extend msg='OK';
      
      -- 输出命名数据集errok
      $err;
      $ok;
  • 输入数据

    # 条目1
    status: '200'
    body: 'this is a test'
    
    # 条目2
    status: '500'
    body: 'internal error'
    
    # 条目3
    status: '404'
    body: 'not found'
  • 输出结果

    # 条目1: 数据集为err
    status: '500'
    body: 'internal error'
    msg: 'ERR'
    
    # 条目2: 数据集为ok
    status: '200'
    body: 'this is a test'
    msg: 'OK'

字段操作指令

project

保留与给定模式相匹配的字段、同时可重命名指定字段。指令执行过程中,先执行完成所有字段保留表达式,再执行重命名表达式。

重要

默认保留时间字段__time__和__time_ns_part__,并且不可重命名与覆盖,更多信息,请参见时间字段

语法

| project -wildcard <field-pattern>, <output>=<field>, ...

参数说明

参数

类型

必填

说明

wildcard

Bool

是否开启通配模式。默认为字段精确匹配。您需要开启通配模式时,需添加该参数。

field-pattern

FieldPattern

需要保留的字段名称或字段和通配符组合(处理匹配到的所有字段)。

output

Field

需要重命名的新字段名称,不支持多次重命名至相同的目标字段。

重要

如果新字段与输入数据中字段重名,其结果取值策略,请参见新旧值保留与覆盖

field

Field

是​

需要重命名的原字段名称。

  • 若该字段在输入数据中不存在,则不执行重命名。

  • 不支持同一字段被多次重命名。

示例

  • 示例1:保留特定字段。

    * | project level, err_msg
  • 示例2:重命名字段。

    * | project log_level=level, err_msg
  • 示例3:保留精确匹配的字段__tag__:*

    * | project "__tag__:*"

project-away

移除与给定模式相匹配的字段,原样保留其他所有字段。

重要

该指令将默认保留时间字段__time__和__time_ns_part__,更多详情,请参见时间字段

语法

| project-away -wildcard <field-pattern>, ...

参数说明

参数

类型

必填

说明

wildcard

Bool

是否开启通配模式。默认为字段精确匹配。您需要开启通配模式时,需添加该参数。

field-pattern

FieldPattern

需要移除的字段名称或者字段和通配符组合(处理匹配到的所有字段)。

project-rename

重命名指定字段,并保留其他所有字段原样。

重要

默认保留时间字段__time__和__time_ns_part__,并且不可重命名与覆盖,更多详情,请参见时间字段

语法

| project-rename <output>=<field>, ...

参数说明

参数

类型

必填

说明

output

Field

重命名后的字段名称。不支持多次重命名至相同的目标字段。

重要

如果新字段与输入数据中字段重名,其结果取值策略,请参见新旧值保留与覆盖

field

Field

待重命名的原字段名称。

  • 若该字段在数据条目中不存在,则不执行重命名。

  • 不支持同一字段被多次重命名

示例

重命名指定字段。

* | project-rename log_level=level, log_err_msg=err_msg

expand-values

展开指定字段的第一层JSON对象,生成多条结果。

重要

语法

| expand-values -path=<path> -limit=<limit> -keep <field> as <output>

参数说明

参数

类型

必填

说明

path

JSONPath

否​

指定字段内容中的JSON路径,用于定位需要展开的内容位置。

默认值为空,表示直接展开指定字段的完整内容。

limit

Integer

每条原始数据可展开的最大条目数,值为110之间的整数。默认值为10。

keep

Bool

展开后是否保留原字段。默认不保留,需要保留时,打开此开关。

field

Field

需要展开的原字段名称,支持类型为VARCHAR。如果指定字段不存在,则不执行展开操作。

output

Filed

展开的目标字段名称。如果不指定,则默认输出结果至输入字段。

针对原始内容的展开逻辑为:

JSON数组:根据数组的元素逐个展开。

JSON字典:根据字典键值对逐个展开。

其他JSON类型:返回原值。

非法JSON:返回null

示例

  • 示例1:展开数组,输出多条结果数据。

    • SPL语句

      * | expand-values y
    • 输入数据

      x: 'abc'
      y: '[0,1,2]'
    • 输出数据,展开为3条数据

      # 条目1
      x: 'abc'
      y: '0'
      
      # 条目2
      x: 'abc'
      y: '1'
      
      # 条目3
      x: 'abc'
      y: '2'
  • 示例2:展开字典,输出多条结果数据。

    • SPL语句

      * | expand-values y
    • 输入数据

      x: 'abc'
      y: '{"a": 1, "b": 2}'
    • 输出数据,展开为2条数据

      # 条目1
      x: 'abc'
      y: '{"a": 1}'
      
      # 条目2
      x: 'abc'
      y: '{"b": 2}'
  • 示例3:展开指定JSON Path下的内容,并输出至新字段。

    • SPL语句

      * | expand-values -keep content -path='$.body' as body
    • 输入数据

      content: '{"body": [0, {"a": 1, "b": 2}]}'
    • 输出数据,展开为2条数据

      # 条目1
      content: '{"body": [1, 2]}'
      body: '0'
      
      # 条目2
      content: '{"body": [1, 2]}'
      body: '{"a": 1, "b": 2}'

结构化数据SQL计算指令

extend

通过SQL表达式计算结果产生新字段。支持的SQL函数列表,请参见SPL支持的SQL函数列表

语法

| extend <output>=<sql-expr>, ...

参数说明

参数

类型

必填

说明

output

Field

添加的目标字段名称。不支持多个表达式结果输出至相同的目标字段。

重要

如果目标字段与输入数据中字段重名,则直接使用新的类型以及值将其覆盖。

sql-expr

SQLExpr

数据处理表达式。

重要

关于null值处理,请参见SPL表达式null值处理

示例

  • 示例1:使用计算表达式。

    * | extend Duration = EndTime - StartTime
  • 示例2:使用正则表达式。

    * | extend server_protocol_version=regexp_extract(server_protocol, '\d+')
  • 示例3:提取JSON路径内容,并转换部分字段的数据类型。

    • SPL语句

      *
      | extend a=json_extract(content, '$.body.a'), b=json_extract(content, '$.body.b')
      | extend b=cast(b as BIGINT)
    • 输入数据

      content: '{"body": {"a": 1, "b": 2}}'
    • 输出结果

      content: '{"body": {"a": 1, "b": 2}}'
      a: '1'
      b: 2

where

根据SQL表达式过滤数据,保留满足SQL表达式的数据条目。where指令支持的SQL函数列表,请参见SPL支持的SQL函数列表

语法

| where <sql-expr>

参数说明

参数

类型

必填

说明

sql-expr

SQLExp

SQL表达式,保留满足此表达式的数据条目。

重要

SQL表达式中null值处理,请参见SPL表达式null值处理

示例

  • 示例1:根据字段内容过滤数据条目。

    * | where userId='123'
  • 示例2:使用匹配字段名的正则表达式过滤数据条目。

    * | where regexp_like(server_protocol, '\d+')
  • 示例3:转换数据类型后,匹配所有服务端错误数据。

    * | where cast(status as BIGINT) >= 500

弱结构化数据提取指令

parse-regexp

提取指定字段中的正则表达式分组匹配信息。

重要
  • 提取结果的数据类型为VARCHAR。如果结果字段与输入数据中字段重名,取值策略请参见新旧值保留与覆盖

  • 无法操作时间字段__time__和__time_ns_part__,请参见时间字段

语法

| parse-regexp <field>, <pattern> as <output>, ...

参数说明

参数

类型

必填

说明

field

Field

需要提取的原始字段名称。

要求输入数据包含该字段,类型须为VARCHAR,且其值为非null。否则,不执行提取操作。

pattern

Regexp

正则表达式,支持RE2正则语法。

output

Field

用于存储正则提取结果的字段名称。

示例

  • 示例1:探索式逐个进行匹配。

    • SPL语句

      *
      | parse-regexp content, '(\S+)' as ip -- 生成字段ip: 10.0.0.0。
      | parse-regexp content, '\S+\s+(\w+)' as method -- 生成字段method: GET。
    • 输入数据

      content: '10.0.0.0 GET /index.html 15824 0.043'
    • 输出结果

      content: '10.0.0.0 GET /index.html 15824 0.043'
      ip: '10.0.0.0'
      method: 'GET'
  • 示例2:完整模式匹配,使用非命名正则捕获。

    • SPL语句

      * | parse-regexp content, '(\S+)\s+(\w+)' as ip, method
    • 输入数据

      content: '10.0.0.0 GET /index.html 15824 0.043'
    • 输出结果

      content: '10.0.0.0 GET /index.html 15824 0.043'
      ip: '10.0.0.0'
      method: 'GET'

parse-csv

提取指定字段中的CSV格式的信息。

重要
  • 提取结果的数据类型为VARCHAR。如果结果字段与输入数据中字段重名,取值策略请参见新旧值保留与覆盖

  • 无法操作时间字段__time__和__time_ns_part__,请参见时间字段

语法

| parse-csv -delim=<delim> -quote=<quote> -strict <field> as <output>, ...

参数说明

参数

类型

必填

说明

delim

String

否​

数据内容的分隔字符为13个有效ASCII字符。

可使用转义符表示特殊字符,比如\t表示制表符、\11表示序号为八进制数11对应的ASCII字符、\x09表示序号为十六进制数09对应的ASCII字符。

也可使用多个字符组合作为分隔符,比如$$$, ^_^

默认值为英文逗号(,)。

quote

Char

否​

数据内容引用符是单个有效ASCII字符,在数据内容中包含分隔符时使用。

比如双引号(")、单引号(')以及不可见字符(0x01)。

默认不使用引用符。

重要

该参数仅在delim参数为单个字符时生效,且取值不能与delim相同。

strict

Bool

当数据内容中值的数量与output中指定字段不一致时,是否开启严格配对。

  • False:非严格配对,按照最大化配对策略执行。

    • 值的数目多于字段时,多余值不输出。

    • 字段数多于值时,多余字段输出空字符串。

  • True:严格配对,不输出任何字段。

默认为关闭,需要开启时,请添加此参数。

field

Field

需要解析的原字段名称。

要求数据内容包含该字段,类型须为VARCHAR,且其值为非null。否则,不执行提取操作。

output

Field

用于存储数据内容解析结果的字段名称。

示例

  • 示例1:简单数据匹配。

    • SPL语句

      * | parse-csv content as x, y, z
    • 输入数据

      content: 'a,b,c'
    • 输出结果

      content: 'a,b,c'
      x: 'a'
      y: 'b'
      z: 'c'
  • 示例2:默认使用双引号作为引用符,匹配包含特殊字符的内容。

    • SPL语句

      * | parse-csv content as ip, time, host
    • 输入数据

      content: '192.168.0.100,"10/Jun/2019:11:32:16,127 +0800",example.aliyundoc.com'
    • 输出结果

      content: '192.168.0.100,"10/Jun/2019:11:32:16,127 +0800",example.aliyundoc.com'
      ip: '192.168.0.100'
      time: '10/Jun/2019:11:32:16,127 +0800'
      host: 'example.aliyundoc.com'
  • 示例3:使用多字符组合作为分隔符。

    • SPL语句

      * | parse-csv -delim='||' content as time, ip, req
    • 输入数据

      content: '05/May/2022:13:30:28||127.0.0.1||POST /put?a=1&b=2'
    • 输出结果

      content: '05/May/2022:13:30:28||127.0.0.1||POST /put?a=1&b=2'
      time: '05/May/2022:13:30:28'
      ip: '127.0.0.1'
      req: 'POST /put?a=1&b=2'

parse-json

提取指定字段中的第一层JSON信息。

重要
  • 提取结果的数据类型为VARCHAR。如果结果字段与输入数据中字段重名,取值策略请参见新旧值保留与覆盖

  • 无法操作时间字段__time__和__time_ns_part__,请参见时间字段

语法

| parse-json -mode=<mode> -path=<path> -prefix=<prefix> <field>

参数说明

参数

类型

必填

说明

mode

String

如果新字段与输入数据中字段重名,指定其结果取值模式。默认值为overwrite。

path

JSONPath

指定字段内容中的JSON路径,用于定位需要提取的内容位置。

默认值为空字符串,表示直接提取指定字段的完整内容。

prefix

String

否​

JSON结构展开的结果字段前缀,默认为空字符串。

field

Field

需要解析的原字段名称。

要求输入数据包含该字段,其值为非null,且满足以下条件之一。否则,不执行提取操作。

  • 类型为JSON

  • 类型为VARCHAR,且值为合法JSON字符串

示例

  • 示例1:提取y字段中的所有键值。

    • SPL语句

      * | parse-json y
    • 输入数据

      x: '0'
      y: '{"a": 1, "b": 2}'
    • 输出结果

      x: '0'
      y: '{"a": 1, "b": 2}'
      a: '1'
      b: '2'
  • 示例2:提取content字段中的body键对应的内容,并将其所有键值提取为字段。

    • SPL语句

      * | parse-json -path='$.body' content
    • 输入数据

      content: '{"body": {"a": 1, "b": 2}}'
    • 输出结果

      content: '{"body": {"a": 1, "b": 2}}'
      a: '1'
      b: '2'
  • 示例3:指定字段值输出模式为preserve,对于已有字段,保留原始值。

    • SPL语句

      * | parse-json -mode='preserve' y
    • 输入数据

      a: 'xyz'
      x: '0'
      y: '{"a": 1, "b": 2}'
    • 输出结果

      x: '0'
      y: '{"a": 1, "b": 2}'
      a: 'xyz'
      b: '2'

parse-kv

提取指定字段中的键值对信息。

重要
  • 提取结果的数据类型为VARCHAR。如果结果字段与输入数据中字段重名,取值策略请参见新旧值保留与覆盖

  • 无法操作时间字段__time__和__time_ns_part__,请参见时间字段

语法

| parse-kv -mode=<mode> -prefix=<prefix> -regexp <field>, <pattern>

参数

参数

类型

必填

说明

mode

String

如果相应的目标字段已存在于输入数据中,可选择数据覆盖模式。

默认值为overwrite。具体请参见字段提取检查与覆盖模式

prefix

String

​否

提取结果输出字段名前缀,默认为空字符串。

regexp

Bool

开启正则提取模式。

field

Field

需要提取的原始字段名称。

要求输入数据包含该字段,类型须为VARCHAR,且其值为非null。否则,则不执行提取操作。

pattern

RegExpr

包含2个正则捕获组的正则表达式,第1个捕获组提取字段名,第2个捕获组提取字段值,支持RE2正则语法。

示例

  • 示例1:正则提取模式,处理复杂的键值对之间的定界符、以及键与值之间的分隔符。

    • SPL语句

      * | parse-kv -regexp content, '([^&?]+)(?:=|:)([^&?]+)'
    • 输入数据

      content: 'k1=v1&k2=v2?k3:v3'
      k1: 'xyz'
    • 输出数据

      content: 'k1=v1&k2=v2?k3:v3'
      k1: 'v1'
      k2: 'v2'
      k3: 'v3'
  • 示例2:正则提取模式,并指定字段值输出模式为preserve,对于已有字段,保留原始值。

    • SPL语句

      * | parse-kv -regexp -mode='preserve' content, '([^&?]+)(?:=|:)([^&?]+)'
    • 输入数据

      content: 'k1=v1&k2=v2?k3:v3'
      k1: 'xyz'
    • 输出结果

      content: 'k1=v1&k2=v2?k3:v3'
      k1: 'xyz'
      k2: 'v2'
      k3: 'v3'
  • 示例3:正则提取模式,提取复杂非结构化数据,值格式为数字或者双引号包裹的字符串。

    • SPL语句

      * | parse-kv -regexp content, '([^&?]+)(?:=|:)([^&?]+)'
    • 输入数据

      content: 'verb="GET" URI="/healthz" latency="45.911µs" userAgent="kube-probe/1.30+" audit-ID="" srcIP="192.168.123.45:40092" contentType="text/plain; charset=utf-8" resp=200'
    • 输出结果

      content: 'verb="GET" URI="/healthz" latency="45.911µs" userAgent="kube-probe/1.30+" audit-ID="" srcIP="192.168.123.45:40092" contentType="text/plain; charset=utf-8" resp=200'
      verb: 'GET'
      URI: '/healthz'
      latency: '45.911µs'
      userAgent: 'kube-probe/1.30+'
      audit-ID: ''
      srcIP: '192.168.123.45:40092'
      contentType: 'text/plain; charset=utf-8'
      resp: '200'

数据加工(新版)指令

支持地域

华北2 阿里政务云1、华东2(上海)、华南2(河源)

pack-fields

将多个字段打包,以JSON序列化输出到新字段,适用于需要结构化传输的场景(如API请求体构建)。

重要
  • 默认不处理非Varchar类型的字段(包括__time____time_ns_part__)。

  • 默认不保留源数据。

语法

| pack-fields -keep -ltrim -include=<include> -exclude=<exclude> as <output>

参数说明

参数

类型

必填

说明

output

String

指定打包后输出的字段名称。字段值格式为JSON格式。

include

RegExp

白名单配置,符合正则表达式的字段会被打包。默认为".*" ,表示全部匹配。更多信息,请参见正则表达式

exclude

RegExp

黑名单配置(优先于白名单),符合正则表达式的字段不会被打包。默认为空,表示不进行匹配判断。更多信息,请参见正则表达式

ltrim

String

在输出字段名称中,去掉前缀。

keep

Bool

打包数据后是否保留被打包的源数据。

True:输出结果中保留被打包的原数据。

False(默认值):输出结果中不保留被打包的源数据。

示例

  • 示例1:将日志所有字段打包到test字段,默认删除被打包的原始字段。

    • SPL语句

      * | pack-fields -include='\w+' as test
    • 输入数据

      test1:123
      test2:456
      test3:789
    • 输出结果

      test:{"test1": "123", "test2": "456", "test3": "789"}
  • 示例2:将日志所有字段打包到test字段,不删除被打包的原始字段。

    • SPL语句

      * | pack-fields -keep -include='\w+' as test
    • 输入数据

      test1:123
      test2:456
      test3:789
    • 输出结果

      test:{"test1": "123", "test2": "456", "test3": "789"}
      test1:123
      test2:456
      test3:789
  • 示例3:打包testabcd字段到content字段,不删除被打包的原始字段。

    • SPL语句

      * | pack-fields -keep -include='\w+' as test
    • 输入结果

      abcd@#%:123
      test:456
      abcd:789
    • 输出结果

      abcd:789
      abcd@#%:123
      content:{"test": "456", "abcd": "789"}
      test:456
  • 示例4:不打包testabcd字段,其余字段打包到content字段,删除被打包的原始字段。

    • SPL语句

      * | pack-fields -exclude='\w+' as test
    • 输入数据

      abcd@#%:123
      test:456
      abcd:789
    • 输出结果

      abcd:789
      content:{"abcd@#%": "123"}
      test:456
  • 示例5:提取出字段值中满足正则表达式的所有KV结果,并打包赋值给name字段。

    • SPL语句

      * | parse-kv -prefix='k_' -regexp dict, '(\w+):(\w+)' | pack-fields -include='k_.*' -ltrim = 'k_' as name
    • 输入数据

      dict: x:123, y:456, z:789
    • 输出结果

      dict:x:123, y:456, z:789
      name:{"x": "123", "y": "456", "z": "789"}

log-to-metric

将日志格式转化为时序存储的格式。

重要
  • 默认忽略不符合时序数据(Metric)要求的日志数据。

  • 自动识别原始日志数据时间字段的时间单位,支持秒、毫秒、微秒、纳秒。

  • 默认Hash写。

语法

| log-to-metric -wildcard -format -names=<names> -labels=<labels> -time_field=<time_field>

参数说明

参数

类型

必填

说明

wildcard

Bool

nameslabels指定的字段名是否开启通配模式。

默认为字段精确匹配。您需要开启通配模式时,需添加该参数。

format

Bool

​否

是否开启自动format。

默认不开启,加工过程中跳过非法的label数据。

开启后对label的非法数据做 format 操作,label值不能含有 "|""#" "$" 等符号,如有的话使用 "_" 代替。

names

FieldList

日志字段列表,用于生成对应的Metric时序点。

如果输入数据中的字段,与至少一个指定的字段名、字段名通配模式匹配,则生成该字段对应的Metric时序点,指标名称即为字段名,指标值为字段值。

比如,[mem, "mem:pct"]表示生成两个时序点,名称分别为memmem:pct

重要
  • 输入字段名需遵循正则表达式[a-zA-Z_:][a-zA-Z0-9_:]*,否则,将不生成该字段对应的时序点。

  • 输入字段值满足如下任一要求,否则,将不生成该字段对应的时序点:

    • 字段为数值类型TINYINT、SMALLINT、INTEGER、BIGINT、HUGEINT、REAL、或者DOUBLE。

    • 字段为文本类型VARCHAR,且其值可转换为合法的DOUBLE类型。

时序数据格式请参考时序数据(Metric)

labels

FieldList

​否

日志字段列表,用于构造对应的时序Label信息。

如果输入数据中的字段,与至少一个指定的字段名、字段名通配模式匹配,则将该字段添加至时序点的label中,label名称即为字段名,label值为字段值。

比如,[host, ip]表示添加两个时序Label,分别为hostip及其原始字段值。

重要
  • 输入字段名需遵循正则表达式[a-zA-Z_][a-zA-Z0-9_]*,否则,生成的时序点label将不包含该字段。

  • 输入字段值需不包含竖线|,否则,生成的时序点Label不覆盖该字段。

  • 输入字段类型为文本类型VARCHAR,否则,不生成对应label。

时序数据格式请参考时序数据(Metric)

time_field

String

时序数据的时间字段。默认使用日志中__time__字段作为时序数据的时间字段。

重要

  • 输入字段格式为时间戳,对应的数值类型需为BIGINT、VARCHAR,若字段为文本类型VARCHAR,其值可转化为合法的BIGINT类型

示例

  • 示例1:将rt字段所在的日志转换为时序数据格式。

    • SPL语句

      * | log-to-metric -names='["rt"]'
    • 输入数据

      __time__: 1614739608
      rt: 123
    • 输出结果

      __labels__:
      __name__:rt
      __time_nano__:1614739608
      __value__:123
  • 示例2:将rt字段所在的日志转换为时序数据格式,并将host字段作为新增labels信息字段。

    • SPL语句

      * | log-to-metric -names='["rt"]' -labels='["host"]'
    • 输入数据

      __time__: 1614739608
      rt: 123
      host: myhost
    • 输出结果

      __labels__:host#$#myhost
      __name__:rt
      __time_nano__:1614739608
      __value__:123
  • 示例3:将rtqps字段所在的日志转换为时序数据格式,并将host字段作为新增labels信息字段。

    • SPL语句

      * | log-to-metric -names='["rt", "qps"]' -labels='["host"]'
    • 输入数据

      __time__: 1614739608
      rt: 123
      qps: 10
      host: myhost
    • 输出结果

      __labels__:host#$#myhost
      __name__:rt
      __time_nano__:1614739608
      __value__:123
      
      __labels__:host#$#myhost
      __name__:qps
      __time_nano__:1614739608
      __value__:10

  • 示例4:模糊匹配将rt1rt2字段所在的日志转换为时序数据格式,并将host字段作为新增labels信息字段。

    • SPL语句

      * | log-to-metric -wildcard -names='["rt*"]' -labels='["host"]'
    • 输入数据

      __time__: 1614739608
      rt1: 123
      rt2: 10
      host: myhost
    • 输出结果

      __labels__:host#$#myhost
      __name__:rt1
      __time_nano__:1614739608
      __value__:123
      
      __labels__:host#$#myhost
      __name__:rt2
      __time_nano__:1614739608
      __value__:10
  • 示例5:将rtqps字段所在的日志转换为时序数据格式,并将host字段作为新增labels信息字段,同时自动格式化新增label值。

    • SPL语句

      * | log-to-metric -format -names='["rt", "qps"]' -labels='["host"]'
    • 输入数据

      __time__: 1614739608
      rt: 123
      qps: 10
      host: myhost1|myhost2
    • 输出结果

      __labels__:host#$#myhost1_myhost2
      __name__:rt
      __time_nano__:1614739608
      __value__:123
      
      __labels__:host#$#myhost1_myhost2
      __name__:qps
      __time_nano__:1614739608
      __value__:10
  • 示例6:将rtqps字段所在的日志转换为时序数据格式,替换字段名称为max_rttotal_qps,并将host字段作为新增labels信息字段。

    • SPL语句

      * | project-rename max_rt = rt, total_qps = qps| log-to-metric -names='["max_rt", "total_qps"]' -labels='["host"]'
    • 输入数据

      __time__: 1614739608
      rt: 123
      qps: 10
      host: myhost
    • 输出结果

      __labels__:host#$#myhost
      __name__:max_rt
      __time_nano__:1614739608
      __value__:123
      
      __labels__:host#$#myhost
      __name__:total_qps
      __time_nano__:1614739608
      __value__:10
  • 示例7:将rtqps字段所在的日志转换为时序数据格式,替换字段名称为max_rttotal_qps,并将host字段重命名为hostname后作为新增labels信息字段。

    • SPL语句

      * | project-rename max_rt = rt, total_qps = qps, hostname=host| log-to-metric -names='["max_rt", "total_qps"]' -labels='["hostname"]'
    • 输入数据

      __time__: 1614739608
      rt: 123
      qps: 10
      host: myhost
    • 输出结果

      __labels__:hostname#$#myhost
      __name__:max_rt
      __time_nano__:1614739608
      __value__:123
      
      __labels__:hostname#$#myhost
      __name__:total_qps
      __time_nano__:1614739608
      __value__:10
  • 示例8:将remote_user字段所在的日志转换为时序数据格式,将status字段作为新增labels信息字段,将time字段作为时序数据的时间字段,并指定原始日志数据时间单位为纳秒。

    • SPL语句

      * | log-to-metric -names='["remote_user"]' -labels='["status"]' -time_field='time'
    • 输入数据

      time:1652943594
      remote_user:89
      request_length:4264
      request_method:GET
      status:200
    • 输出结果

      __labels__:status#$#200
      __name__:remote_user
      __time_nano__:1652943594
      __value__:89

metric-to-metric

对已有时序数据进一步加工(如添加/修改/删除标签)。

重要
  • 输入字段名需遵循正则表达式[a-zA-Z_][a-zA-Z0-9_]*,否则,生成的时序点Label将不包含该字段。

  • 如果三个option参数包含同一个字段,优先级为:add_labels > del_labels > rename_labels 。

输出时序数据格式请参考时序数据(Metric)

语法

| metric-to-metric -format -add_labels=<add_labels> -del_labels=<del_labels> -rename_labels=<rename_labels>

参数说明

参数

类型

必填

说明

add_labels

Array

需要增加的Label字段列表,用于构造新的时序Label信息。

将原始数据添加至时序点的Label中,仅支持VARCHAR类型。

比如,{"host":"http://www.xxx.com", "ip":"127.0.0.1"}是原始数据,输入["host", "ip"],原始的label中增加|host#$#http://www.xxx.com|ip#$#127.0.0.1 ,如果原始的label中存在host字段,会覆盖原字段的值。

del_labels

Array

需要减少的Label字段列表,用于构造新的时序Label信息。

如果输入数据中的字段,原始Label中的字段名匹配,则将原始Label中的对应字段删除。

比如,原始的Label值为 host#$#http://www.xxx.com|ip#$#127.0.0.1,输入["ip"]表示删除一个时序Label,原始的label中更新为host#$#http://www.xxx.com ,如果原始的label中存在ip字段,不做处理。

rename_labels

Map

需要重命名的Label字段列表,用于构造新的时序Label信息。

将原始时序点的Label根据Map信息进行更新,key名称即为字段名,value值为新字段名。

比如,{"host":"host_new", "ip":"ip_new"}"host"重命名为"host_new""ip"重命名为"ip_new"。如果原始的label中不存在对应字段,不做处理。

format

Bool

是否开启自动format。默认不开启,加工过程中跳过非法数据。

开启后:

  • 对__labels__做排序。

  • LabelKey 和 LabelValue 做 format 操作。

    • LabelKey:需满足正则 “[a-zA-Z_][a-zA-Z0-9_]”,非法字符使用" "代替。

    • LabelValue:不能含有 "|", "#","$" 等符号,如有的话使用 "_" 代替。

  • 将__labels__中 LabelValue 为空字符串的Label给 drop 掉,但该条数据仍保留。

  • 去除__labels__字段中的重复 Label,保留逻辑按LabelValue的字母序。

示例

  • 示例1:增加label

    • SPL语句

      * | extend qps = '10'|metric-to-metric -add_labels='["qps"]'
    • 输入数据

      __labels__:host#$#myhost
      __name__:rt
      __time_nano__:1614739608
      __value__:123
    • 输出结果

      __labels__:host#$#myhost|qps#$#10
      __name__:rt
      __time_nano__:1614739608
      __value__:123
  • 示例2:删除label

    • SPL语句

      * | metric-to-metric -del_labels='["qps"]'
    • 输入数据

      __labels__:host#$#myhost|qps#$#10
      __name__:rt
      __time_nano__:1614739608
      __value__:123
    • 输出结果

      __labels__:host#$#myhost
      __name__:rt
      __time_nano__:1614739608
      __value__:123
  • 示例3:重命名label

    • SPL语句

      * | metric-to-metric -rename_labels='{"host":"etl_host"}'
    • 输入数据

      __labels__:host#$#myhost|qps#$#10
      __name__:rt
      __time_nano__:1614739608
      __value__:123
    • 输出结果

      __labels__:etl_host#$#myhost|qps#$#10
      __name__:rt
      __time_nano__:1614739608
      __value__:123
  • 示例4:一键format非法数据

    • SPL语句

      * | metric-to-metric -format
    • 输入数据

      __labels__:host#$#myhost|qps#$#10|asda$cc#$#j|ob|schema#$#|#$#|#$#xxxx
      __name__:rt
      __time_nano__:1614739608
      __value__:123
    • 输出结果

      __labels__:asda_cc#$#j|host#$#myhost|qps#$#10
      __name__:rt
      __time_nano__:1614739608
      __value__:123

聚合指令

stats

用于统计分析日志的指令,类似 SQL 中的聚合函数(如 COUNTSUMAVG 等)。对日志数据中的特定字段进行统计、分组和聚合操作。

重要
  • 该指令专用于Logstore的查询分析,不适用于新版数据加工、SPL规则消费、写入处理器和Logtail配置等场景。

  • 默认情况stats返回前100条聚合结果,如果需要返回更多可以结合limit指令使用

语法

stats <output>=<aggOperator> by <group>,[<group>...]

参数说明

参数

类型

必填

说明

output

String

为统计结果字段指定别名。

aggOperator

SQLExp

支持以下聚合函数:

  • count

  • count_if

  • min

  • max

  • sum

  • avg

  • skewness

  • kurtosis

  • approx_percentile

  • approx_distinct

  • bool_and

  • bool_or

  • every

  • arbitrary

  • array_agg

group

String

指定聚合的维度,类似sqlgroup by的字段

示例

  • 示例1:对于accesslogip统计pv

    • SPL语句

      * | stats pv=count(*) by ip
    • 输入数据

      ip: 192.168.1.1
      latencyMs: 10
      
      ip: 192.168.1.1
      latencyMs: 20
      
      ip: 192.168.1.2
      latencyMs: 10
    • 输出数据

      ip: 192.168.1.2
      pv: 1
      
      ip: 192.168.1.1
      pv: 2
  • 示例2:对于accesslog统计所有ip的延迟min/max

    • SPL语句

      * 
      | extend latencyMs=cast(latencyMs as bigint)
      | stats minLatencyMs=min(latencyMs), maxLatencyMs=max(latencyMs) by ip
    • 输入数据

      ip: 192.168.1.1
      latencyMs: 10
      
      ip: 192.168.1.1
      latencyMs: 20
      
      ip: 192.168.1.2
      latencyMs: 10
    • 输出数据

      ip: 192.168.1.2
      minLatencyMs: 10
      maxLatencyMs: 20
      
      ip: 192.168.1.1
      minLatencyMs: 10
      maxLatencyMs: 10
  • 示例3:对于accesslog统计所有pv

    • SPL语句

      * | stats pv=count(*)
    • 输入数据

      ip: 192.168.1.1
      latencyMs: 10
      
      ip: 192.168.1.1
      latencyMs: 20
      
      ip: 192.168.1.2
      latencyMs: 10
    • 输出数据

      pv: 3

sort

对查询结果进行排序,支持对字段值或统计结果进行升序(asc)或降序(desc)排序。它是日志分析中快速定位关键数据、生成有序报表的重要工具。

重要

该指令专用于Logstore的查询分析,不适用于新版数据加工、SPL规则消费、写入处理器和Logtail配置等场景。

语法

sort <field> [asc/desc] ,(<field> [asc/desc])

参数说明

参数

类型

必填

说明

field

String

指定排序的字段。支持以下类型字段:

  • 原始日志字段(如 statusrequest_time)。

  • 统计字段(如 count(*)avg(response_time))。

  • 时间字段(如 @timestamp)。

asc/desc

String

  • asc:升序排序(默认)。

  • desc:降序排序(常用场景:按统计值从高到低排序)。

示例

对于accessloglatencyMs排序。

  • SPL语句

    * 
    | extend latencyMs=cast(latencyMs as bigint) 
    | sort latencyMs desc
  • 输入数据

    ip: 192.168.1.1
    latencyMs: 10
    
    ip: 192.168.1.1
    latencyMs: 20
    
    ip: 192.168.1.2
    latencyMs: 15
  • 输出数据

    ip: 192.168.1.1
    latencyMs: 20
    
    ip: 192.168.1.2
    latencyMs: 15
    
    ip: 192.168.1.1
    latencyMs: 10

limit

用于限制查询结果返回的日志行数,是控制数据量的核心指令之一。通过 limit 可有效防止查询结果过大导致的性能问题或资源浪费,适用于日志分析、实时监控等多种场景。

重要
  • 该指令专用于Logstore的查询分析,不适用于新版数据加工、SPL规则消费、写入处理器和Logtail配置等场景。

  • 若不配合sort指令明确排序规则,limit指令的输出结果的 顺序是随机的(因日志存储时未保证自然顺序)。

语法

limit (<offset>,) <size>

参数说明

参数

类型

必填

说明

offset

Interger

跳过前offset行。

size

Interger

行数限制。

示例

对于accessloglatencyMs排序后取第一条。

  • SPL语句

    * 
    | extend latencyMs=cast(latencyMs as bigint) 
    | sort latencyMs
    | limit 1
  • 输入数据

    ip: 192.168.1.1
    latencyMs: 10
    
    ip: 192.168.1.1
    latencyMs: 20
    
    ip: 192.168.1.2
    latencyMs: 15
  • 输出数据

    ip: 192.168.1.1
    latencyMs: 20