写入处理器可在日志数据写入Logstore前对数据进行处理,例如字段修改,字段解析,数据过滤和数据脱敏。本文介绍写入处理器的配置方法,以及使用场景示例。
前提条件
已创建Project、标准型Logstore并完成日志采集配置。具体操作,请参见创建项目Project、创建Logstore和数据采集概述。
使用场景
假如要从原始日志中截取三个字段:request_method
、request_uri
和status
。您可按照以下步骤操作。
原始日志
body_bytes_sent: 22646
host: www.example.com
http_protocol: HTTP/1.1
remote_addr: 192.168.31.1
remote_user: Elisa
request_length: 42450
request_method: GET
request_time: 675
request_uri: /index.html
status: 200
time_local: 2024-12-04T13:47:54+08:00
操作步骤
创建写入处理器
登录日志服务控制台。
在Project列表区域,单击目标Project。
在左侧导航栏选择
。在写入处理器页签,单击创建。在创建处理器面板配置处理器名称、SPL和处理失败,配置完成后单击确定。参数说明如下。
参数
说明
处理器名称
输入处理器的名称,例如
nginx-logs-text
。描述
处理器的描述。
SPL
输入SPL语句。例如:
* | project request_method, request_uri, status
更多信息,请参见SPL指令。
处理失败
SPL处理失败后的行为,支持:
保留原始数据
丢弃原始数据
说明这里处理失败仅指SPL执行失败,例如数据不合法导致算子执行异常。不包含SPL语法错误的场景。
如果SPL语法配置错误导致解析失败,默认会保留原始数据。
将写入处理器应用到Logstore。
在目标Project页面,在左侧导航栏单击日志存储,然后将鼠标悬浮在目标Logstore上,单击
。在Logstore属性页面,单击右上角修改,在编辑状态下配置写入处理器,选择需要关联的写入处理器,然后单击右上角的保存。
说明关联写入处理器,仅对增量日志生效,生效时间1分钟左右。
在Logstore主页面,单击查询/分析,查询采集到的日志。
更多使用场景示例
字段修改
通过
project
、project-away
、project-rename
、extend
等 SPL 指令可以对数据的字段进行增删改处理。例如原始日志为:body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time_local: 2024-12-04T13:47:54+08:00
使用场景
需求描述
SPL语句
结果
保留特定字段
仅保留如下三个字段:
request_method
request_uri
status
* | project request_method, request_uri, status
request_method: PUT request_uri: /request/path-1/file-6?query=123456 status: 200
仅保留如下三个字段,且需要对结果字段重命名:
request_method
重命名为method
request_uri
重命名为uri
status
* | project method=request_method, uri=request_uri, status
method: PUT uri: /request/path-1/file-6?query=123456 status: 200
保留所有
request_
开头的字段。* | project -wildcard "request_*"
request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456
删除特定字段
删除如下字段:
http_protocol
referer
remote_addr
remote_user
* | project-away http_protocol, referer, remote_addr, remote_user
body_bytes_sent: 22646 host: www.example.com request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time_local: 2024-12-04T13:47:54+08:00
删除所有
request_
开头的字段。* | project-away -wildcard "request_*"
body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa status: 200 time_local: 2024-12-04T13:47:54+08:00
新增字段
新增
app
字段,值固定为test-app
。* | extend app='test-app'
app: test-app body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time_local: 2024-12-04T13:47:54+08:00
新增
request_query
字段,值需要从request_uri
中进行提取。* | extend request_query=url_extract_query(request_uri)
body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_query: query=123456 request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time_local: 2024-12-04T13:47:54+08:00
修改字段名
将
time_local
重命名为time
。* | project-rename time=time_local
body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6?query=123456 status: 200 time: 2024-12-04T13:47:54+08:00
修改字段值
将
request_uri
字段进行处理,仅保留路径部分,丢掉参数部分。* | extend request_uri=url_extract_path(request_uri)
或者
* | extend request_uri=regexp_replace(request_uri, '\?.*', '')
body_bytes_sent: 22646 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.31.1 remote_user: Elisa request_length: 42450 request_method: PUT request_time: 675 request_uri: /request/path-1/file-6 status: 200 time_local: 2024-12-04T13:47:54+08:00
字段解析
通过
parse-regexp
、parse-json
、parse-csv
等 SPL 指令,以及 SQL 中的正则、JSON 等处理函数,可以实现对数据的字段解析和提取。使用场景
原始数据
需求描述
SPL语句
结果
正则解析
content: 192.168.1.75 - David [2024-07-31T14:27:24+08:00] "PUT /request/path-0/file-8 HTTP/1.1" 819 21577 403 73895 www.example.com www.example.com "Mozilla/5.0 (Windows NT 5.2; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1"
通过正则表达式对 Nginx 访问日志进行字段提取,并丢弃原来的
content
字段。* | parse-regexp content, '(\S+)\s-\s(\S+)\s\[(\S+)\]\s"(\S+)\s(\S+)\s(\S+)"\s(\d+)\s(\d+)\s(\d+)\s(\d+)\s(\S+)\s(\S+)\s"(.*)"' as remote_addr, remote_user, time_local, request_method, request_uri, http_protocol, request_time, request_length, status, body_bytes_sent, host, referer, user_agent | project-away content
body_bytes_sent: 73895 host: www.example.com http_protocol: HTTP/1.1 referer: www.example.com remote_addr: 192.168.1.75 remote_user: David request_length: 21577 request_method: PUT request_time: 819 request_uri: /request/path-0/file-8 status: 403 time_local: 2024-07-31T14:27:24+08:00 user_agent: Mozilla/5.0 (Windows NT 5.2; WOW64) AppleWebKit/535.1 (KHTML, like Gecko) Chrome/13.0.782.41 Safari/535.1
request_method: PUT request_uri: /request/path-0/file-8 status: 200
从
request_uri
字段中提取出file-8
部分,并命名为file
字段。* | extend file=regexp_extract(request_uri, 'file-.*')
file: file-8 request_method: PUT request_uri: /request/path-0/file-8 status: 200
JSON解析
headers: {"Authorization": "bearer xxxxx", "X-Request-ID": "29bbe977-9a62-4e4a-b2f4-5cf7b65d508f"}
将
headers
字段进行 JSON 解析,并丢弃原来的headers
字段。* | parse-json headers | project-away headers
Autorization: bearer xxxxx X-Request-ID: 29bbe977-9a62-4e4a-b2f4-5cf7b65d508f
从
headers
中提取部分字段,例如提取出Authorization
字段,并命名为token
* | extend token=json_extract_scalar(headers, 'Authorization')
headers: {"Authorization": "bearer xxxxx", "X-Request-ID": "29bbe977-9a62-4e4a-b2f4-5cf7b65d508f"} token: bearer xxxxx
request: {"body": {"user_id": 12345, "user_name": "Alice"}}
将
request
字段中的body
子字段进行JSON解析。* | parse-json -path='$.body' request
request: {"body": {"user_id": 12345, "user_name": "Alice"}} user_id: 12345 user_name: Alice
分隔符解析
content: 192.168.0.100,"10/Jun/2019:11:32:16,127 +0800",www.example.com
按照逗号将字段进行分割,并丢弃原来的
content
字段。* | parse-csv -quote='"' content as ip, time, host | project-away content
host: www.example.com ip: 192.168.0.100 time: 10/Jun/2019:11:32:16,127 +0800
content: 192.168.0.100||10/Jun/2019:11:32:16,127 +0800||www.example.com
使用
||
作为分隔符,将字段进行分割,并丢弃原来的content
字段。* | parse-csv -delim='||' content as ip, time, host | project-away content
host: www.example.com ip: 192.168.0.100 time: 10/Jun/2019:11:32:16,127 +0800
数据过滤
通过
where
指令可以对数据进行过滤。需要特别注意的是,在SPL处理过程中,会默认将所有原始字段当做文本来进行处理,因此如果需要进行数值操作,应当先通过类型转换函数函数进行类型转换。
原始数据
需求描述
SPL语句
结果
request_id: ddbde824-7c3e-4ff1-a6d1-c3a53fd4a919 status: 200 --- request_id: 7f9dad20-bc57-4aa7-af0e-436621f1f51d status: 500
仅保留
status
为200
的数据。* | where status='200'
或者
* | where cast(status as bigint)=200
request_id: ddbde824-7c3e-4ff1-a6d1-c3a53fd4a919 status: 200
request_id: ddbde824-7c3e-4ff1-a6d1-c3a53fd4a919 status: 200 --- request_id: 7f9dad20-bc57-4aa7-af0e-436621f1f51d status: 500 error: something wrong
仅保留不存在
error
字段的数据。* | where error is null
request_id: ddbde824-7c3e-4ff1-a6d1-c3a53fd4a919 status: 200
仅保留存在
error
字段的数据。* | where error is not null
request_id: 7f9dad20-bc57-4aa7-af0e-436621f1f51d status: 500 error: something wrong
method: POST request_uri: /app/login --- method: GET request_uri: /user/1/profile status: 404 --- method: GET request_uri: /user/2/profile status: 200
仅保留
request_uri
为/user/
开头的数据。* | where regexp_like(request_uri, '^\/user\/')
method: GET request_uri: /user/1/profile status: 404 --- method: GET request_uri: /user/2/profile status: 200
保留
request_uri
为/user/
开头,且status
为200
的数据。* | where regexp_like(request_uri, '^\/user\/') and status='200'
method: GET request_uri: /user/2/profile status: 200
数据脱敏
通过 SPL
extend
指令结合正则处理、字符串处理、URL处理等 SQL 函数,可以实现数据的脱敏操作。使用
regexp_replace
函数对字段的值进行正则替换的时候,支持使用捕获组。在替换值的时候,可以使用\1
、\2
… 分别表示第一个、第二个…捕获组的值。例如
regexp_replace('192.168.1.1', '(\d+)\.(\d+)\.\d+\.\d+', '\1.\2.*.*')
结果为192.168.*.*
。原始数据
需求描述
SPL语句
结果
request_uri: /api/v1/resources?user=123&ticket=abc status: 200
request_uri
参数中包含一些敏感信息,需要移除。* | extend request_uri=url_extract_path(request_uri)
或者
* | extend request_uri=regexp_replace(request_uri, '\?.*', '')
request_uri: /api/v1/resources status: 200
client_ip: 192.168.1.123 latency: 100
对 IP 做脱敏处理,将中间两部分替换为星号。
* | extend client_ip=regexp_replace(client_ip, '(\d+)\.\d+\.\d+\.(\d+)', '\1.*.*.\2')
client_ip: 192.*.*.123 latency: 100
sql: SELECT id, name, config FROM app_info WHERE name="test-app" result_size: 1024
sql
字段中可能包含一些敏感信息,因此需要仅保留操作以及对应的表名即可。* | extend table=regexp_extract(sql, '\bFROM\s+([^\s;]+)|\bINTO\s+([^\s;]+)|\bUPDATE\s+([^\s;]+)', 1) | extend action=regexp_extract(sql,'\b(SELECT|INSERT|UPDATE|DELETE|CREATE|DROP|ALTER)\b', 1) | project-away sql
action: SELECT table: app_info result_size: 1024