转载

每日一博 | 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两个文件夹,用来存放配置和启动日志。最终结果如下 每日一博 | Logstash 搭建日志文件预警机制 * 第一步:创建一个简单配置

` input { # 以日志文件作为来源 file { # 文件路径 path => "D:/tmp/test.log" } } filter {} output { # 输出到console stdout { codec => rubydebug } }
* 启动logstash ``

D:/tmp/logstash-2.3.2/bin>logstash.bat ../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这个工具,能够快速的搭建出一套自动化的日志监控,对于小规模的系统来说,真是够爽的。
原文  http://my.oschina.net/u/1983545/blog/694252
正文到此结束
Loading...