一、背景
grok作为解析解析工具,本身支持很多种类的日期格式,但是我们的日期格式是:yyyy-MM-dd HH:mm:ss.SSS,比如2024-04-08 16:27:31.855。
- TIMESTAMP_ISO8601: 匹配ISO 8601日期时间格式,例如2024-04-08T10:41:48Z。
- DATE: 匹配常见的日期格式,例如Apr 8, 2024。
- TIMESTAMP: 匹配多种日期时间组合格式,例如Apr 8 10:41:48。
- TIMESTAMP_SEC: 匹配以秒为单位的UNIX时间戳,例如1617924862。
- TIMESTAMP_MSEC: 匹配以毫秒为单位的UNIX时间戳,例如1617924862123。
- TIMESTAMP_USEC: 匹配以微秒为单位的UNIX时间戳,例如1617924862123456。
- TIMESTAMP_NSEC: 匹配以纳秒为单位的UNIX时间戳,例如1617924862123456789。
- DATE_TIME: 匹配日期和时间的组合,例如2024-04-08 10:41:48。
- DATE_TIME_TZ: 匹配带有时区信息的日期和时间组合,例如2024-04-08T10:41:48+02:00。
- DATE_TIME_TZ_OFFSET: 匹配带有时区偏移量的日期和时间组合,例如2024-04-08 10:41:48 GMT+02:00。
- EPOCH: 匹配从1970年1月1日开始的秒数,例如1617924862。
- EPOCH_MS: 匹配从1970年1月1日开始的毫秒数,例如1617924862123。
二、grok增加自定义正则表达式
grok自带的正则表达式配置路径是:/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns
bash-4.2$ ls -la
total 112
drwxrwsr-x 2 logstash root 335 Oct 16 2020 .
drwxrwsr-x 4 logstash root 176 Oct 16 2020 ..
-rw-rw-r-- 1 logstash root 1831 Oct 16 2020 aws
-rw-rw-r-- 1 logstash root 4831 Oct 16 2020 bacula
-rw-rw-r-- 1 logstash root 260 Oct 16 2020 bind
-rw-rw-r-- 1 logstash root 2154 Oct 16 2020 bro
-rw-rw-r-- 1 logstash root 879 Oct 16 2020 exim
-rw-rw-r-- 1 logstash root 10095 Oct 16 2020 firewalls
-rw-rw-r-- 1 logstash root 5338 Oct 16 2020 grok-patterns
-rw-rw-r-- 1 logstash root 3251 Oct 16 2020 haproxy
-rw-rw-r-- 1 logstash root 987 Oct 16 2020 httpd
-rw-r--r-- 1 root root 1388 Apr 9 09:19 java
-rw-rw-r-- 1 logstash root 1087 Oct 16 2020 junos
-rw-rw-r-- 1 logstash root 1037 Oct 16 2020 linux-syslog
-rw-rw-r-- 1 logstash root 74 Oct 16 2020 maven
-rw-rw-r-- 1 logstash root 49 Oct 16 2020 mcollective
-rw-rw-r-- 1 logstash root 190 Oct 16 2020 mcollective-patterns
-rw-rw-r-- 1 logstash root 614 Oct 16 2020 mongodb
-rw-rw-r-- 1 logstash root 9597 Oct 16 2020 nagios
-rw-rw-r-- 1 logstash root 142 Oct 16 2020 postgresql
-rw-rw-r-- 1 logstash root 845 Oct 16 2020 rails
-rw-rw-r-- 1 logstash root 224 Oct 16 2020 redis
-rw-rw-r-- 1 logstash root 188 Oct 16 2020 ruby
-rw-rw-r-- 1 logstash root 404 Oct 16 2020 squid
文章开头部分提及的日期正则,大多数是配置在文件grok-patterns里。
现在我们的业务日志示例见下:
2024-04-09 11:00:11.035 INFO [auth-service,] 14591 — [AuthService_EventPool_291503862] c.x.s.a.i.e.h.LoginLogEventHandler : LoginLogEventHandler - writeLoginLog - 登录登出日志 [id=1777531927092264963\tuserId=1233\ttenantId=1\tappCode=XA106004\taccountType=0\tloginName=cs361\tusername=测361\tosName=TB223FC_S000001_240206_XX\tversionName=test_v3.111.5.20240321S.C\tdeviceId=HA1WFS68\tpackageName=com.xx.xxxstu\tclientIp=172.27.25.139\tmac=26:21:03:F1:1C:46\tdeviceModel=Lenovo TB223FC\tloginOutType=101\timei=Unknown_Value\tdate=20240409110011\tosVersion= 12]
那么grok正则表达式应该如何呢?
grok {
match => {"message"=>"%{JAVA_DATE:logdate}\s+%{XHJVM_VALUE:logType}\s.*登录登出日志\s+\[id=(%{FIELD_VALUE:id}?\s+)userId=(%{FIELD_VALUE:userId}?\s+)tenantId=(%{FIELD_VALUE:tenantId}?\s+)appCode=(%{FIELD_VALUE:appCode}?\s+)accountType=(%{FIELD_VALUE:accountType}?\s+)loginName=(%{FIELD_VALUE:loginName}?\s+)username=(%{FIELD_VALUE:username}?\s+)osName=(%{FIELD_VALUE:osName}?\s+)versionName=(%{FIELD_VALUE:versionName}?\s+)deviceId=(%{FIELD_VALUE:deviceId}?\s+)packageName=(%{FIELD_VALUE:packageName}?\s+)clientIp=(%{FIELD_VALUE:clientIp}?\s+)mac=(%{FIELD_VALUE:mac}?\s+)deviceModel=(%{FIELD_VALUE:deviceModel}?\s+)loginOutType=(%{FIELD_VALUE:loginOutType}?\s+)imei=(%{FIELD_VALUE:imei}?\s+)date=(%{FIELD_VALUE:date}?\s+)osVersion=(%{FIELD_VALUE:osVersion}?)\]"}
}
可以看到,我们这里针对时间格式进行了自定义,在/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/java中增加了以下正则表达式:
JAVA_DATE %{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:?%{MINUTE}(?::?%{SECOND})?
XHJVM_VALUE [a-zA-Z]{4,5}
FIELD_VALUE [^\n]+
完整的java文件见下:(绿色部分为新增的正则表达式)
三、docker-compose挂载文件
新增挂载宿主机文件logstash/conf/java至/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/java,完整的logstash启动命令见下:
logstash:
image: elastic/logstash:7.9.3
restart: always
container_name: logstash
command: logstash -f /usr/share/logstash/pipeline/*.conf
volumes:
- ./logstash/conf/logstash.conf:/usr/share/logstash/pipeline/logstash.conf
- ./logstash/conf/auth.conf:/usr/share/logstash/pipeline/auth.conf
- ./logstash/conf/java:/usr/share/logstash/vendor/bundle/jruby/2.5.0/gems/logstash-patterns-core-4.1.2/patterns/java
- ./logstash/template.json:/etc/logstash/template.json
ports:
- "5044:5044"
- "9600:9600"
environment:
- "LS_JAVA_OPTS=-Xms512m -Xmx512m"
- elasticsearch.hosts=elasticsearch:9200
# 解决logstash监控连接报错
- xpack.monitoring.elasticsearch.hosts=elasticsearch:9200
- "TZ=Asia/Shanghai"
depends_on:
- elasticsearch
四、总结
编写grok的关键就是搞清楚其正则匹配,它已自带了许多格式,本文侧重描述如何自定义正则表达式。