实验结构
filebeat –> logstash –> elasticsearch –> kibana
说明:
ELK是实时日志处理领域的第一开源选择,基于实时全文索引,统一的配置语言,支持集群线性扩展,这次实验设计的各种软件均属于ELK的套件工具。
filebeat 是一个轻量的日志采集器,安装在各应用服务器,其实logstash也可以实现此功能不过过于笨重,其监控所定义的日志文件,然后根据配置统一输出到logstash,当然也可直接输出到elasticsearch或redis,但是filebeat只支持多行合并和简单过滤控制,我们需要logstash更高级的日志处理功能;
logstash 是一个丰富的日志收集和处理工具,这里我们主要用来监听日志管道,并对日志进行清洗处理成我们想要的json数据,输出保存到elasticsearch 索引库;
elasticsearch 是一个强大的java分布式开源搜索引擎,它基于lucene实现索引和搜索的功能,使用RESTful API处理所有请求,这里我们主要用于日志数据存储和检索查询;
kibana 是一个针对elasticsearch的web工具,基于nodejs开发,这里我们用于web查询和统计界面定制;
一、系统环境
服务器系统统一都是 CentOS6.6,日志采集的 应用服务器 如下,安装 filebeat-5.2.1 并分别定义不同的采集策略。
PHP server 192.168.100.191
:采集PHP-fpm的异常日志
:采集PHP-slow的慢速日志
mysql server 192.168.100.195
:采集mysql-slow的慢速日志
日志服务器 只部署了一台,安装 logstash/elasticsearch/kibana在一起,不过都是可分开,且前两者可集群部署。
logs server 192.168.100.120
:logstash-5.2.1 监听TCP-5044端口,用于收集filebeat发送过来的日志
:elasticsearch-5.2.1 监听TCP-9200端口,用于存储 logstash 输出的日志数据
:kibana-5.2.1 监听TCP-5601端口,用于日志web数据查询
二、安装
在应用服务器上安装 filebeat 采集器
使用rpm安装包
# rpm -ivh filebeat-5.2.1-x86_64.rpm
基本配置文件路径
# vim /etc/filebeat/filebeat.yml
启动和停止filebeat的方法
# /etc/init.d/filebeat start
最后一次日志采集的定位,这个文件别修改了
# ls -l /var/lib/filebeat/registry
采集操作日志
# ls -l /log/log/filebeat/filebeat
在日志服务器上安装 elasticsearch
elasticsearch需要java运行环境支持
# yum install java-1.8.0-openjdk
# rpm -ivh elasticsearch-5.2.1.rpm
默认的安装路径
# ls -l /usr/share/elasticsearch
默认配置目录和文件
# ls -l /etc/elasticsearch/elasticsearch.yml
在配置文件中指定的数据目录和日志目录
# ls -l /data/elasticsearch
默认启动和停止elasticsearch的方法
# /etc/init.d/elasticsearch start
在安装中遇到的一个问题,其他的 sysctl 参数问题可以 google下
报错:
ERROR: bootstrap checks failed
system call filters failed to install; check the logs and fix your configuration or disable system call filters at your own risk
原因:
这是在因为Centos6不支持SecComp,而ES5.2.0默认bootstrap.system_call_filter为true进行检测,所以导致检测失败,失败后直接导致ES不能启动。
解决:
在elasticsearch.yml中配置bootstrap.system_call_filter为false,注意要在Memory下面:
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
在日志服务器上安装 logstash
logstash需要 java的运行环境# rpm -ivh logstash-5.2.1.rpm默认的安装路径# ls -l /usr/share/logstash默认的配置路径,指定配置文件目录、日志目录# more /etc/logstash/logstash.ymlpath.data: /var/lib/logstashpath.config: /etc/logstash/conf.dpath.logs: /var/log/logstash作为filebeat接收器的配置文件,实验中很重的一个规则配置文件# ls -l /etc/logstash/conf.d/filebeat.conf默认启动和停止logstash的方法# initctl start logstash
在日志服务器上安装 kibana
通过源码方式下载和安装kibana5# tar zxvf kibana-5.2.1-linux-x86_64.tar.gz# mv kibana-5.2.1-linux-x86_64 /usr/local/# ln -s /usr/local/kibana-5.2.1-linux-x86_64 /usr/local/kibana基本配置文件,主要是设定端口和elasticsearch的连接参数# more /usr/local/kibana/config/kibana.ymlserver.port: 5601server.host: “192.168.100.120”elasticsearch.url: “http://192.168.100.120:9200”这里通过nohup启动kibana后台运行,源码包里自带nodejs运行环境,可以通过nohup.out观察输出# nohup /usr/local/kibana/bin/kibana &
web浏览:http://192.168.100.120:5601
三、配置
1、在应用服务器上的 filebeat 配置
采集 mysql-slow 日志:/etc/filebeat/filebeat.yml
filebeat:prospectors:–#设置输入的类型为日志文件,以及日志路径input_type: logdocument_type: “mysql-slow”paths:– /data/app/mysql/data/test08-slow.log#设置多行合并匹配规则,反向匹配,匹配行首不是# User@host 或者# Time:的行合并,根据slow日志的格式来调整吧multiline.pattern: ‘^[#][ ][User@Host:]i|[#][ ][Time:]’#multiline.pattern: ‘[#][ ][Time:]’multiline.negate: truemultiline.match: after#过滤设置,黑名单。包含“Time:”的行,这个过滤是为了把不符合规则的日志清洗,但它只能对合并之后的数据进行exclude_lines: [“Time:”]output:# 输出到 logstash,指定后端的连接参数,和logstash的设置匹配logstash:hosts: [“192.168.100.120:5044”]logging:level: debug
采集 php的php-fpm和slow日志:/etc/filebeat/filebeat.ym
filebeat:prospectors:#定义第一个输入,针对php-fpm日志–input_type: logdocument_type: “php-fpm”paths:– /data/app/php5.5.20/var/log/php-fpm.log#定义多行匹配规则,这里有3个正向条件(包含Stack strace:的行、包含空格+数字+.的行、包含空格+thrown in的行)multiline.pattern: ‘(Stack\strace:)|(\s[0-9]\.)|(#[0-9]{2}\s)|(\”\”)|(\s\sthrown\sin)’multiline.negate: falsemultiline.match: after#过滤设置,白名单。包含WARNING的汗include_lines: [“WARNING”]#定义第二个输入,针对slow日志,因为每个pool是单独的slow日志,所以通配符多个日志–input_type: logdocument_type: “php-slow”paths:– /data/app/php5.5.20/var/log/*.log.slow#定义多行匹配规则,反向匹配,把[数字]的行向上合并multiline.pattern: ‘[\[][0-9]{2}’multiline.negate: truemultiline.match: afteroutput:logstash:hosts: [“192.168.100.120:5044”]logging:level: debug
2、在日志服务器上 elasticsearch 的配置
单节点基础配置,如果配置集群请参考其他文档
root# more /etc/elasticsearch/elasticsearch.yml
#定义es集群名称
cluster.name: bosheng_logs
#定义该节点的名称,各个节点不能重复
node.name: node1
#配置数据目录,注意elasticsearch会有自己的运行用户,要赋予目录此用户的权限
path.data: /data/elasticsearch/data
#配置日志目录
path.logs: /data/elasticsearch/logs
#关闭锁定内存
bootstrap.memory_lock: false
bootstrap.system_call_filter: false
#指定本机IP地址
network.host: 192.168.100.120
#指定http访问端口
http.port: 9200
3、在日志服务器上配置 logstach
主要是filebeat.conf 的配置,因为涉及到日志的收集和清洗,这是最主要的配置,包括对各种应用日志的规则匹配后输出指定变量的json数据给elasticsearch
值得注意的是,logstash的启动很慢(相当的慢,几分钟你不要吃惊),在调试grok规则语法的时候不是很方便,可以使用在线调试器先测试通过
https://grokdebug.herokuapp.com/
#定义logstash的一个输入源,这里定义的是beats,以及监听的端口,用来接收filebeat传输过来的数据input {beats {port => “5044”}}filter {#对于type是php-fpm(和filebeat的document_type设置匹配)的日志用此规则处理if[type] == “php-fpm” {grok {match => [#和下面的比对,会发现这个正则匹配规则的写法有点特殊,这是一种多条件匹配的格式,如果日志存在多种格式的话“message”, “(?m)^\[%{MONTHDAY}-%{MONTH}-%{YEAR}\s%{TIME}\]\s(%{WORD:level})\:\s\[(%{WORD})\s(%{WORD:poolname})\]\s(child)\s%{NONNEGINT}\s(said\sinto\sstderr:\s)%{DATA:info}(?:\n%{GREEDYDATA})?$”,“message”, “^\[%{MONTHDAY}-%{MONTH}-%{YEAR}\s%{TIME}\]\s(%{WORD:level})\:\s\[(%{WORD})\s(%{DATA:poolname})\]\s(child)\s%{NONNEGINT},\s%{DATA:info}(\s\(%{NONNEGINT}%{DATA})$”,“message”, “^\[%{MONTHDAY}-%{MONTH}-%{YEAR}\s%{TIME}\]\s(%{WORD:level})\:\s\[(%{WORD})\s(%{DATA:poolname})\]\s(child)\s%{NONNEGINT}\s%{DATA:info}$”]}}#对于type是php-slow(和filebeat的document_type设置匹配)的日志用此规则处理if[type] == “php-slow” {grok {match => [“message”, “(?m)^\[%{MONTHDAY}-%{MONTH}-%{YEAR}\s%{TIME}\]\s\s\[(pool)\s(%{DATA:poolname})\]\s(pid\s%{NONNEGINT})\n%{DATA:filename}\n%{GREEDYDATA}$”]}}#对于type是mysql-slow(和filebeat的document_type设置匹配)的日志用此规则处理if[type] == “mysql-slow” {grok {match => [“message”, “(?m)^#\s+User@Host:\s+%{USER:user}\[[^\]]+\]\s+@\s+\[(?:%{IP:clientip})?\]\n#\s+Query_time:\s+%{NUMBER:query_time:float}\s+Lock_time:\s+%{NUMBER:lock_time:float}\s+Rows_sent:\s+%{NUMBER:rows_sent:int}\s+Rows_examined:\s+%{NUMBER:rows_examined:int}(?:\n+use\s+%{USER};)?\nSET\s+timestamp=%{NUMBER:timestamp};\n\s*(?<query>(?<action>\w+)\b.*)\s*(?:\n#\s+Time)?.*$”]}}}#为每一种不同type设置的日志配置不同的索引集,并传递document_typeoutput {if[type] == “php-fpm” {elasticsearch {hosts => [“192.168.100.120:9200”]index => “php-%{+YYYY.MM.dd}”document_type => “%{[@metadata][type]}”}}if[type] == “php-slow” {elasticsearch {hosts => [“192.168.100.120:9200”]index => “phpslow-%{+YYYY.MM.dd}”document_type => “%{[@metadata][type]}”}}if[type] == “mysql-slow” {elasticsearch {hosts => [“192.168.100.120:9200”]index => “mysql-%{+YYYY.MM.dd}”document_type => “%{[@metadata][type]}”}}}
logstash提供了一个默认正则变量定义文件,包括%{USER}、%{IP}、%{NUMBER} 、%{DATA}等,路径如下,同目录下也可以看到其他的一些默认规则定义
/usr/share/logstash/vendor/bundle/jruby/1.9/gems/logstash-patterns-core-4.0.2/patterns/grok-patterns
在上面我们所用到的logstash配置中,涉及到的一些正则匹配规则如下,可以作为参考,毕竟要更具自己的日志格式进行调整
(?m)打开多行模式的开关^#以 # 字符顶头\s+匹配一个或多个空字符\s*0个或多个空字符%{USER:user}以 USER 模式进行正则匹配,结果放在user中\[[^\]]+\]以 [ 开头 以]结尾,内容是由一个或多个不是 ] 的字符填充而成\[(?:%{IP:clientip})?\]以 [ 开头 以]结尾,内容可能有,也可能无,如果有并且匹配 IP 的正则模式,结果放在clientip中%{NUMBER:id:int}以 NUMBER 模式进行正则匹配,为整数型,结果放在id中\n配换行符%{NUMBER:query_time:float}以 NUMBER 模式进行正则匹配,为浮点型,结果放在query_time中(?:use\s+%{USER:usedatabase};\s*\n)?这个匹配可能有,也可能无,如果有,就是以use开头,若干空字符,以 USER 模式进行正则匹配,结果放在usedatabase中,然后紧接着 ; ,后面是0个或多个空字符,然后是换行,注意:如果有是整体有,如果无,是整体无\b代表字单词边界不占位置,只用来指示位置.*尽可能多的任意匹配(?<query>(?<action>\w+)\b.*)整体匹配,存到query中,以一个或多个字符开头组成的单词,结果存到action中(?:\n#\s+Time)?内容可能有,也可能无,如果有,是接在一个换行之后,以 # 开头,隔着一个或多个空字符,然后是Time.*$任意匹配直到结尾
四、一些基本的调试方法
查看目前的索引库
http://192.168.100.120:9200/_cat/indices?v
通过 RESTful 查询索引库
http://192.168.100.120:9200/mysql-*/_search
通过RESTful删除一个elasticsearch的索引库
curl -XDELETE http://127.0.0.1:9200/phpslow-2015.06.0*
使用kibana查询,通过浏览器访问
http://192.168.100.120:5601