ELK日志收集系统搭建
架构图
ELK 架构图:其中es 是集群,logstash 是单节点(猜想除非使用nginx对log4j的网络输出分发),kibana是单机(用不着做成集群)。
1.拓扑图
2.logstash 收集日志示意图。
3.带有redis的流程图。
ELK部署
1.三种组件下载地址:https://www.elastic.co/downloads
当然所有的资料都已经有中文翻译,去这里吧。
http://kibana.logstash.es/content/kibana/v3/configuration.html
作用概览:
es存储数据,提供查询数据源。
logstash 收集数据,格式化并传输到es。当然一般会使用redis作为中转队列以增强传输的 可靠性。
kibana 提供优雅的查询界面,对es数据定制化查询,功能十分强劲。
2.elasticsearch安装
ES安装
(1)解压elasticsearch-2.3.1.tar.gz,sudo tar -zvxf elasticsearch-2.3.1.tar.gz,在当前路径生成目录:elasticsearch-2.3.1;为该目录做一个软连接ln -s elasticsearch-1.0.1 elasticsearch。完成之后,目录结构如下图:
(2)配置es。这里只做最简单的配置,修改ES_HOME/config/elasticsearch.yml文件,将node.name的值设置为“test-node1”,表示当前这个es服务节点名字为test-node1,修改http.port:9200,修改cluster.name: my-application。
(3)启动ES。进入ES安装目录,执行命令:bin/elasticsearch -d -Xms512m -Xmx512m,然后在浏览器输入http://ip:9200/,查看页面信息,是否正常启动。status=200表示正常启动了,还有一些es的版本信息,name为配置文件中node.name的值。
因为要做集群嘛:另一台机器上也默认相同配置即可,es会根据cluster.name 寻找自己的伙伴。
插件head安装方法1:
1.elasticsearch/bin/plugin -install mobz/elasticsearch-head
2.运行es
3.打开http://localhost:9200/_plugin/head/
插件安装方法2:
1.https://github.com/mobz/elasticsearch-head下载zip 解压
2.建立elasticsearch-1.0.0\plugins\head\_site文件
3.将解压后的elasticsearch-head-master文件夹下的文件copy到_site
4.运行es
5.打开http://localhost:9200/_plugin/head/
插件kopf安装:
bin/plugin --install lmenezes/elasticsearch-kopf
http://localhost:9200/_plugin/kopf
3.logstash安装
先看启动命令。
./bin/logstash -f config/to_es.conf --log log/logstash.log
当然你需要长期运行后台启动的话 使用nohup命令吧
nohup ./bin/logstash agent -f config/ftoredis.conf --log og &
所以,先解压吧,进入LS_home目录。你需要指定启动时的配置文件,log文件。当然配置文件是需要自己建立的,log会自动生成,不过推荐先建立起来(先计划后行动)。
你需要在.conf文件中加入如下结构的内容:
input {
}
filter{
}
output{
}
当然你也可以参考我的,再具体点的你就去官网看吧。
#file —>redis 这是从磁盘收集日志并传输到redis的配置。 /config/to_redis.conf
# structure of this file
# Set: https://www.elastic.co/guide/en/logstash/current/configuration-file-structure.html
input {
# For detail config for log4j as input,
# See: https://www.elastic.co/guide/en/logstash/current/plugins-inputs-log4j.html
#log4j {
# mode => "server"
# host => "127.0.0.1"
# port => 4567
#}
stdin{}
file {
type => "tomcat_access"
path => ["/Users/xxx/Desktop/access3.log"]
start_position => "beginning"
# discover_interval => "2"
}
}
filter {
grok {
match => [ "message","\[%{HTTPDATE:timestamp}\] %{IPORHOST:clientip} (?:%{NUMBER:bytes}|-) \"(?:%{WORD:verb} %{NOTSPACE:request}(?: HTTP/%{NUMBER:httpversion})?|-)\" %{NUMBER:response} (%{WORD:session_id}|-) %{USER-INT:thread} %{INT:responsetime}" ]
}
date {
match => [ "timestamp" , "dd/MMM/yyyy:HH:mm:ss Z" ]
}
kv {
source => "request"
field_split => "&?"
value_split => "="
}
urldecode {
all_fields => true
}
#如果插件不能满足要求,那就自己写ruby表达式,当然这里任性换行即可
ruby{
code => "while event['uripath'] =~ /\/\d*\//
event['uripath'] = event['uripath'].gsub(/\/\d*\//, '/*/')
end"
}
#Only matched data are send to output.
}
output{
# For detail config for elasticsearch as output,
# See: https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html
# elasticsearch {
# action => "index" #The operation on ES
# hosts => "127.0.0.1:9200" #ElasticSearch host, can be array.
# index => "ft" #The index to write data to, can be any string.
# }
stdout{
codec => rubydebug
}
redis{
host => "10.8.1.121"
port => 6379
data_type =>"list"
key => "tomcat_access"
}
}
与上面相对应,这是从redis读取key值key保持一致,传输到es的配置。
#redis -> es 从redis读取输出到es中。 /config/to_es.conf
#l structure of this file
# Set: https://www.elastic.co/guide/en/logstash/current/configuration-file-structure.html
input {
redis {
host => "10.8.1.121"
port => "6379"
type => "tomcat_access_redis"
data_type => "list"
key => "tomcat_access"
}
}
filter {
#Only matched data are send to output.
}
output {
# For detail config for elasticsearch as output,
# See: https://www.elastic.co/guide/en/logstash/current/plugins-outputs-elasticsearch.html
elasticsearch {
action => "index" #The operation on ES
hosts => "127.0.0.1:9200" #ElasticSearch host, can be array.
index => "ft3" #The index to write data to, can be any string.
特别声明:logstash对es的映射mapping默认在logstash-*才使用,而其他的不会使用映射,这可能会给kibana分析带来困难。
那么直接上传新的template到ES:
cp vendor/bundle/jruby/1.9/gems/logstash-output-elasticsearch-2.5.5-java/lib/logstash/outputs/elasticsearch/elasticsearch-template.json ./uc_template.json
这个文件然后修改。”template“:“yourindex*” 如 “template”:“ft*”
curl -XPUT http://192.168.0.66:9200//_template/template_oa_uc -d ‘@/home/logstash/logstash-2.3.1/config/uc_template.json'
当然此时你需要在配置中指定一个template的名字:
template_name => "template_oa_uc" #注意这个名字是用来查找映射配置的,尽量设置成全局唯一的
}
stdout{}
}
特别注意:因为es查询会涉及到分词,如形如/api/oms/queryEmployee/usercode 之类的链接在统计的时候将会被拆分为api oms queryEmployee...等独立统计,如果需要raw字段进行统计会造成不方便。在index不是logstash-*的时候需要自己指定raw的映射文件。当然,logstash默认在index =>logstash-* 的时候将会保留.raw字段。
另外:
1.logstash 默认使用sincedb.*保存读取文件的行数,$HOME/.sincedb* 。
2.如果删除这个文件重新读取的话这里可能会有个坑,就是不指定es的documentid,在设置为start_position=beginning的时候,会造成数据重复读取,正确做法是指定output的documentid.
当然,你也可以直接删掉es的数据。
上面的配置中保留了log4j传输相关的配置,如果不适用file的形式,直接使用log4j传输也可以,只需要将to_redis.conf 配置中的input改掉,注释掉grok中的匹配。对于log4j更具体的配置,请参考 https://www.elastic.co/guide/en/logstash/current/plugins-inputs-log4j.html
4.kibana安装
解压,进入config目录,找到 config/kibana.yml 有下面几行你就足够面对基本的挑战了。
# Kibana is served by a back end server. This controls which port to use.
server.port: 5601
# The host to bind the server to.
server.host: "127.0.0.1"
# If you are running kibana behind a proxy, and want to mount it at a path,
# specify that path here. The basePath can't end in a slash.
# server.basePath: ""
# The maximum payload size in bytes on incoming server requests.
# server.maxPayloadBytes: 1048576
# The Elasticsearch instance to use for all your queries.
elasticsearch.url: "http://localhost:9200"
# preserve_elasticsearch_host true will send the hostname specified in `elasticsearch`. If you set it to false,
# then the host you use to connect to *this* Kibana instance will be sent.
# elasticsearch.preserveHost: true
# Kibana uses an index in Elasticsearch to store saved searches, visualizations
# and dashboards. It will create a new index if it doesn't already exist.
kibana.index: ".kibana"
启动很简单:
进入bin目录 ,然后 ./kibana >log &
注意后台启动后ps -ef|grep kibana 是找不到进程信息的。启动过程中console会输出pid,记住pid即可,当然这是开玩笑.
如果要停掉怎么办呢,那就根据端口号去找吧,linux下的命令是
fuser -n tcp 5601 —-5601 是你配置文件kibana.yml 中的server.port。
或者 lsof -i:5601 或者 lsof -i tcp:5084 反正很多啦,随便用。找到pid kill掉。
访问:http://127.0.0.1:5601 即可。
小坑:对于redis
因file—>redis_cluster is ok, redis_cluster—>es is fail,oh my god,what did the author think when it created logstash。好吧,只能妥协了,采用单机跑redis。目前并不知道作者下个版本是否会对 redis_cluster -> logstash -> es 会做出支持。
事实上,redis只是作为中转站,并不会被无限制的写入内存撑爆了,r->e 挂掉了另说。但是这不影响,因为redis write oom了,read是可以的,logstash会停止write,直到 redis能重新write。
错误排查以及解决:
错误排查以及总结:
(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk.
今天运行Redis时发生错误,错误信息如下:
(error) MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
Redis被配置为保存数据库快照,但它目前不能持久化到硬盘。用来修改集合数据的命令不能用。请查看Redis日志的详细错误信息。
原因:
强制关闭Redis快照导致不能持久化。
解决方案:
运行config set stop-writes-on-bgsave-error no 命令后,关闭配置项stop-writes-on-bgsave-error解决该问题。
root@ubuntu:/usr/local/redis/bin# ./redis-cli
127.0.0.1:6379> config set stop-writes-on-bgsave-error no
OK
127.0.0.1:6379> lpush myColour "red"
(integer) 1