由于公司开发部门调整,接手了原来其他部门的系统开发的工作,大大小小系统4/5个,独立部署的应用十几个。 面对突然增加的应用数量,每天业务反馈的系统问题让我的团队应接不暇,每天查看日志就得从几台服务器上面拉十几份日志文件。 面对这样的情况,迫切需要将日志监控自动化。
目前网上常讨论的一些方式 * 代码中埋点或者自己写脚本 * 商业收费产品:日志易... * 开源类 zabbix、ELK、flume+mq...
根据团队自身情况对实现方式有几个要求: * 非侵入。因为系统接手维护,原来的开发人员大都已经离职,修改代码的风险太大,而且时间上也不允许我投入资源去修改系统。 * 免费。仅仅是团队自己的一个需求,并未达到公司层面,不方便申请费用。 * 轻量。系统的用户量都不大,多数为公司内部管理系统,没有多余的服务器资源可以调用。 * 简单。团队技术能力较弱,需要简单配置即可使用。
总之就是,能够实现最简单的自动化监控,使我们能够主动解决系统异常而不是等待业务部门反馈。 所以最终选择ELK,并且只用到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 ../conf/sample.conf
` * 测试一把 启动成功后,在文件中添加一行数据,此时可以在控制台看到你所添加的内容输出。
{ "message" => "添加了一行日志", "@version" => "1", "@timestamp" => "2016-06-19T15:25:17.786Z", "path" => "D://tmp//test.log", "host" => "z201510f-PC" } ``
我们的日志输出是这样的:
` 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提供了很多) ``
LOG4J_DATESTAMP 20%{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:?%{MINUTE}(?::?%{SECOND})
LOG4J_THREAD [.*]
LOG4J_CLASS [%{JAVACLASS}]
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等各种目标)
` { "@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" ] }`