ELK是Elasticsearch、Logstash与Kibana三个组件的首字母的缩写,三个开源组件组合在一起就构成了一个完整的日志采集、处理与查询解决方案,下图是Elastic公司给出的ELK方案架构图。

最底层是Beats与Logstash,Beats是一个数据迁移工具可以将各种数据源如文件、网络数据包、Syslog等数据做简单解析后写入Logstash做进一步处理或直接写入Elasticsearch;Logstash与Beats功能稍有重合,它可以接收Beats发送出来的数据或者直接读取本地文件,他注重的主要是数据的预处理,本文也将对Logstash做比较详细的介绍;中间层是Elasticsearch,主要负责数据的持久化与分析,是ELK Stack的核心;最上层是Kibana,主要负责对Elasticsearch中的数据进行可视化展示。
Logstash由两个必要组件:INPUT与OUTPUT,一个可选组件FILTER组成,INPUT组件主要负责数据读取(如Beats、本地文件、syslog等),FILTER组件负责数据的预处理,OUTPUT组件负责数据输出(如Elasticsearch、Kafka、本地文件等)。

本节将详细介绍Filebeat读取本地apache日志作为输入、Elasticsearch作为输出的ELK Stack日志解决方案。

标准apache日志日志示例:
86.1.76.62 - - [04/Jan/2015:05:30:37 +0000] "GET /projects/xdotool/ HTTP/1.1" 200 12292 "http://www.haskell.org/haskellwiki/Xmonad/Frequently_asked_questions" "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140205 Firefox/24.0 Iceweasel/24.3.0"
86.1.76.62 - - [04/Jan/2015:05:30:37 +0000] "GET /reset.css HTTP/1.1" 200 1015 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140205 Firefox/24.0 Iceweasel/24.3.0"
86.1.76.62 - - [04/Jan/2015:05:30:37 +0000] "GET /style2.css HTTP/1.1" 200 4877 "http://www.semicomplete.com/projects/xdotool/" "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20140205 Firefox/24.0 Iceweasel/24.3.0"Filebeats负责将本地的日志文件解析后交于Logstash做进一步的处理,其配置如下:
filebeat.prospectors:
- type: log
paths:
- /path/to/file/logstash-tutorial.log
output.logstash:
hosts: ["localhost:5044"]5044端口是Logstash配置的beats监听端口
Logstash配置:
input {
beats {
port => "5044" # 输入为beats,监听端口5044
}
}
filter {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}"} # grok插件
}
geoip {
source => "clientip" # geoip插件
}
}
output {
elasticsearch {
hosts => ["localhost:9200"]
index => "apache_log-%{+YYYY.MM.dd}"
}
}配置文件由三部分组成:input、filter、output
对于日志数据,由于单个索引的存储量的瓶颈,ES一般推荐使用时间作为后缀为同一份日志数据创建多个索引,而用户则通过一个定时器来定时删除过期的索引。ES在6.6之后,在x-pack中推出了索引生命周期管理相关的API来简化与增强类似日志数据索引的管理。该方案基于时间将索引数据分为四个阶段:Hot、Warm、Cold、Delete,这四个阶段分别有如下的定义:
对于这四种并给不同的数据阶段,ES也给出了不同的数据处理方式如下,更加详细的文档可以看这里。
PUT _ilm/policy/apache_log_policy
{
"policy": {
"phases": {
"hot": {
"actions": { // 该阶段索引需要执行的Action
"rollover": {
"max_size": "50KB", // 单个索引超过50KB或者存在时间超过1分钟后进行Rollover
"max_age": "1m"
}
}
},
"warm" : {
"min_age": "10m", // 索引创建10分钟后进入warm阶段
"actions": {
"forcemerge" : { // 强制执行Merge,每个Shard最多1个Segment
"max_num_segments": 1
}
}
},
"delete": {
"min_age": "60m", // 索引创建60分钟后进入delete阶段
"actions": {
"delete": {} // 删除索引
}
}
}
}
}这边创建了一个名为apache_log_policy的索引生命周期管理规则,总共有三个阶段:Hot、Warm和Delete,在Hot阶段单个索引大于50KB或者创建时间超过1分钟将会Rollover。Hot索引创建时间超过10分钟后,索引进入Warm阶段,在该阶段,索引将会被执行force_merge,每个Shard最多一个Segment。Warm阶段的索引再创建60分钟后将会被删除。
PUT /_template/apache_log_template
{
"index_patterns": ["apache_log-*"],
"settings": {
"number_of_shards": 1,
"number_of_replicas": 1,
"index.lifecycle.name": "apache_log_policy", // 关联的索引生命周期规则
"index.lifecycle.rollover_alias": "apache_log" // 索引生命周期管理所用的索引别名
}
}PUT apache_log-000001 // 索引名称必须以数字结尾,方便规则进行Rollover
{
"aliases": {
"apache_log": {
"is_write_index": true
}
}
}当索引创建后,由于索引名满足了上述索引模板,所以该索引会被索引生命周期所管理。这边要注意的是,索引的名称必须以数字结尾以便于规则对索引进行Rollover。
为了让这些被管理的索引堆外暴露时看上去是一个索引,这边给了该索引一个别名:apache_log,并打开了is_write_index,is_write_index配置会被生命周期管理规则在Rollover是赋给新的索引。
GET apache_log-*/_ilm/explain响应示例
{
"indices" : {
"apache_log-000008" : {
"index" : "apache_log-000008", // 索引名称
"managed" : true, // 是否被规则管理
"policy" : "apache_log_policy", // 规则名称
"lifecycle_date_millis" : 1554118764383,
"phase" : "warm", // 当前阶段
"phase_time_millis" : 1554119964175,
"action" : "complete",
"action_time_millis" : 1554120564177,
"step" : "complete",
"step_time_millis" : 1554120564177,
"phase_execution" : { // 改阶段需要执行的Action
"policy" : "apache_log_policy",
"phase_definition" : {
"min_age" : "10m",
"actions" : {
"forcemerge" : {
"max_num_segments" : 1
}
}
},
"version" : 4,
"modified_date_in_millis" : 1554117414882
}
},
"apache_log-000007" : {
"index" : "apache_log-000007",
"managed" : true,
"policy" : "apache_log_policy",
"lifecycle_date_millis" : 1554117564136,
"phase" : "warm",
"phase_time_millis" : 1554118164176,
"action" : "complete",
"action_time_millis" : 1554118764177,
"step" : "complete",
"step_time_millis" : 1554118764177,
"phase_execution" : {
"policy" : "apache_log_policy",
"phase_definition" : {
"min_age" : "10m",
"actions" : {
"forcemerge" : {
"max_num_segments" : 1
}
}
},
"version" : 4,
"modified_date_in_millis" : 1554117414882
}
},
"apache_log-000009" : {
"index" : "apache_log-000009",
"managed" : true,
"policy" : "apache_log_policy",
"lifecycle_date_millis" : 1554119964235,
"phase" : "warm",
"phase_time_millis" : 1554120564291,
"action" : "forcemerge",
"action_time_millis" : 1554120564291,
"step" : "segment-count",
"step_time_millis" : 1554120564350,
"phase_execution" : {
"policy" : "apache_log_policy",
"phase_definition" : {
"min_age" : "10m",
"actions" : {
"forcemerge" : {
"max_num_segments" : 1
}
}
},
"version" : 4,
"modified_date_in_millis" : 1554117414882
}
},
"apache_log-000010" : {
"index" : "apache_log-000010",
"managed" : true,
"policy" : "apache_log_policy",
"lifecycle_date_millis" : 1554119964245,
"phase" : "hot",
"phase_time_millis" : 1554119964364,
"action" : "rollover",
"action_time_millis" : 1554119964364,
"step" : "check-rollover-ready",
"step_time_millis" : 1554119964364,
"phase_execution" : {
"policy" : "apache_log_policy",
"phase_definition" : {
"min_age" : "0ms",
"actions" : {
"rollover" : {
"max_size" : "50kb",
"max_age" : "10m"
}
}
},
"version" : 4,
"modified_date_in_millis" : 1554117414882
}
}
}
}基于ES提供的索引生命周期管理,我们可以很方便地实现日志数据的管理,Logstash的ES输出插件也支持了索引生命周期管理规则所管理的索引,具体配置如下:
output {
elasticsearch {
hosts => ["localhost:9200"]
ilm_enabled => true
ilm_rollover_alias => "apache_log"
ilm_pattern => "000001"
ilm_policy => "apache_log_policy"
}
}来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/31509949/viewspace-3145911/ ,如需转载,请注明出处,否则将追究法律责任。