You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

求助:无法为Sophos UTM的特定syslog日志编写grok表达式

构建Sophos UTM HTTP Proxy日志的Grok表达式

我完全懂这种感受——Sophos UTM的日志格式混合了系统日志头和自定义键值对,有时候还有截断内容,写grok确实容易卡壳。咱们一步步拆解你的日志,搞定这个表达式。

首先先把你的原始日志再贴一遍方便对照:

Apr 28 16:57:49 utm-vap-xx.domain.local 2018: 04:28-17:02:05 s-utm-01 httpproxy[52816]: id="0001" severity="info" sys="SecureWeb" sub="http" name="http access" action="pass" method="POST" srcip="10.11.110.5" dstip="216.163.176.36" user="" group="" ad_domain="" statuscode="200" cached="0" profile="REF_DefaultHTTPProfile (Default Web Filter Profile)" filteraction="REF_Defaul...

第一步:匹配系统日志头部

日志开头是标准的syslog格式部分,我们可以用预定义的grok模式来匹配:

%{MONTH:log_month} %{MONTHDAY:log_day} %{TIME:log_time} %{HOSTNAME:utm_hostname}

这部分会提取出:

  • log_month: Apr
  • log_day: 28
  • log_time: 16:57:49
  • utm_hostname: utm-vap-xx.domain.local

第二步:匹配Sophos内部时间和设备标识

接下来是UTM自己的时间戳和设备名:

%{YEAR:utm_year}: %{MONTHDAY:utm_day}-%{TIME:utm_time} %{HOSTNAME:utm_device}

提取内容:

  • utm_year: 2018
  • utm_day: 28
  • utm_time: 17:02:05
  • utm_device: s-utm-01

第三步:匹配进程信息

然后是httpproxy的进程ID:

%{DATA:process_name}\[%{NUMBER:process_id:int}\]:

这里int是把进程ID转换成整数类型,提取结果:

  • process_name: httpproxy
  • process_id: 52816

第四步:匹配键值对部分

最麻烦的就是后面的key="value"格式内容,因为有些值是空字符串(比如user=""),还有带空格的(比如profile="REF_DefaultHTTPProfile (Default Web Filter Profile)"),另外你的日志最后有截断的...,所以我们用GREEDYDATA来处理剩余内容,同时逐个匹配关键字段保证准确性:

id="%{DATA:log_id}" severity="%{DATA:severity}" sys="%{DATA:system}" sub="%{DATA:subsystem}" name="%{DATA:event_name}" action="%{DATA:action}" method="%{DATA:http_method}" srcip="%{IP:src_ip}" dstip="%{IP:dst_ip}" user="%{DATA:user}" group="%{DATA:group}" ad_domain="%{DATA:ad_domain}" statuscode="%{NUMBER:http_status:int}" cached="%{NUMBER:cached:int}" profile="%{DATA:web_filter_profile}" filteraction="%{GREEDYDATA:filter_action}"

这里用IP模式匹配IP地址更精准,int转换数字类型方便后续统计。GREEDYDATA会把filteraction的值(包括截断的...)全部捕获。

完整的Grok表达式

把所有部分组合起来,注意空格和分隔符:

%{MONTH:log_month} %{MONTHDAY:log_day} %{TIME:log_time} %{HOSTNAME:utm_hostname} %{YEAR:utm_year}: %{MONTHDAY:utm_day}-%{TIME:utm_time} %{HOSTNAME:utm_device} %{DATA:process_name}\[%{NUMBER:process_id:int}\]: id="%{DATA:log_id}" severity="%{DATA:severity}" sys="%{DATA:system}" sub="%{DATA:subsystem}" name="%{DATA:event_name}" action="%{DATA:action}" method="%{DATA:http_method}" srcip="%{IP:src_ip}" dstip="%{IP:dst_ip}" user="%{DATA:user}" group="%{DATA:group}" ad_domain="%{DATA:ad_domain}" statuscode="%{NUMBER:http_status:int}" cached="%{NUMBER:cached:int}" profile="%{DATA:web_filter_profile}" filteraction="%{GREEDYDATA:filter_action}"

测试建议

你可以用Grok Debugger(比如Elastic自带的或者本地调试工具)来测试这个表达式,把你的日志粘贴进去验证每个字段是否正确提取。如果遇到其他变体日志(比如不同的action或者profile名称),只需要调整对应的DATA部分即可——比如如果profile里的内容有特殊字符,DATA模式依然能处理,因为它匹配除了换行之外的所有字符。

内容的提问来源于stack exchange,提问作者Sean Jose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 09:34:06