使用Logstash搭建基于日志文件的预警机制
时间:2016-06-21 02:07 来源:未知 作者:IT
摘要
本文将会描述如何在复杂的系统环境下,快速使用Logstash搭建基于日志文件的系统预警机制
背景
由于公司开发部门调整,接手了原来其他部门的系统开发的工作,大大小小系统4/5个,独立部署的应用十几个。 面对突然增加的应用数量,每天业务反馈的系统问题让我的团队应接不暇,每天查看日志就得从几台服务器上面拉十几份日志文件。 面对这样的情况,迫切需要将日志监控自动化。
框架选型
目前网上常讨论的一些方式
代码中埋点或者自己写脚本
商业收费产品:日志易...
开源类 zabbix、ELK、flume+mq...
根据团队自身情况对实现方式有几个要求:
非侵入。因为系统接手维护,原来的开发人员大都已经离职,修改代码的风险太大,而且时间上也不允许我投入资源去修改系统。
免费。仅仅是团队自己的一个需求,并未达到公司层面,不方便申请费用。
轻量。系统的用户量都不大,多数为公司内部管理系统,没有多余的服务器资源可以调用。
简单。团队技术能力较弱,需要简单配置即可使用。
总之就是,能够实现最简单的自动化监控,使我们能够主动解决系统异常而不是等待业务部门反馈。 所以最终选择ELK,并且只用到Logstash。
开始配置
1、目的描述
识别实现指定日志文件中的错误信息
统计错误数量
通过IM进行预警
2、Logstash安装、配置
本文在win7、jdk7下进行配置 下载Logstash官网提供的最新版本 wget https://download.elastic.co/logstash/logstash/logstash-2.3.2.zip 解压到D:\tmp\logstash-2.3.2 我创建了logs和conf两个文件夹,用来存放配置和启动日志。最终结果如下 输入图片说明
第一步:创建一个简单配置
input {
# 以日志文件作为来源
file {
# 文件路径
path => "D:\tmp\test.log"
}
}
filter {}
output {
# 输出到console
stdout {
codec => rubydebug
}
}
启动logstash
D:\tmp\logstash-2.3.2\bin>logstash.bat -f ..\conf\sample.conf
测试一把 启动成功后,在文件中添加一行数据,此时可以在控制台看到你所添加的内容输出。
{
"message" => "添加了一行日志",
"@version" => "1",
"@timestamp" => "2016-06-19T15:25:17.786Z",
"path" => "D:\\tmp\\test.log",
"host" => "z201510f-PC"
}
3、日志分析
我们的日志输出是这样的:
2016-06-19 13:54:52,476 [pool-128-thread-1] [com.zf.sys.Test] [WARN] - 这里有异常
首先要将日志格式化,这里需要使用Logstash filter中基于正则的插件gork。(更多详情见https://www.elastic.co/guide)
自定义能够匹配上述日志内容的正则(虽然logstash提供了很多)
#2016-06-19 13:54:52,476 [pool-128-thread-1] [com.zf.sys.Test] [WARN] - 这里有异常
# yyyy-MM-dd HH:mm:ss,SSS eg: 2014-01-09 17:32:25,527
LOG4J_DATESTAMP 20%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:?%{MINUTE}(?::?%{SECOND})
# [pool-128-thread-1]
LOG4J_THREAD \[.*\]
# [com.zf.sys.Test]
LOG4J_CLASS \[%{JAVACLASS}\]
# [WARN]
LOG4J_LEVEL \[%{WORD}\]
# 这里有异常
LOG4J_MSG (.*)
在gork中引用自定义的正则
filter {
# 正则解析
grok {
# 增加自定义的正则,这里我把自定义的正则文件,加在了这个目录下
patterns_dir => "D:\tmp\logstash-2.3.2\vendor\bundle\jruby\1.9\gems\logstash-patterns-core-2.0.5\patterns"
# 从message字段中解析出 datetime thread classname level msg
match => ["message", "%{LOG4J_DATESTAMP:datetime} %{LOG4J_THREAD:thread} %{LOG4J_CLASS:classname} %{LOG4J_LEVEL:level} - %{LOG4J_MSG:msg}"]
# 删除原来的message字段
remove_field => [ "message" ]
# 增加WARN,作为标记
add_tag => "warn"
}
}
测试正则是否生效 好了,都写好了,再试一把是否生效。增加一条日志,正确解析则会输出:
{
"@version" => "1",
"@timestamp" => "2016-06-19T15:36:07.104Z",
"path" => "D:\\tmp\\test.log",
"host" => "z201510f-PC",
"datetime" => "2016-06-19 13:54:52,476",
"thread" => "[pool-128-thread-1]",
"classname" => "[com.zf.sys.Test]",
"level" => "[WARN]",
"msg" => "这里有异常",
"tags" => [
[0] "warn"
]
}
为匹配到的内容创建一个对应属性,最终结果就是一个json格式。(可以通过上面的output配置将此内容输出到redis、kafka、http等各种目标)
4、预警规则
上面已经完成了目标日志的解析,我需要的是,当日志5分钟中出现WARN级别的异常信息超过三条,能够自动预警。 完成这样的预警规则,需要使用两个filter插件:metrics、ruby
# 计数
metrics {
# 每301秒清空计数器
clear_interval =>301
# 每隔300秒统计一次
flush_interval =>300
# 计数器数据保存的字段名 level的值就是上面解析出来的
meter => "events_%{[level]}"
# 增加"metric",作为标记
add_tag => "metric"
# 3秒内的message数据才统计,避免延迟
# ignore_older_than => 3
}
# 如果event中标记为“metric”的
if "metric" in [tags] {
# 执行ruby代码
ruby {
# 如果level为warn的数量小于3条,就忽略此事件(即不发送任何消息)。
code => "event.cancel if event['events_[WARN]']['count'] < 3"
}
}
完成以上配置后,可以在test.log中连续添加3行以上日志,如果输出如下内容则表示成功。
{
"@version" => "1",
"@timestamp" => "2016-06-19T15:42:39.023Z",
"message" => "z201510f-PC",
"events_" => {
"WARN" => {
"count" => 3,
"rate_1m" => 0.0,
"rate_5m" => 0.0,
"rate_15m" => 0.0
}
},
"tags" => [
[0] "metric"
]
}
5、配置提醒
提醒是通过output实现的,即对以上处理的结果进行输出。前面用到的都是控制台输出,在实际情况中我需要通过公司微信企业号进行通知,所以我需要做一些处理。
output {
# 如果event中标记为“metric”,表示只发送计数的消息。
if "metric" in[tags]{
# 通过http请求公众号发送微信消息。(此处简略描述)
http {
url ==> "http:xxxx/xxx.do?data=配置时间内WARN异常数量:%{[events_[WARN]][count]}"
}
}
}
总结
日志监控实现不容易,尤其是大公司那种规模。通过logstash这个工具,能够快速的搭建出一套自动化的日志监控,对于小规模的系统来说,真是够爽的。
(责任编辑:IT)
摘要 本文将会描述如何在复杂的系统环境下,快速使用Logstash搭建基于日志文件的系统预警机制 背景 由于公司开发部门调整,接手了原来其他部门的系统开发的工作,大大小小系统4/5个,独立部署的应用十几个。 面对突然增加的应用数量,每天业务反馈的系统问题让我的团队应接不暇,每天查看日志就得从几台服务器上面拉十几份日志文件。 面对这样的情况,迫切需要将日志监控自动化。 框架选型 目前网上常讨论的一些方式 代码中埋点或者自己写脚本 商业收费产品:日志易... 开源类 zabbix、ELK、flume+mq... 根据团队自身情况对实现方式有几个要求: 非侵入。因为系统接手维护,原来的开发人员大都已经离职,修改代码的风险太大,而且时间上也不允许我投入资源去修改系统。 免费。仅仅是团队自己的一个需求,并未达到公司层面,不方便申请费用。 轻量。系统的用户量都不大,多数为公司内部管理系统,没有多余的服务器资源可以调用。 简单。团队技术能力较弱,需要简单配置即可使用。 总之就是,能够实现最简单的自动化监控,使我们能够主动解决系统异常而不是等待业务部门反馈。 所以最终选择ELK,并且只用到Logstash。 开始配置 1、目的描述 识别实现指定日志文件中的错误信息 统计错误数量 通过IM进行预警 2、Logstash安装、配置 本文在win7、jdk7下进行配置 下载Logstash官网提供的最新版本 wget https://download.elastic.co/logstash/logstash/logstash-2.3.2.zip 解压到D:\tmp\logstash-2.3.2 我创建了logs和conf两个文件夹,用来存放配置和启动日志。最终结果如下 输入图片说明 第一步:创建一个简单配置 input { # 以日志文件作为来源 file { # 文件路径 path => "D:\tmp\test.log" } } filter {} output { # 输出到console stdout { codec => rubydebug } } 启动logstash D:\tmp\logstash-2.3.2\bin>logstash.bat -f ..\conf\sample.conf 测试一把 启动成功后,在文件中添加一行数据,此时可以在控制台看到你所添加的内容输出。 { "message" => "添加了一行日志", "@version" => "1", "@timestamp" => "2016-06-19T15:25:17.786Z", "path" => "D:\\tmp\\test.log", "host" => "z201510f-PC" } 3、日志分析 我们的日志输出是这样的: 2016-06-19 13:54:52,476 [pool-128-thread-1] [com.zf.sys.Test] [WARN] - 这里有异常 首先要将日志格式化,这里需要使用Logstash filter中基于正则的插件gork。(更多详情见https://www.elastic.co/guide) 自定义能够匹配上述日志内容的正则(虽然logstash提供了很多) #2016-06-19 13:54:52,476 [pool-128-thread-1] [com.zf.sys.Test] [WARN] - 这里有异常 # yyyy-MM-dd HH:mm:ss,SSS eg: 2014-01-09 17:32:25,527 LOG4J_DATESTAMP 20%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:?%{MINUTE}(?::?%{SECOND}) # [pool-128-thread-1] LOG4J_THREAD \[.*\] # [com.zf.sys.Test] LOG4J_CLASS \[%{JAVACLASS}\] # [WARN] LOG4J_LEVEL \[%{WORD}\] # 这里有异常 LOG4J_MSG (.*) 在gork中引用自定义的正则 filter { # 正则解析 grok { # 增加自定义的正则,这里我把自定义的正则文件,加在了这个目录下 patterns_dir => "D:\tmp\logstash-2.3.2\vendor\bundle\jruby\1.9\gems\logstash-patterns-core-2.0.5\patterns" # 从message字段中解析出 datetime thread classname level msg match => ["message", "%{LOG4J_DATESTAMP:datetime} %{LOG4J_THREAD:thread} %{LOG4J_CLASS:classname} %{LOG4J_LEVEL:level} - %{LOG4J_MSG:msg}"] # 删除原来的message字段 remove_field => [ "message" ] # 增加WARN,作为标记 add_tag => "warn" } } 测试正则是否生效 好了,都写好了,再试一把是否生效。增加一条日志,正确解析则会输出: { "@version" => "1", "@timestamp" => "2016-06-19T15:36:07.104Z", "path" => "D:\\tmp\\test.log", "host" => "z201510f-PC", "datetime" => "2016-06-19 13:54:52,476", "thread" => "[pool-128-thread-1]", "classname" => "[com.zf.sys.Test]", "level" => "[WARN]", "msg" => "这里有异常", "tags" => [ [0] "warn" ] } 为匹配到的内容创建一个对应属性,最终结果就是一个json格式。(可以通过上面的output配置将此内容输出到redis、kafka、http等各种目标) 4、预警规则 上面已经完成了目标日志的解析,我需要的是,当日志5分钟中出现WARN级别的异常信息超过三条,能够自动预警。 完成这样的预警规则,需要使用两个filter插件:metrics、ruby # 计数 metrics { # 每301秒清空计数器 clear_interval =>301 # 每隔300秒统计一次 flush_interval =>300 # 计数器数据保存的字段名 level的值就是上面解析出来的 meter => "events_%{[level]}" # 增加"metric",作为标记 add_tag => "metric" # 3秒内的message数据才统计,避免延迟 # ignore_older_than => 3 } # 如果event中标记为“metric”的 if "metric" in [tags] { # 执行ruby代码 ruby { # 如果level为warn的数量小于3条,就忽略此事件(即不发送任何消息)。 code => "event.cancel if event['events_[WARN]']['count'] < 3" } } 完成以上配置后,可以在test.log中连续添加3行以上日志,如果输出如下内容则表示成功。 { "@version" => "1", "@timestamp" => "2016-06-19T15:42:39.023Z", "message" => "z201510f-PC", "events_" => { "WARN" => { "count" => 3, "rate_1m" => 0.0, "rate_5m" => 0.0, "rate_15m" => 0.0 } }, "tags" => [ [0] "metric" ] } 5、配置提醒 提醒是通过output实现的,即对以上处理的结果进行输出。前面用到的都是控制台输出,在实际情况中我需要通过公司微信企业号进行通知,所以我需要做一些处理。 output { # 如果event中标记为“metric”,表示只发送计数的消息。 if "metric" in[tags]{ # 通过http请求公众号发送微信消息。(此处简略描述) http { url ==> "http:xxxx/xxx.do?data=配置时间内WARN异常数量:%{[events_[WARN]][count]}" } } } 总结 日志监控实现不容易,尤其是大公司那种规模。通过logstash这个工具,能够快速的搭建出一套自动化的日志监控,对于小规模的系统来说,真是够爽的。 (责任编辑:IT) |