相关文章推荐

在项目中会产生大量的日志以方便问题跟踪,有时需要统计分析系统运行期间的日志,例如:分析系统使用情况,使用人数,系统错误信息等等。根据不同的日志类别,生成可视化图表展示,所以就需要需要对日志进行处理,将每一行拆分成多个字段,存入数据库或者es,便于统计分析,生成报表。

由于之前没有接触过,网上通过搜集资料,找到使用logstash来分割反向代理的日志,由单个简单的正则组合,就能对一大段文字进行切割,惊叹与简单可配置。后来找到了java也可以通过Grok进行日志的统计分析,Grok进行日志处理的好处有:1:默认集成了多中正则表达式;2:支持自定义的正则表达式。

grok是一种采用组合多个预定义的正则表达式,用来匹配分割文本并映射到关键字的工具。通常用来对日志数据进行预处理。logstash的filter模块中grok插件是其实现之一。

Grok内置了许多的正则表达式库,便于我们直接使用开发(github搜索grok,项目一般都有这个pattern文件)
grok支持自定义匹配字段规则,可以灵活满足扩展的需求。

grok预定义匹配字段

USERNAME [a-zA-Z0-9._-]+
USER %{USERNAME}
INT (?:[+-]?(?:[0-9]+))
BASE10NUM (?<![0-9.+-])(?>[+-]?(?:(?:[0-9]+(?:\.[0-9]+)?)|(?:\.[0-9]+)))
NUMBER (?:%{BASE10NUM})
BASE16NUM (?<![0-9A-Fa-f])(?:[+-]?(?:0x)?(?:[0-9A-Fa-f]+))
BASE16FLOAT \b(?<![0-9A-Fa-f.])(?:[+-]?(?:0x)?(?:(?:[0-9A-Fa-f]+(?:\.[0-9A-Fa-f]*)?)|(?:\.[0-9A-Fa-f]+)))\b
POSINT \b(?:[1-9][0-9]*)\b
NONNEGINT \b(?:[0-9]+)\b
WORD \b\w+\b
NOTSPACE \S+
SPACE \s*
DATA .*?
GREEDYDATA .*
QUOTEDSTRING (?>(?<!\\)(?>"(?>\\.|[^\\"]+)+"|""|(?>'(?>\\.|[^\\']+)+')|''|(?>`(?>\\.|[^\\`]+)+`)|``))
UUID [A-Fa-f0-9]{8}-(?:[A-Fa-f0-9]{4}-){3}[A-Fa-f0-9]{12}
# Networking
MAC (?:%{CISCOMAC}|%{WINDOWSMAC}|%{COMMONMAC})
CISCOMAC (?:(?:[A-Fa-f0-9]{4}\.){2}[A-Fa-f0-9]{4})
WINDOWSMAC (?:(?:[A-Fa-f0-9]{2}-){5}[A-Fa-f0-9]{2})
COMMONMAC (?:(?:[A-Fa-f0-9]{2}:){5}[A-Fa-f0-9]{2})
IPV6 ((([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){5}(((:[0-9A-Fa-f]{1,4}){1,2})|:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3})|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|((:[0-9A-Fa-f]{1,4})?:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})|((:[0-9A-Fa-f]{1,4}){0,2}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){2}(((:[0-9A-Fa-f]{1,4}){1,5})|((:[0-9A-Fa-f]{1,4}){0,3}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|((:[0-9A-Fa-f]{1,4}){0,4}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:))|(:(((:[0-9A-Fa-f]{1,4}){1,7})|((:[0-9A-Fa-f]{1,4}){0,5}:((25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)(\.(25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)){3}))|:)))(%.+)?
IPV4 (?<![0-9])(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))(?![0-9])
IP (?:%{IPV6}|%{IPV4})
HOSTNAME \b(?:[0-9A-Za-z][0-9A-Za-z-]{0,62})(?:\.(?:[0-9A-Za-z][0-9A-Za-z-]{0,62}))*(\.?|\b)
HOST %{HOSTNAME}
IPORHOST (?:%{HOSTNAME}|%{IP})
HOSTPORT %{IPORHOST}:%{POSINT}
# paths
PATH (?:%{UNIXPATH}|%{WINPATH})
UNIXPATH (?>/(?>[\w_%!$@:.,-]+|\\.)*)+
TTY (?:/dev/(pts|tty([pq])?)(\w+)?/?(?:[0-9]+))
WINPATH (?>[A-Za-z]+:|\\)(?:\\[^\\?*]*)+
URIPROTO [A-Za-z]+(\+[A-Za-z+]+)?
URIHOST %{IPORHOST}(?::%{POSINT:port})?
# uripath comes loosely from RFC1738, but mostly from what Firefox
# doesn't turn into %XX
URIPATH (?:/[A-Za-z0-9$.+!*'(){},~:;=@#%_\-]*)+
#URIPARAM \?(?:[A-Za-z0-9]+(?:=(?:[^&]*))?(?:&(?:[A-Za-z0-9]+(?:=(?:[^&]*))?)?)*)?
URIPARAM \?[A-Za-z0-9$.+!*'|(){},~@#%&/=:;_?\-\[\]]*
URIPATHPARAM %{URIPATH}(?:%{URIPARAM})?
URI %{URIPROTO}://(?:%{USER}(?::[^@]*)?@)?(?:%{URIHOST})?(?:%{URIPATHPARAM})?
# Months: January, Feb, 3, 03, 12, December
MONTH \b(?:Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|Jun(?:e)?|Jul(?:y)?|Aug(?:ust)?|Sep(?:tember)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\b
MONTHNUM (?:0?[1-9]|1[0-2])
MONTHNUM2 (?:0[1-9]|1[0-2])
MONTHDAY (?:(?:0[1-9])|(?:[12][0-9])|(?:3[01])|[1-9])
# Days: Monday, Tue, Thu, etc...
DAY (?:Mon(?:day)?|Tue(?:sday)?|Wed(?:nesday)?|Thu(?:rsday)?|Fri(?:day)?|Sat(?:urday)?|Sun(?:day)?)
# Years?
YEAR (?>\d\d){1,2}
HOUR (?:2[0123]|[01]?[0-9])
MINUTE (?:[0-5][0-9])
# '60' is a leap second in most time standards and thus is valid.
SECOND (?:(?:[0-5]?[0-9]|60)(?:[:.,][0-9]+)?)
TIME (?!<[0-9])%{HOUR}:%{MINUTE}(?::%{SECOND})(?![0-9])
# datestamp is YYYY/MM/DD-HH:MM:SS.UUUU (or something like it)
DATE_US %{MONTHNUM}[/-]%{MONTHDAY}[/-]%{YEAR}
DATE_EU %{MONTHDAY}[./-]%{MONTHNUM}[./-]%{YEAR}
ISO8601_TIMEZONE (?:Z|[+-]%{HOUR}(?::?%{MINUTE}))
ISO8601_SECOND (?:%{SECOND}|60)
TIMESTAMP_ISO8601 %{YEAR}-%{MONTHNUM}-%{MONTHDAY}[T ]%{HOUR}:?%{MINUTE}(?::?%{SECOND})?%{ISO8601_TIMEZONE}?
DATE %{DATE_US}|%{DATE_EU}
DATESTAMP %{DATE}[- ]%{TIME}
TZ (?:[PMCE][SD]T|UTC)
DATESTAMP_RFC822 %{DAY} %{MONTH} %{MONTHDAY} %{YEAR} %{TIME} %{TZ}
DATESTAMP_RFC2822 %{DAY}, %{MONTHDAY} %{MONTH} %{YEAR} %{TIME} %{ISO8601_TIMEZONE}
DATESTAMP_OTHER %{DAY} %{MONTH} %{MONTHDAY} %{TIME} %{TZ} %{YEAR}
DATESTAMP_EVENTLOG %{YEAR}%{MONTHNUM2}%{MONTHDAY}%{HOUR}%{MINUTE}%{SECOND}
# Syslog Dates: Month Day HH:MM:SS
SYSLOGTIMESTAMP %{MONTH} +%{MONTHDAY} %{TIME}
PROG (?:[\w._/%-]+)
SYSLOGPROG %{PROG:program}(?:\[%{POSINT:pid}\])?
SYSLOGHOST %{IPORHOST}
SYSLOGFACILITY <%{NONNEGINT:facility}.%{NONNEGINT:priority}>
HTTPDATE %{MONTHDAY}/%{MONTH}/%{YEAR}:%{TIME} %{INT}
# Shortcuts
QS %{QUOTEDSTRING}
# Log formats
SYSLOGBASE %{SYSLOGTIMESTAMP:timestamp} (?:%{SYSLOGFACILITY} )?%{SYSLOGHOST:logsource} %{SYSLOGPROG}:
COMMONAPACHELOG %{IPORHOST:clientip} %{USER:ident} %{USER:auth} \[%{HTTPDATE:timestamp}\] "(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|%{DATA:rawrequest})" %{NUMBER:response} (?:%{NUMBER:bytes}|-)
COMBINEDAPACHELOG %{COMMONAPACHELOG} %{QS:referrer} %{QS:agent}
# Log Levels
LOGLEVEL ([Aa]lert|ALERT|[Tt]race|TRACE|[Dd]ebug|DEBUG|[Nn]otice|NOTICE|[Ii]nfo|INFO|[Ww]arn?(?:ing)?|WARN?(?:ING)?|[Ee]rr?(?:or)?|ERR?(?:OR)?|[Cc]rit?(?:ical)?|CRIT?(?:ICAL)?|[Ff]atal|FATAL|[Ss]evere|SEVERE|EMERG(?:ENCY)?|[Ee]merg(?:ency)?)

maven 项目添加对应依赖

<dependency>
   <groupId>io.krakens</groupId>
   <artifactId>java-grok</artifactId>
   <version>0.1.9</version>
 </dependency>

由于不同系统的日志各不相同,其结构也挺复杂,所以grok使用正则表达式来解析日志,它对于一些常见系统的日志(如:nginx、tomcat、apache)已经内置好了正则表达式库,基本上满足绝大多数日志的需求,也可以根据日志的格式自定义正则表达式库,使用起来很简单,代码如下:

    GrokCompiler grokCompiler = GrokCompiler.newInstance();
    // 进行注册, registerDefaultPatterns()方法注册的是Grok内置的patterns
    grokCompiler.registerDefaultPatterns();
    // 添加自定的正则表达式,解析日期(例如:2021-07-07 13:45:39.210)
    grokCompiler.register("DATETIME","[0-9,\\.\\-: ]+");
    /* 传入自定义的pattern, 会从已注册的patterns里面进行配对, 
     * 例如: %{DATETIME:datetime}
     * 配对成功后, 会在match时按照固定的解析格式将解析结果存入map中, 此处datetime作为输出的key
       Grok grok = grokCompiler.compile("%{DATETIME:datetime} %{LOGLEVEL:level} %{INT:pid} --- \\[%{NOTSPACE:thread}\\] %{NOTSPACE:classed}\\s*:%{GREEDYDATA:message}");
       String logMsg = "2021-07-07 13:45:39.210  INFO 16100 --- [SpringContextShutdownHook] com.zaxxer.hikari.HikariDataSource       : Shutdown completed.";
        // 通过match()方法进行匹配, 对log进行解析, 按照指定的格式进行输出
        Match grokMatch = grok.match(logMsg);
        // 获取结果
        Map<String, Object> resultMap = grokMatch.capture();
        System.out.print(resultMap);
{datetime=2021-07-07 13:45:39.210 , level=INFO, classed=com.zaxxer.hikari.HikariDataSource, pid=16100, thread=SpringContextShutdownHook, message= Shutdown completed.}

grok在线调试地址: 在线Grok Debug工具,Grok校验|调试

在项目中会产生大量的日志以方便问题跟踪,有时需要统计分析系统运行期间的日志,例如:分析系统使用情况,使用人数,系统错误信息等等。根据不同的日志类别,生成可视化图表展示,所以就需要需要对日志进行处理,将每一行拆分成多个字段,存入数据库或者es,便于统计分析,生成报表。由于之前没有接触过,网上通过搜集资料,找到使用logstash来分割反向代理的日志,由单个简单的正则组合,就能对一大段文字进行切割,惊叹与简单可配置。后来找到了java也可以通过Grok进行日志的统计分析,Grok进行日志处理的好处有:1:默 Java Grok 是简单的API,可让您轻松 解析 日志 和其他 文件 (单行)。 使用 Java Grok ,您可以将非结构化 日志 和事件数据转换为结构化数据(JSON)。 我可以将 Grok 用作什么? 从 日志 和流程中报告错误和其他模式 解析 复杂的文本输出并将其转换为json以进行外部处理 将“一次写入,随处 使用 ”应用于正则表达式 自动为未知文本输入提供模式(您想要生成模式以供将来匹配的 日志 ) Maven仓库 <dependency> <groupId>io.krakens</groupId> <artifactId> java - grok </artifactId> <version>0.1.9</version> </dependency> 还是用gradle compile " io.krakens: java - grok :0.1.9 " 旧版本() 用法( ) 如何 使用 java Open Grok -邪恶的快速源浏览器 Open Grok 使用 Java 编写的快速且可用的源代码搜索和交叉引用引擎。 它可以帮助您搜索,交叉引用和导航您的源代码树。 它可以理解许多源代码管理系统的各种程序 文件 格式和版本控制历史。 该项目的官方页面位于: : 2. Open Grok 安装和设置 2. 1.更新 Open Grok 使用 ,版本组件进一步指示有关更新到较新版本的更多详细信息。 版本方案为xyz,任何组件的更改均解释为: x-主要向后不兼容的更新 y-需要对存储库进行完全干净的重新索引(例如,索 Logstash的 Grok 可以使蹩脚的、无结构的 日志 内容结构化 需要注意的地方 grok 模式是正则表达式,因此这个插件的性能受到正则表达式引擎严重影响,效率并不高。如果通过给定的匹配格式匹配不上会Kibana查询的时候打上tag 为 grok failed 的标签 grok 模式的语法如下: %{SYNTAX:SEMANTIC} SYNTAX:代表匹配值的类型,例如3.44可以...
由于项目中,要求统计分析系统运行期间的 日志 ,根据不同的 日志 类别,在前台JSP通过Echarts图标展示,所以需要对 日志 进行处理,将其整理成能够 使用 的JSON格式 日志 ,然后输出前台展示。 由于之前没有接触过,一开始比较懵逼,网上通过搜集资料,找到了大家都基本上通过 Grok 进行 日志 的统计分析, Grok 进行 日志 处理的好处有:1:默认集成了多中正则表达式;2:支持自定义的正则表达式。 1、正则表达式库 Grok 内置了许多的正则表达式库,便于我们直接 使用 开发(github搜索 grok ,项目一般都有这个patte
因为是maven项目,所以可以直接在pom中添加依赖,这样包就自己下载下来了: &amp;amp;lt;dependency&amp;amp;gt; &amp;amp;lt;groupId&amp;amp;gt;io.krakens&amp;amp;lt;/groupId&amp;amp;gt; &amp;amp;lt;artifactId&amp;amp;gt; java - grok &amp;amp
<!-- https://mvnrepository.com/artifact/io.thekraken/ grok --> <dependency> <groupId>io.krakens</groupId> <artifactId> java - grok </artifactId> <version>0.1.9</version> </depend Free Grok 是用 Java 编写的快速且可用的源代码搜索和交叉引用引擎。 它可以帮助您搜索,交叉引用和导航您的源代码树。 它可以理解许多源代码管理系统的各种程序 文件 格式和版本控制历史。 该项目的官方页面位于: 最新的 Java (至少1.8) 像Tomcat(8.x或更高版本)这样的Servlet容器,支持Servlet 2.5和JSP 旺盛的标签或通用标签 源代码管理安装,取决于建立索引的存储库的类型 如果要构建Free Grok : 蚂蚁(1.9.4及更高版本) JFlex Netbeans(可选,至少为8.2,将需要Ant 1.9.4) Free Grok 通常在servlet容器(例如Tomcat)中运行。 SRC_ROOT环境变量引用包含您的源树的目录。 Free Grok 分析源代码树,并建立搜索索引以及源 文件 的交叉引用超文本版本。 这些生成的数据 文件 将存储在环 Java 使用 的正则引擎是NFA(非确定型有限状态自动机)。 一个状态可以通过标记了字符或ε的多条边跳转到另一个状态。字符或ε 分别表示读入一个字符或不读入字符可以跳转到另一个状态上,比如遇到表达式的右括号和回溯。NFA的特点是匹配过程面临很多的岔路去做出选择,一旦某条岔路失败,就需要回溯,类似于深度优先搜索。不过并不一定完全遍历,完成匹配之后就停止搜索了。 比如(a|b)*abb
如果没有 日志 解析 ,搜索和可视化 日志 几乎是不可能的,一个被低估的技能记录器需要读取他们的数据。 解析 结构化你的传入(非结构化) 日志 ,以便用户可以在调查期间或设置仪表板时搜索清晰的字段和值。 最流行的 日志 解析 语言是 Grok 。 你可以 使用 Grok 插件在各种 日志 管理和分析工具比如 Elastic Stack 中 解析 日志 数据。在这里查看我之前的的 Grok 教程。 但是用 Grok 解析 日志 可能会很棘手。 本博客将研究一些 Grok 模式示例,这些示例可以帮助您了解如何 解析 日志 数据。 开始 使用 Gr.
- `input` 部分 使用 `file` 插件,用于从指定目录下收集 日志 文件 。`path` 参数指定了 日志 文件 所在的路径,`start_position` 参数设置为 `beginning`,表示从 文件 开头开始读取。如果设置为 `end`,则表示从 文件 末尾开始读取。 - `filter` 部分用于对收集到的 日志 进行过滤和处理。例如,可以 使用 ` grok ` 插件对 日志 进行 解析 使用 `mutate` 插件进行字段操作等。 - `output` 部分用于将处理后的 日志 输出到指定的目的地。例如,可以将 日志 输出到 Elasticsearch 中,或者 使用 `stdout` 插件将 日志 输出到控制台。
 
推荐文章