日志服务数据加工最佳实践: 使用正则与grok解析Ngnix日志

简介: 本篇介绍日志服务数据加工最佳实践: 使用正则表达式与grok解析Ngnix日志, 使用grok自带的400+模式实现最简化解析

2000元阿里云代金券免费领取,2核4G云服务器仅664元/3年,新老用户都有优惠,立即抢购>>>


阿里云采购季(云主机223元/3年)活动入口:请点击进入>>>,


阿里云学生服务器(9.5元/月)购买入口:请点击进入>>>,


本部分实践案例,旨在通过一种场景多种解决方案的对比,选择出一种最快最好的解决方案。本专题主要讲解正则解析方面的场景实践。

场景:解析Nginx日志

以下以一条Nginx日志为例,向大家展开如何解析Nginx日志的多种方案。

203.208.60.89 - - [04/Jan/2019:16:06:38 +0800] "GET /atom.xml HTTP/1.1" 200 273932 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

需求

1、从Nginx日志中提取出clientip、ident、auth、timestamp、verb、request、url、httpversion、response、bytes、referrer、agent信息
2、对解析出来的url进行再提取,提取出url_proto、url_host、url_param
3、对解析出来的url_param进行再提取,提取出url_path、url_query信息

原始日志

在控制台收集到的日志格式是string格式,如下所示:

__source__:  30.43.16.15
__tag__:__client_ip__:  12.120.75.140
__tag__:__receive_time__:  1563443076
content: 203.208.60.89 - - [04/Jan/2019:16:06:38 +0800] "GET http://cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0 HTTP/1.1" 200 273932 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

LOG DSL编排

本部分将提供两种方案,解决以上需求。

方案一:正则解析

1、针对需求1解析Nginx日志的加工编排如下:

e_regex("content",r'(?P<ip>\d+\.\d+\.\d+\.\d+)( - - \[)(?P<datetime>[\s\S]+)\] \"(?P<verb>[A-Z]+) (?P<request>[\S]*) (?P<protocol>[\S]+)["](?P<code>\d+) (?P<sendbytes>\d+) ["](?P<refere>[\S]*)["] ["](?P<useragent>[\S\s]+)["]')

预览处理日志:

ip: 203.208.60.89
datetime: 04/Jan/2019:16:06:38 +0800
verb: GET
request: http://cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0
protocol: HTTP/1.1
code: 200
sendbytes: 273932
refere: -
useragent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)

2、针对需求2解析第一步加工后得到的url的加工编排如下:

e_regex('url',r'(?P<url_proto>(\w+)):\/\/(?P<url_domain>[a-z0-9.]*[^\/])(?P<uri_param>(.+)$)')

预览处理日志:

url_proto: http
url_domain: cdn1cdedge0001.coxlab.net
uri_param: /_astats?application=&inf.name=eth0

3、针对需求3解析第二步得到的url参数的加工编排如下:

e_regex('uri_param',r'(?P<uri_path>\/\_[a-z]+[^?])\?(?<uri_query>(.+)$)')

预览处理日志:

uri_path: /_astats
uri_query: application=&inf.name=eth0

4、综上LOG DSL规则可以如以下形式:

"""第一步:初步解析Nginx日志"""
e_regex("content",r'(?P<ip>\d+\.\d+\.\d+\.\d+)( - - \[)(?P<datetime>[\s\S]+)\] \"(?P<verb>[A-Z]+) (?P<request>[\S]*) (?P<protocol>[\S]+)["](?P<code>\d+) (?P<sendbytes>\d+) ["](?P<refere>[\S]*)["] ["](?P<useragent>[\S\s]+)["]')
"""第二步:解析第一步得到的url"""
e_regex('url',r'(?P<url_proto>(\w+)):\/\/(?P<url_domain>[a-z0-9.]*[^\/])(?P<uri_param>(.+)$)')
"""第三步:解析第二步的到的url参数"""
e_regex('uri_param',r'(?P<uri_path>\/\_[a-z]+[^?])\?(?<uri_query>(.+)$)')

预览综上处理后的日志如下:

__source__:  30.43.16.15
__tag__:__client_ip__:  12.120.75.140
__tag__:__receive_time__:  1563443076
content: 203.208.60.89 - - [04/Jan/2019:16:06:38 +0800] "GET http://cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0 HTTP/1.1" 200 273932 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
ip: 203.208.60.89
datetime: 04/Jan/2019:16:06:38 +0800
verb: GET
request: http://cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0
protocol: HTTP/1.1
code: 200
sendbytes: 273932
refere: -
useragent: Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)
url_proto: http
url_domain: cdn1cdedge0001.coxlab.net
uri_param: /_astats?application=&inf.name=eth0
uri_path: /_astats
uri_query: application=&inf.name=eth0                        

