Elasticsearch 7.17.6中Squid日志USER字段截取异常求助
Squid日志Elasticsearch解析中USER字段丢失问题解决
我已将Squid代理配置为向Elasticsearch 7.17.6发送日志,除USER字段映射外一切正常。预期格式为DOMAIN/USER,原始消息中ELK能正确接收,但映射后仅显示DOMAIN,/USER部分丢失。该字段在映射和索引模式中已配置为keyword类型,以下是filebeat pipeline.json配置:
{ "description": "Pipeline for parsing squid elasticsearch.log", "processors": [{ "grok": { "field": "message", "patterns":[ "%{POSINT:squid.proxy.request_time}.%{POSINT:squid.proxy.request_time_ms}\\|.*?%{NUMBER:squid.proxy.response_time}\\|%{IP:squid.proxy.src_ip}\\|(%{MAC:squid.proxy.mac}|-)\|%{DATA:squid.proxy.request_status}\\|%{DATA:squid.proxy.status_code}\\|%{NUMBER:squid.proxy.http_size}\\|%{WORD:squid.proxy.http_method}\\|(%{IP:squid.proxy.server_ip}|%{HOSTNAME:squid.proxy.website})\|(%{USER:squid.proxy.user})|(%{USER:{WORD}/{WORD}}|-)\|%{WORD:squid.proxy.hierarchy}\\|(%{IP:squid.proxy.server_ip}|-)\|(%{DATA:squid.proxy.ct}|-)\|(%{NUMBER:squid.proxy.total_time}|-)\|%{UUID:squid.proxy.uuid}\|(%{HOSTNAME:squid.proxy.website}|-)\|(%{DATA:squid.proxy.useragent}|-)\|\|\|.*?(category:.*?cinfo:%{NUMBER:squid.proxy.category_id}-%{WORD:squid.proxy.category_name};|-).*" ], "ignore_missing": false, "ignore_failure": false } },{ "rename":{ "field": "message", "target_field": "squid.proxy.original_message" } }, { "date": { "field": "squid.proxy.request_time", "formats": ["UNIX", "dd MMM H:m:s"], "ignore_failure": true } }, { "geoip": { "field": "squid.proxy.server_ip", "target_field": "squid.proxy.geo", "ignore_missing": true } }, { "remove": { "field": "message", "ignore_missing": true, "ignore_failure": true } }], "on_failure" : [{ "drop" : { "ignore_failure" : true } }] }
问题原因
原grok配置中USER字段的匹配规则存在两个问题:
- 默认的
USERgrok模式仅匹配[a-zA-Z0-9._-]+,不包含/符号,因此只能捕获DOMAIN/USER中/之前的部分 - 第二个分支
%{USER:{WORD}/{WORD}}语法错误,无法正确解析包含/的内容
解决方法
修改grok模式中USER字段的匹配规则,使用能包含/的模式替换原有规则:
方案1:使用DATA模式(简单直接)
将原配置中(%{USER:squid.proxy.user})|(%{USER:{WORD}/{WORD}}|-)替换为(%{DATA:squid.proxy.user}|-),DATA模式可匹配任意非空白字符,能完整捕获DOMAIN/USER格式内容。
修改后的完整pipeline配置:
{ "description": "Pipeline for parsing squid elasticsearch.log", "processors": [{ "grok": { "field": "message", "patterns":[ "%{POSINT:squid.proxy.request_time}.%{POSINT:squid.proxy.request_time_ms}\\|.*?%{NUMBER:squid.proxy.response_time}\\|%{IP:squid.proxy.src_ip}\\|(%{MAC:squid.proxy.mac}|-)\|%{DATA:squid.proxy.request_status}\\|%{DATA:squid.proxy.status_code}\\|%{NUMBER:squid.proxy.http_size}\\|%{WORD:squid.proxy.http_method}\\|(%{IP:squid.proxy.server_ip}|%{HOSTNAME:squid.proxy.website})\|(%{DATA:squid.proxy.user}|-)\|%{WORD:squid.proxy.hierarchy}\\|(%{IP:squid.proxy.server_ip}|-)\|(%{DATA:squid.proxy.ct}|-)\|(%{NUMBER:squid.proxy.total_time}|-)\|%{UUID:squid.proxy.uuid}\|(%{HOSTNAME:squid.proxy.website}|-)\|(%{DATA:squid.proxy.useragent}|-)\|\|\|.*?(category:.*?cinfo:%{NUMBER:squid.proxy.category_id}-%{WORD:squid.proxy.category_name};|-).*" ], "ignore_missing": false, "ignore_failure": false } },{ "rename":{ "field": "message", "target_field": "squid.proxy.original_message" } }, { "date": { "field": "squid.proxy.request_time", "formats": ["UNIX", "dd MMM H:m:s"], "ignore_failure": true } }, { "geoip": { "field": "squid.proxy.server_ip", "target_field": "squid.proxy.geo", "ignore_missing": true } }, { "remove": { "field": "message", "ignore_missing": true, "ignore_failure": true } }], "on_failure" : [{ "drop" : { "ignore_failure" : true } }] }
方案2:自定义严格匹配模式
如果需要更严格的字符限制,可以先自定义包含/的grok模式,再用于匹配:
- 在grok的
patterns数组最开头添加自定义模式:USERDOMAIN [a-zA-Z0-9._-/]+ - 将USER字段匹配规则替换为
(%{USERDOMAIN:squid.proxy.user}|-)
验证
修改后重新部署pipeline,发送测试日志即可验证DOMAIN/USER格式的内容是否被完整捕获。
内容的提问来源于stack exchange,提问作者André Bolinhas
相关产品推荐
相关产品推荐

