有个中文文档介绍的非常好,也比较详细。
ELKstack 中文指南 :http://kibana.logstash.es/
我只是用了部分功能。就是日志分析功能架构如图。
由于我们的系统非常小,日志也比较少。我没做过架构和性能的优化,只是将Elasticsearch参数做了部分优化,以后还需要改进。Elasticsearch同时也做了存储之用。
之前看别人说的日志分析系统很有道理故摘录如下:
##################
初级: syslog基中管理 + 手工编写分析脚本 + CGI输出,适合简单分析,数据量不大的场景
进阶:LogStash,是一个应用程序日志、事件的传输、处理、管理和搜索的平台。你可以用它来统一对应用程序日志进行收集管理,提供 Web 接口用于查询和统计。个人用下来感觉它的全文检索功能最为强大,基本上你可以把它看成是splunk的开源解决方案
更灵活: Flume + Hadoop + Hive,这三个都是属于Apache基金会下的项目,Flume用与收集日志,Hadoop用于分析与存储,Hive用于存放处理后的数据。这个方案是最灵活也是最强大的,不过搭配起来需要花时间,UI要另外编写。
个人推荐LogStash,问题的需求都能满足,而且这是个total solution。
######################
所以我做日志分析的时候也选择了Elasticsearch+Logstash+Kibana
Logstash 日志采集 Elasticsearch 存储和查询 Kibana 展示
Logstash :
我们的jboss 日志格式比较奇特。
2015-07-29 19:53:33,754 INFO [STDOUT] (DubboMonitorSendTimer-thread-1) 2015-07-29 19:53:33,754 INFO : com.alibaba.dubbo.monitor.dubbo.DubboMonitor#send : [DUBBO] Send statistics to monitor zookeeper://zookeeper1.ablejava.com:2181/com.alibaba.dubbo.monitor.MonitorService?anyhost=true&application=simple-monitor&check=false&delay=-1&dubbo=2.5.3&interface=com.alibaba.dubbo.monitor.MonitorService&methods=lookup,collect&pid=65509&revision=2.5.3&side=provider×tamp=1438064637106, dubbo version: 2.5.3, current host: 192.168.9.110
所以 我写了匹配规则:
input {
file {
path => “/usr/local/jboss/server/default/log/server.log”
type => “jboss_131”
}
}
filter {
multiline {
patterns_dir => “/usr/local/rizhi/logstash-1.4.4/patterns”
pattern => “(^%{TOMCAT_DATESTAMP})”
negate => true
what => “previous”
}
grok {
patterns_dir => “/usr/local/rizhi/logstash-1.4.4/patterns”
match => [ “message”, “%{TOMCATLOG}”,”message”, “%{TOMCATLOG2}”, “message”, “%{CATALINALOG}” ]
}
mutate {
replace => [“host”, “10.173.161.131”]
}
date {
match => [ “timestamp”, “yyyy-MM-dd HH:mm:ss,SSS Z”, “MMM dd, yyyy HH:mm:ss a” ]
}
}
output {
elasticsearch { host => ‘10.168.25.125’ protocol => “http”}
}
由于格式不是固定的,所以需要匹配多种格式。以下是格式的定义:
CATALINA_DATESTAMP %{MONTH} %{MONTHDAY}, 20%{YEAR} %{HOUR}:?%{MINUTE}(?::?%{SECOND}) (?:AM|PM)
TOMCAT_DATESTAMP %{YEAR}-%{MONTHNUM}-%{MONTHDAY} %{HOUR}:?%{MINUTE}(?::?%{SECOND})
#TOMCATLOG %{TOMCAT_DATESTAMP:timestamp} %{LOGLEVEL:level} \[%{QS:xs}\]
TOMCATLOG %{TOMCAT_DATESTAMP:timestamp} %{LOGLEVEL:level} \[%{JAVALOGMESSAGE:xs}\] \(%{JAVALOGMESSAGE:thread}\) %{TOMCAT_DATESTAMP:timestamp2} %{LOGLEVEL:level2} : %{JAVALOGMESSAGE:logmessage}
TOMCATLOG2 %{TOMCAT_DATESTAMP:timestamp} %{LOGLEVEL:level} \[%{JAVALOGMESSAGE:xs}\] \(%{JAVALOGMESSAGE:thread}\) %{TOMCAT_DATESTAMP:timestamp2} %{LOGLEVEL:level2}\: %{JAVALOGMESSAGE:logmessage}
CATALINALOG %{TOMCAT_DATESTAMP:timestamp} %{LOGLEVEL:level} %{JAVALOGMESSAGE:logmessage}
THREAD %{USERNAME}-%{USERNAME}-%{INT}
JAVALOGMESSAGE (.*)
nginx的日志的话,更好配置!设置成json格式就能很好的采集。
file {
type => “nginx_253_user”
path => “/usr/local/nginx/logs/access_user.log”
codec => “json”
}
filter {
geoip {
source => “forwardedip”
add_tag => [ “geoip” ]
}
mutate {
replace => [“host”, “10.173.164.253”]
}
}
geoip 是为了获取地理地址所用的参数。
nginx的日志定义:
log_format logbackup ‘{“timestamp”:”$time_iso8601″,’
‘”remoteAddr”:”$remote_addr”,’
‘”forwardedip”:”$http_x_forwarded_for”,’
‘”status”:”$status”,’
‘”hostname”:”$host”,’
# ‘”uri”:”$uri”,’
‘”request”:”$request”,’
‘”requestUri”:”$request_uri”,’
‘”request_time”:$request_time,’
‘”http_referer”:”$http_referer”,’
‘”http_user_agent”:”$http_user_agent”,’
‘”body_bytes_sent”:$body_bytes_sent,’
‘”upstream_http_host”:”$upstream_addr”,’
‘”upstream_response_time”:”$upstream_response_time”}’;
logstat 在设置采集格式的时候很麻烦。所以可以使用调试模式。
[root@base1-livecourse110 logstash-1.4.4]# cat logstash.conf_bak
input {
stdin {
add_field => {“key” => “value”}
codec => “plain”
tags => [“add”]
type => “std”
}
}
filter {
grok {
patterns_dir => “/root/logstash-1.4.4/patterns”
match => [ “message”, “%{TOMCATLOG}” ]
}
}
output {
stdout { codec => rubydebug }
}
这个就是手动输入,界面输出的。只要修改grok的参数就好了。
我在搭建中遇到了 一个报错
waited for 30s and no initial state was set by the discovery logstash
你只要修改格式就好了
output {
#stdout { codec => rubydebug }
if [type] == “netflow” {
elasticsearch {
cluster => “elk-cluster”
index => “netflow-%{+YYYY.MM.dd}”
host => “10.4.0.47”
protocol => “http”
workers => 2
}
}
添加个protocol => “http” 即可
具体的原因可以看指南有说明,是日志的格式的原因。参考:http://kibana.logstash.es/content/logstash/plugins/output/elasticsearch.html
新插件支持三种协议: node,http 和 transport。
还有就是数据类型,很多数据可能需要变成float数据类型。否则无法计算。
filter {
mutate {
split => [ "upstreamtime", "," ]
}
mutate {
convert => [ "upstreamtime", "float" ]
}
}
elasticsearch:
配置很简单,你按照指南即可配置。问题遇到的也比较少。会经常遇到数据类型的问题。
kibana:
配置也很简单,你随便找个文档就可。实际遇到的问题比较多。
Elasticsearch 的外网访问。之前elasticsearch在内网,玩的没问题,后来放到服务器那边一直报错。
Error Could not reach http://121.40.143.26:9200/_aliases. If you are using a proxy, ensure it is configured correctlyCould not reach http://121.40.143.26:9200/_aliases. If you are using a proxy, ensure it is configured correctly其实单独访问有没问题。后来看到文章说打开调试模式可以查原因。
从浏览器中直接访问elasticsearch主机的9200端口,没有问题,表明elasticsearch实际上是开启了端口的。于是问题就锁定到了Kibana 3和elasticsearch 1.5的兼容问题上了。这个时候尝试打开chrome开发者模式的Console窗口,发现了以下的报错:
发现原来访问的是 http://10.168.25.125:9200/logstash-2015.08.12%2Clogstash-2015.08.13%2Clogstash-2015.08.13/_aliases?ignoreUnavailable=true 内网的ip
再去看elasticsearch 的日志。
[2015-08-13 17:06:10,171][INFO ][http ] [S’ym] bound_address {inet[/0.0.0.0:9200]}, publish_address {inet[/10.168.25.125:9200]}
原来如此 把publish_address换成外网即可。vi config/elasticsearch.yml
network.publish_host: 121.40.143.263
测试下来没有问题!bingo,不过kibana的报错实在是太坑。又多get一个调试技能!
还有就是定制的一些功能和介绍。 我发几个文档详细说明了。也算作示例,可以附件观看。
[gview file=”https://www.hmouse.cn/wp-content/uploads/2015/09/日志服务器查询手册.docx”] [gview file=”https://www.hmouse.cn/wp-content/uploads/2015/09/日志系统介绍.pptx”][gview file=https://www.hmouse.cn/wp-content/uploads/2015/09/日志系统.zip]
后续补记:
后来又遇到一个logstat的延迟的问题。发现录入时间远远落后日志的时间。
原因查了半天也没头绪,后来我直接打出到本地的文件。发现还是有类似的问题,那么发现应该是客户端的问题。
对比了另一台发现。另一台的性能更差,为什么另一台不延迟了,这个深深的困扰了我。后来推测可能是另一台用的是SSD硬盘的原因。这样就能解释为什么会有延迟了。
但是还有一个问题困扰我。那就是有问题这台的IO不是很高。虽然不是SSD,但是应该还是能满足需求。推测重启应该能解决问题。但是线上不能重启,所以我通过将进程拆成4个,来解决延迟的问题。(就是启动四个进程去取日志)目前来看还是可以的。以后会继续观察。