方案二:Grok解析

1、使用grok模式解析Nginx日志,只需要COMBINEDAPACHELOG模式即可。

模式 规则 说明
COMMONAPACHELOG `%{IPORHOST:clientip} %{HTTPDUSER:ident} %{USER:auth} [%{HTTPDATE:timestamp}] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})? %{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes} -)` 解析出clientip、ident、auth、timestamp、verb、request、httpversion、response、bytes字段内容
COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent} 解析出上一行中所有字段,另外还解析出referrer、agent字段

针对需求1解析Nginx日志的加工编排如下:

e_regex('content',grok('%{COMBINEDAPACHELOG}'))

预览处理日志:

clientip: 203.208.60.89
ident: -
auth: -
timestamp: 04/Jan/2019:16:06:38 +0800
verb: GET
request: http://cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0
httpversion: 1.1
response: 200
bytes: 273932
referrer: "-"
agent: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"

2、解析request只需要使用grok的以下几种模式组合即可完成解析:

模式 规则 说明
URIPROTO [A-Za-z]+(\+[A-Za-z+]+)? 匹配url中的头部分,如http://hostname.domain.tld/_astats?application=&inf.name=eth0会匹配到http
USER [a-zA-Z0-9._-]+ 匹配字母、数字和._-组合
URIHOST %{IPORHOST}(?::%{POSINT:port})? 匹配IPORHOST和POSINT
URIPATHPARAM %{URIPATH}(?:%{URIPARAM})? 匹配url参数部分

针对需求2解析第一步加工后得到的request的加工编排如下:

e_regex('request',grok("%{URIPROTO:uri_proto}://(?:%{USER:user}(?::[^@]*)?@)?(?:%{URIHOST:uri_domain})?(?:%{URIPATHPARAM:uri_param})?"))

预览处理日志:

url_proto: http
url_domain: cdn1cdedge0001.coxlab.net
uri_param: /_astats?application=&inf.name=eth0

3、解析url_param可以使用grok的以下模式即可完成解析:

模式 规则 说明
GREEDYDATA .* 匹配任意或多个除换行符

针对需求3解析第二步得到的url参数的加工编排如下:

e_regex('url_param',grok("%{GREEDYDATA:uri_path}\?%{GREEDYDATA:uri_query}"))

预览处理日志:

uri_path: /_astats
uri_query: application=&inf.name=eth0

4、综上LOG DSL规则可以如以下形式:

"""第一步:初步解析Nginx日志"""
e_regex('content',grok('%{COMBINEDAPACHELOG}'))
"""第二步:解析第一步得到的url"""
e_regex('request',grok("%{URIPROTO:uri_proto}://(?:%{USER:user}(?::[^@]*)?@)?(?:%{URIHOST:uri_domain})?(?:%{URIPATHPARAM:uri_param})?"))
"""第三步:解析第二步的到的url参数"""
e_regex('url_param',grok("%{GREEDYDATA:uri_path}\?%{GREEDYDATA:uri_query}"))

预览综上处理后的日志如下:

__source__:  30.43.16.15
__tag__:__client_ip__:  12.120.75.140
__tag__:__receive_time__:  1563443076
content: 203.208.60.89 - - [04/Jan/2019:16:06:38 +0800] "GET http://cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0 HTTP/1.1" 200 273932 "-" "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
clientip: 203.208.60.89
ident: -
auth: -
timestamp: 04/Jan/2019:16:06:38 +0800
verb: GET
request: http://cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0
httpversion: 1.1
response: 200
bytes: 273932
referrer: "-"
agent: "Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)"
url_proto: http
url_domain: cdn1cdedge0001.coxlab.net
uri_param: /_astats?application=&inf.name=eth0
uri_path: /_astats
uri_query: application=&inf.name=eth0                        

对比

综上所述,可以看出使用正则解析和Grok模式解析Nginx日志两种方案优劣。

正则方案

对于不是很熟悉的开发人员使用正则解析日志效率会比较低,而且学习成本会比较大,另外一点是灵活性不够,比如在request内容改成

http://twiss@cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0

那么还使用以上正则

(?P<url_proto>(\w+)):\/\/(?P<url_domain>[a-z0-9.]*[^\/])(?P<uri_param>(.+)$)

request则会解析成

url_proto: http
url_domain: twiss@
uri_param: cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0

