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

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 本篇介绍日志服务数据加工最佳实践: 使用正则表达式与grok解析Ngnix日志, 使用grok自带的400+模式实现最简化解析


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

场景:解析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日志并进行多维度分析。
目录
相关文章
|
16天前
|
数据采集 XML 前端开发
五:《智慧的网络爬虫》— bs4数据解析
【8月更文挑战第4天】bs4(Beautiful Soup 4)是python的一个库,最主要的功能是从网页抓取数据,它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式。BeautifulSoup会帮你节省数小时甚至数天的工作时间。在本篇文章的最后设置了一个爬取全国所有天气的项目作为本篇文章的总结,愿大家有所收获~
36 6
五:《智慧的网络爬虫》— bs4数据解析
|
13天前
|
SQL 存储 算法
【数据挖掘】恒生金融有限公司2023届秋招数据ETL工程师笔试题解析
恒生科技2022年9月24号数据ETL工程师岗位的笔试题目及答案汇总,包括了SQL选择题、SQL编程题和业务应用SQL编程题,涵盖了数据库基础知识、SQL语句编写以及数据仓库概念等多个方面。
30 2
【数据挖掘】恒生金融有限公司2023届秋招数据ETL工程师笔试题解析
|
4天前
|
存储 数据采集 数据可视化
深入解析GPS接收机的位置数据文件:项目实战从数据解析到可视化
全球定位系统(GPS)是现代技术的支柱之一,广泛应用于交通导航、科学研究、智能设备等领域。GPS接收机通过接收来自卫星的信号,确定设备的地理位置,并将这些位置信息记录在数据文件中。 这些数据文件通常包含大量的信息,如时间、位置、海拔高度、卫星状态等。本篇文章将通过解析这些数据文件,展示如何利用Python和Folium库实现数据的读取、处理和可视化,帮助读者深入理解GPS数据的处理过程。
|
1天前
|
JSON Java Android开发
Android 开发者必备秘籍:轻松攻克 JSON 格式数据解析难题,让你的应用更出色!
【8月更文挑战第18天】在Android开发中,解析JSON数据至关重要。JSON以其简洁和易读成为首选的数据交换格式。开发者可通过多种途径解析JSON,如使用内置的`JSONObject`和`JSONArray`类直接操作数据,或借助Google提供的Gson库将JSON自动映射为Java对象。无论哪种方法,正确解析JSON都是实现高效应用的关键,能帮助开发者处理网络请求返回的数据,并将其展示给用户,从而提升应用的功能性和用户体验。
|
4天前
|
JSON 数据管理 关系型数据库
【Dataphin V3.9】颠覆你的数据管理体验!API数据源接入与集成优化,如何让企业轻松驾驭海量异构数据,实现数据价值最大化?全面解析、实战案例、专业指导,带你解锁数据整合新技能!
【8月更文挑战第15天】随着大数据技术的发展,企业对数据处理的需求不断增长。Dataphin V3.9 版本提供更灵活的数据源接入和高效 API 集成能力,支持 MySQL、Oracle、Hive 等多种数据源,增强 RESTful 和 SOAP API 支持,简化外部数据服务集成。例如,可轻松从 RESTful API 获取销售数据并存储分析。此外,Dataphin V3.9 还提供数据同步工具和丰富的数据治理功能,确保数据质量和一致性,助力企业最大化数据价值。
18 1
|
7天前
|
存储 数据采集 JSON
数据存储的正确规范:csv/xlsx和JSON全方位解析
数据存储的正确规范:csv/xlsx和JSON全方位解析
21 1
|
11天前
|
XML API 数据库
商品详情数据API接口概念(sku详情图属性等全面的解析)
商品详情数据API接口是指一种编程接口(API, Application Programming Interface),它允许开发者或系统以编程方式获取商品的详细信息,包括但不限于SKU(Stock Keeping Unit,库存量单位)的详细信息、商品图片、商品属性、价格、库存状态、用户评价等。这种接口通常由电商平台、商品数据库服务商或第三方数据提供商提供,旨在帮助开发者或企业快速集成商品数据到其应用程序或系统中。
|
21天前
|
监控 数据管理 关系型数据库
数据管理DMS使用问题之是否支持将操作日志导出至阿里云日志服务(SLS)
阿里云数据管理DMS提供了全面的数据管理、数据库运维、数据安全、数据迁移与同步等功能,助力企业高效、安全地进行数据库管理和运维工作。以下是DMS产品使用合集的详细介绍。
|
22天前
|
SQL 数据采集 数据管理
SQL数据:探索、管理与优化的全面解析
在信息化时代,数据成为企业核心资产。本文探讨SQL在数据探索、管理与优化中的作用:使用DESC、SELECT了解数据集;评估数据质量;发现数据特征。管理方面,涵盖数据存储、检索、更新与维护。优化则涉及索引、查询及数据库设计,确保高性能和效率。掌握SQL能有效挖掘数据价值,支持企业决策与创新。
27 1
|
24天前
|
存储 分布式计算 监控
日志数据投递到MaxCompute最佳实践
日志服务采集到日志后,有时需要将日志投递至MaxCompute的表中进行存储与分析。本文主要向用户介绍将数据投递到MaxCompute完整流程,方便用户快速实现数据投递至MaxCompute。
130 2

相关产品

  • 日志服务
  • 推荐镜像

    更多