Elk 是 ElasticSearch + logstash + kibana 的缩写,是一套集成的开源日志分析平台。作为当前最流行的日志分析平台,有着很多的天然优势。易部署,跨平台,高效的日志解析引擎和搜索引擎,以及非常强大的可视化平台,受到很多运维人员的青睐。
之前一直有做这方面的尝试,比如二进制审计日志分析,常用的 oplog 日志分析等等。但是因为受限于某些原因没能坚持下去。正好这次受到组内有人做的 mongo 数据库监控项目的启发,觉得使用 elk 平台会更加方便,于是重新开始尝试了一下。
以下是 elk 的整体架构, logstash-forword 是日志采集器,负责从各个服务器上采集日志信息,可以是文本或者二进制形式的日志。logstash 负责将采集的日志解析出来,映射成es 的字段名,并存入 es 中,而 Kibana 提供了可视化的分析平台,可以基于es 的数据生成各种报表。
由于整套方案都是基于java的,所以跨平台性很好,无需安装,下载之后即可运行。以下实践结果基于测试环境,es 运行在服务器 127.0.0.1,logstash 和 kibana 运行在服务器 200.200.107.249。使用的版本分别为elasticsearch-2.3 , kibana-4.5.4 , logstash-5.3.2 [ 附官方下载地址 ]。此外要注意 es 和 kibana 的版本保持对应。
kibana 版本 | es 版本 |
---|---|
4.1 | 1.4.4+ |
4.2 | 2.0+ |
4.3 | 2.1+ |
4.4 | 2.2+ |
4.5 | 2.3+ |
4.6 | 2.4+ |
4.7 | 5.0+ |
logstash 可以指定配置文件运行,配置文件中指定了关联的 ES 的地址以及日志解析方式。在 config/ 目录下copy 一份默认的配置文件,命名为 mongo-lostash.conf。 配置文件主要指定三件事:输入—解析—输出。
这里直接指定 mongo 日志的路径, 如果有多种类型的日志,可以指定 type 标志来区分。
input {
file { //当输入源是文件时
path => "/home/moa/db/mongodb/log/mongod.log"
type => "mongolog"
}
}
filter 将 input 的结果进行处理,并转为 es 中对应的字段。以下是对 type 为 mongolog 的日志进行处理。grok 是logstash 内置的正则解析引擎,包含丰富的正则表达式。
那么接下来是对于 mongo 日志的解析。根据 mongo 官网 (日志规范 )对日志的描述,mongo3.0 以上版本的日志格式为:
[]
@timestamp : 时间
@severity : 日志级别,分为: F(Fatal)/E(Error)/W(Warning)/I(Informational)/D(Debug)
@component: 包括 /NETWORK/ACCESS/COMMMAND/GEO/INDEX/QUERY/ROLLBACK/SHARDING/JOURNAL/WRITE 等
@context: 上下文,主要打印数据库连接
@message: 具体的日志数据
其中 compoent = COMMAND 基本涵盖了大部分的增删改查等数据库操作,这一部分的 message 是我们需要具体关注的。以下是部分有代表性的日志
// NETWROK 建立连接的日志
2018-01-02T10:47:02.253+0800 I NETWORK [initandlisten] connection accepted from anonymous unix socket #179873 (349 connections now open)
// ACCESS 接入失败的日志
2016-09-24T02:01:03.404+0800 I ACCESS [conn2232] Failed to authenticate Opt_ALL@admin with mechanism MONGODB-CR: AuthenticationFailed UserNotFound Could not find user Opt_ALL@admin
// COMMAND 日志
2016-08-14T19:08:54.569+0800 I COMMAND [conn4521] insert im.user_msg ninserted:1 keyUpdates:0 writeConflicts:0 numYields:0 locks:{ Global: { acquireCount: { r: 1, w: 1 } }, Database: { acquireCount: { w: 1 } }, Collection: { acquireCount: { w: 1 } } } 492ms
2018-01-03T13:28:17.308+0800 I COMMAND [conn9678] query task.opt_log query: { query: { did: 519390, taskid: 172 }, orderby: { opt_time: -1 } } planSummary: IXSCAN { did: 1.0, taskid: 1.0, opt_time: 1.0 } ntoreturn:3 ntoskip:0 nscanned:2 nscannedObjects:2 keyUpdates:0 writeConflicts:0 numYields:2 nreturned:2 reslen:429 locks:{ Global: { acquireCount: { r: 6 } }, Database: { acquireCount: { r: 3 } }, Collection: { acquireCount: { r: 3 } } } 120ms
2016-08-14T19:09:02.836+0800 I COMMAND [conn4521] remove im.user_msg query: { did: 10000, pid: 8445, msg_id: { $lte: 510 } } ndeleted:100 keyUpdates:0 writeConflicts:0 numYields:1 locks:{ Global: { acquireCount: { r: 2, w: 2 } }, Database: { acquireCount: { w: 2 } }, Collection: { acquireCount: { w: 2 } } } 212ms
以上述 COMMAND 类型的日志为例,其 message 部分又可以拆分出以下的格式
@command_type : 操作类型,比如 query/insert/update/remove/getmore(迭代返回) 等等
@databasename : 操作的数据库,比如 im.user_msg
@command_detail : 会输出具体的 queryplan,如果是全表扫描会出现 COLL_SCAN 之类的关键词
@spend_time : 花费时间,单位是 ms
通过对以上的mongo日志格式分析,我们现在就可以使用grok 解析出这些字段。 grok 内置了大部分的正则表达式,可以直接当做标签使用,比如用于匹配时间的 TIMESTAMP_ISO8601,MONGO3_SEVERITY 等等。每个标签后面可以指定这部分匹配结果的字段名。
先解析整行日志,然后再解析 component=COMMAND 日志的内容,从而得到操作信息和数据库信息等。
filter {
if [type] == "mongolog" {
grok {
match => ["message","%{TIMESTAMP_ISO8601:timestamp}\s+%{MONGO3_SEVERITY:severity}\s+%{MONGO3_COMPONENT:component}\s+(?:\[%{DATA:context}\])?\s+%{GREEDYDATA:body}"]
}
if [component] =~ "COMMAND" {
grok {
match => ["body","%{WORD:command_type}\s+%{DATA:db_name}\s+\w+\:\s+%{GREEDYDATA:command}\s+%{INT:spend_time}ms$"]
}
}
date {
match => [ "timestamp","UNIX", "YYYY-MM-dd HH:mm:ss", "ISO8601"]
remove_field => [ "timestamp" ]
}
}
}
指定 es 的 host 和索引。另外测试结果输出一份到屏幕便于观察。
output{
elasticsearch {
hosts => ["127.0.0.1:9200"]
index => "mongolog"
}
stdout {
codec => rubydebug
}
}
配置文件搞定之后就可以运行
bin/logstash -f config/mongo-logstash.conf
为了验证 logstash 的结果,重启下moa 服务,可以看到有大量的接入请求和查询请求。
同时在es 服务器 127.0.0.1:9200上也可以看到数据
kibana 是在es 数据的基础上进行可视化的分析并生成各种报表。在配置文件中指定es 的地址,并运行即可
#修改配置文件为如下所示
[root@dnsserver ~]# cat /usr/local/kibana/config/kibana.yml | grep elasticsearch.url
elasticsearch.url: "http://127.0.0.1:9200"
#运行
[root@dnsserver ~]# bin/kibana
kibana 主界面分为 Discover 、Visualize、DashBoard、Setting。Discover用于查看所有元数据,Visualize 用于生成报表和图形,DashBorad 可以将 Visulalize 生成的多个结果放在一起对比。
先在setting 界面新增一个 index_pattern,选择一个需要分析的索引,可以使用正则表达式匹配多个索引进行分析。logstash 会自动为每条数据生成一个时间相关的字段@timestamp 。
Discover 看到的是es 元数据,默认只显示最近15 分钟的数据,如果需要查看更多,可以修改右上角的timefilter。可以用正则去搜索数据,并保存正则表达式用于多次搜索。
图- timefilter
图- Discover界面的数据
Visualize 可以生成多种类型的图表,并支持保存。
![kibana visualize](C:\Users\sf\Desktop\markdown_html\kibana visualize.png)
比如需要查看一段时间内数据库所有表的查询次数,以直方图的形式展现出来。
根据一段时间内数据库查询生成所有表的查询次数直方图
可以看到上述平台几乎可以非常轻松的搭建在任何服务器上,使得对文本型日志的监控运维更方便更高效。
如果线下专门搭建一个用于分析的 es 服务器,定时从线上数据库的副本同步数据到本地,可以进行各种分析。
kibana官方文档:https://www.elastic.co/guide/en/kibana/current/index.html
官方下载地址: https://www.elastic.co/downloads