很显然,如果还使用原来的正则模式的话,解析出来的内容是不符合要求的。因此,还需要修改正则模式才能正常解析。由此可见,灵活的使用正则的解析的难度比较高。

Grok方案

Grok模式解析对于开发人员是友好的,对于非开发人员亦然如此。Grok学习成本低,只需要了解哪些模式代表的哪些字段类型就可以轻松解析你想解析的日志内容。Grok学习曲线低,可以通过用户文档中GROK参考来学习实践。

Grok灵活性高,比如还是以上述正则方案中例子为参考:

request内容改成

http://twiss@cdn1cdedge0001.coxlab.net/_astats?application=&inf.name=eth0

Grok模式不变

e_regex('request',grok("%{URIPROTO:uri_proto}://(?:%{USER:user}(?::[^@]*)?@)?(?:%{URIHOST:uri_domain})?(?:%{URIPATHPARAM:uri_param})?"))

request则会解析成

url_proto: http
user: twiss
url_domain: cdn1cdedge0001.coxlab.net
uri_param: /_astats?application=&inf.name=eth0

在Grok模式不变的情况下,request添加user的情况下,还是能够正确解析出正确的日志内容。

结论

从灵活性、高效性、低成本、学习曲线等方面对比, GROK都要比直接使用正则表达式要有优势. 但是GROK模式的本质其实还是正则表达式, 但是数据加工已经提供了400种模式包装了场景的正则, 建议优先使用. 当然在需要的情况下, 也可以混合使用GROK与正则甚至自行编写需要的正则.

进一步参考

欢迎扫码加入官方钉钉群获得实时更新与阿里云工程师的及时直接的支持:
image

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
相关文章
|
5天前
|
数据采集 监控 数据可视化
日志解析神器——Logstash中的Grok过滤器使用详解
日志解析神器——Logstash中的Grok过滤器使用详解
34 4
|
5天前
|
域名解析 缓存 网络协议
阿里云DNS常见问题之阿里云DNS的操作日志查不到如何解决
阿里云DNS(Domain Name System)服务是一个高可用和可扩展的云端DNS服务,用于将域名转换为IP地址,从而让用户能够通过域名访问云端资源。以下是一些关于阿里云DNS服务的常见问题合集:
|
5天前
|
消息中间件 测试技术 Python
Python使用多线程解析超大日志文件
Python使用多线程解析超大日志文件
92 0
|
5天前
|
SQL 监控 关系型数据库
数据库日志解析:深入了解MySQL中的各类日志
数据库日志解析:深入了解MySQL中的各类日志
298 0
|
2天前
|
关系型数据库 MySQL 数据库
mysql数据库bin-log日志管理
mysql数据库bin-log日志管理
|
3天前
|
存储 关系型数据库 数据库
关系型数据库文件方式存储LOG FILE(日志文件)
【5月更文挑战第11天】关系型数据库文件方式存储LOG FILE(日志文件)
13 1
|
3天前
|
运维 监控 安全
Java一分钟之-Log4j与日志记录的重要性
【5月更文挑战第16天】Log4j是Java常用的日志框架,用于灵活地记录程序状态和调试问题。通过设置日志级别和过滤器,可避免日志输出混乱。为防止日志文件过大,可配置滚动策略。关注日志安全性,如Log4j 2.x的CVE-2021-44228漏洞,及时更新至安全版本。合理使用日志能提升故障排查和系统监控效率。
21 0
|
5天前
|
C++
JNI Log 日志输出
JNI Log 日志输出
19 1
|
5天前
|
存储 运维 大数据
聊聊日志硬扫描,阿里 Log Scan 的设计与实践
泛日志(Log/Trace/Metric)是大数据的重要组成,伴随着每一年业务峰值的新脉冲,日志数据量在快速增长。同时,业务数字化运营、软件可观测性等浪潮又在对日志的存储、计算提出更高的要求。
|
5天前
|
XML Java Maven
Springboot整合与使用log4j2日志框架【详解版】
该文介绍了如何在Spring Boot中切换默认的LogBack日志系统至Log4j2。首先,需要在Maven依赖中排除`spring-boot-starter-logging`并引入`spring-boot-starter-log4j2`。其次,创建`log4j2-spring.xml`配置文件放在`src/main/resources`下,配置包括控制台和文件的日志输出、日志格式和文件切分策略。此外,可通过在不同环境的`application.yml`中指定不同的log4j2配置文件。最后,文章提到通过示例代码解释了日志格式中的各种占位符含义。

相关产品

  • 日志服务
  • 推荐镜像

    更多
    http://www.vxiaotou.com