1 前言
EFK是一套分布式日志服务解决方案,由各个组件构成。EFK分别是指:elasticsearch、filebeat、kibana。不过在真实的生产环境中,搭建日志服务可能还需要logstash来进行规制解析,使用kafka进行削峰填谷作为缓冲。在本文中,我主要介绍如何使用elasticsearch+filebeat+logstash+kibana来快速搭建一套分布式日志服务,来接入线上的多个产品线,并进行日志的统一管理。
2整体框架及各组件介绍
2.1 整体框架
2.2 各组件简介
filebeat:作为agent部署在需要收集日志的服务所在的机器上,进行日志的收集;
logstash:接收来自filebeat的日志流,进行规则解析,写入到es;
elasticsearch + searchguard:es用于日志的存储、查询;searchguard用于对es索引的安全防护;
kibana:进行日志查询的可视化界面。
3 日志收集&传输
3.1 logstash作为agent
在最初的ELK方案中,是将logstash作为agent部署在各个client上的进行日志的收集、解析直接写入到es中。但是在要接入的服务非常多、日质量不断增大的场景中,这种方式会造成以下影响:
- logstash非常占用内存,会影响到部署到本机器上的线上服务
- 直接写es会对es造成非常大的压力
filebeat使用go进行开发的,其轻量级特性非常适合作为agent进行部署。在本文的日志服务中,filebeat所扮演的角色,就是作为agent进行日志的收集,以及对于java异常日志multiline的处理。
3.2 filebeat作为agent
各公司都应该有自己的线上服务部署平台,由于要收集的服务是分布在许多不同的机器上的。建议将filebeat封装为一个服务,直接将二进制包打包到要部署服务的包中,根据不同的沙盒或者线上环境加载不同的filebeat.yml配置文件进行安装即可。
3.2.1 filebeat的日志收集文件说明
举例说明,我们要收集sonofelice模块的sonofelice.debug.log中的日志,针对这一个日志文件需要配置一个sonofelice_debug.yml日志收集文件,以便filebeat开启一个harvest通道开始日志收集。具体配置示例如下:
- type: log
enabled: true
paths:
- /home/work/logs/sonofelice/debug/sonofelice.debug.log
- /home/work/logs/sonofelice/debug/sonofelice.debug.log*/*.debug.log
ignore_older: 72h
close_inactive: 1h
multiline:
pattern: '^\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d'
negate: true
match: after
fields:
productline: test
module: sonofelice
submodule: api
type: debug
language: java
logpattern: java-std
region: bj
在上述配置中,必选项及解释可以参考博客:...上述配置中的各个字段会对应为es中的具体的document中的field。
3.2.2 filebeat.yml文件说明
在本文示例中通过filebeat写入的logstash,因此只需要配置如下几个部分即可。
- Filebeat modules模块用于配置3.2.1中对于每个日志文件配置的日志收集文件所在的路径。
- Logstash output部分用于配置要写入的logstash的各节点服务地址,以及证书相关信息
#============================= Filebeat modules ===============================
filebeat.config.modules:
# Glob pattern for configuration loading
path: ${path.config}/modules.d/*.yml
# Set to true to enable config reloading
reload.enabled: true
# Period on which files under path should be checked for changes
reload.period: 10s
path.data: /home/filebeat/data
filebeat.shutdown_timeout: 300s
filebeat.config.inputs:
enabled: true
path: inputs/*.yml
reload.enabled: true
reload.period: 10s
queue.mem:
events: 4096
flush.min_events: 512
flush.timeout: 1s
#output.console:
# pretty: true
#----------------------------- Logstash output --------------------------------
output.logstash:
# The Logstash hosts
hosts: ["logstash-hosts1:5044", "logstash-hosts2:5044", "logstash-hosts3:5044"]
loadbalance: true
# Optional SSL. By default is off.
# List of root certificates for HTTPS server verifications
ssl.certificate_authorities: ['${FILEBEAT_ROOT_CA_PATH}']
# Certificate for SSL client authentication
ssl.certificate: '${FILEBEAT_CRT_PEM_PATH}'
# Client Certificate Key
ssl.key: '${FILEBEAT_KEY_PEM_PATH}'
为了确保安全性,我们开启了证书访问,关于证书的生成部分,另有相关文章介绍,此处不再赘述。
如果希望将filebeat的相关监控信息写入到es,可以启用xpack monitoring,配置如下:
#============================== Xpack Monitoring ===============================
# filebeat can export internal metrics to a central Elasticsearch monitoring
# cluster. This requires xpack monitoring to be enabled in Elasticsearch. The
# reporting is disabled by default.
# Set to true to enable the monitoring reporter.
xpack.monitoring.enabled: true
# Uncomment to send the metrics to Elasticsearch. Most settings from the
# Elasticsearch output are accepted here as well. Any setting that is not set is
# automatically inherited from the Elasticsearch output configuration, so if you
# have the Elasticsearch output configured, you can simply uncomment the
# following line.
xpack.monitoring.elasticsearch:
hosts: ["es-host1:9920","es-host2:9920","es-host3:9920"]
protocol: "https"
username: "filebeat_system"
password: "abcdefg"
ssl.enabled: true
ssl.verification_mode: full
ssl.certificate_authorities: ['${FILEBEAT_ROOT_CA_PATH}']
# metric http server
http.enabled: true
http.host: localhost
http.port: 5066
4 日志规则解析
Logstash 是一款强大的数据处理工具,它可以实现数据传输,格式处理,格式化输出,还有强大的插件功能,常用于日志处理。对于logstash的详细介绍可以参考:...本文介绍的日志服务中,logstash的作用主要是接收来自filebeat收集上来的日志,匹配不同的规则,写入到不同的es索引中。
同filebeat一样,也非常建议将logstash封装为可以直接部署的服务。我们重点介绍logstash的基础配置,以及pipelines的配置。
4.1 logstash.yml配置解析
pipeline.batch.size: 500
pipeline.batch.delay: 100
config.reload.automatic: true
config.reload.interval: 30s
queue.type: persisted
path.queue: /home/logstash/data/queue
queue.max_bytes: 4gb
queue.checkpoint.writes: 256
dead_letter_queue.enable: true
dead_letter_queue.max_bytes: 100gb
path.dead_letter_queue: /home/logstash/data/dead_letter_queue
http.host: "127.0.0.1"
http.port: 5044
# ------------ X-Pack Settings (not applicable for OSS build)--------------
#
# X-Pack Monitoring
# https://www.elastic.co/guide/en/logstash/current/monitoring-logstash.html
xpack.monitoring.enabled: true
xpack.monitoring.elasticsearch.username: logstash_system
xpack.monitoring.elasticsearch.password: kdhlr953
xpack.monitoring.elasticsearch.url: ["https://es-host1:9920","https://es-host2:9920","https://es-host3:9920"]
xpack.monitoring.elasticsearch.ssl.truststore.path: /home/work/certificate/truststore.jks
xpack.monitoring.elasticsearch.ssl.truststore.password: sjaifdakdjf
xpack.monitoring.elasticsearch.ssl.verification_mode: certificate
xpack.monitoring.elasticsearch.sniffing: false
xpack.monitoring.collection.interval: 10s
xpack.monitoring.collection.pipeline.details.enabled: true
跟filebeat一样,我们开启了证书访问,因此也需要证书相关的支持。更多配置相关的介绍可以自行百度。后续也会有文章进行详细介绍。
4.2 pipelines配置解析
pipelines.yml文件主要配置logstash需要加载的pipelines的相关路径:
- pipeline.id: filebeat-log
path.config: "pipelines/filebeat-log/*.conf"
4.3 pipelines热加载
pipelines主要分为三部分:input、fileter、output,这三部分可以配置到三个不同的配置文件中。
这三个配置文件的改动是热加载的。logstash会定期进行检测。
4.3.1 input.conf
主要是filter-beats插件的配置,配置示例如下:
input {
beats {
port => 5044
client_inactivity_timeout => 600
ssl => true
ssl_certificate_authorities => ["/home/work/certificate/chain-ca.pem"]
ssl_certificate => "/home/work/certificate/server.crt.pem"
ssl_key => "/home/work/certificate/server.key.pem"
ssl_verify_mode => "force_peer"
}
}
4.3.2 filter.conf
最挑战的就是fileter的配置部分。强烈推荐定义规则时先使用grok调试器进行在线调试后再加载到logstash中。https://grokdebug.herokuapp.com/配置参考如下:
filter {
# 备份一下事件时间,@timestamp在后面的日志处理过程中会被替换成日志内容中的时间
mutate {
copy => {
"@timestamp" => "event_timestamp"
}
}
if [fields][language] == "go" and [fields][type] == "info" {
grok {
match => {
"message" => "^\[%{GO_TIMESTAMP:[@metadata][log_timestamp]}\]\s+\[%{DATA:log_level}\]"
}
pattern_definitions => {
"GO_TIMESTAMP" => "%{YEAR}/%{MONTHNUM}/%{MONTHDAY} %{HOUR}:%{MINUTE}:%{SECOND} %{TZ}"
}
}
date {
match => ["[@metadata][log_timestamp]", "yyyy/MM/dd HH:mm:ss z"]
timezone => "Asia/Shanghai"
}
}
if ![@metadata][index_name] {
mutate {
add_field => {"[@metadata][index_name]" => "%{[fields][productline]}-%{[fields][logpattern]}-%{[fields][type]}"}
}
}
if ![@metadata][document_id] {
mutate {
add_field => {"[@metadata][document_id]" => "%{[@timestamp]}%{[offset]}%{[host][name]}"}
}
mutate {
gsub => ["[@metadata][document_id]", "[.:TZ-]", ""]
}
}
}
4.3.3 output.conf
output {
if "_grokparsefailure" in [tags] or "_jsonparsefailure" in [tags] {
file {
path => "/home/work/logstash/failure_output/failure-%{+YYYY-MM-dd}.log"
}
} else {
elasticsearch {
hosts => ["https://es-host1:9920","https://es-host2:9920","https://es-host3:9920"]
index => "logstash-%{[@metadata][index_name]}-%{+YYYY.MM.dd}"
document_id => "%{[@metadata][document_id]}"
ssl => true
ssl_certificate_verification => true
truststore => "/home/work/certificate/truststore.jks"
truststore_password => "adofkoe"
user => "logstash"
password => "dafodmfkamkefadfg"
}
}
}
如果filebeat收集的日志不满足fileter.conf中配置的grok表达式,会统一写入到failure文件中,方便问题排查。
5 日志存储查询
5.1 elasticsearch
elasticsearch是一个全文检索引擎,在本文中的日志服务中主要用于日志的结构化存储和查询。
为了将不同产品线的访问权限进行隔离,我们需要在es安装时加载search-guard插件。
在第一次部署es启动前需要进行系统配置更新(使用root权限),修改/etc/security/limit.conf,保存后logout然后再login一遍系统
- hard nofile 65536
- soft nofile 65536 work hard nofile 65536 work soft nofile 65536
- soft nproc 4096
- hard nproc 4096 work soft nproc 4096 work hard nproc 4096 work soft memlock unlimited work hard memlock unlimited
在/etc/sysctl.conf加入 vm.max_map_count=262144 保存后执行sysctl -p
对于search-guard插件,可以将es封装为可独立部署的线上服务,在部署脚本中加载search-guard插件。关于插件的安装在本文中先不进行过多介绍,重点介绍一下search-guard插件的账号体系配置。
sgconfig中的用户密码需要通过执行es节点部署路径中plugin/search-guard-6/tools/hash.sh脚本来生成hash值。 执行命令为bash hash.sh -p $PASSWORD 然后将生成的hash填入sg_internal_users.yml中,并执行bin/sg_update.sh脚本
具体执行步骤如下:
第一步: 在es节点部署路径中,执行以下命令,得到一个哈希值
bash plugins/search-guard-6/tools/hash.sh -p tsdb123
第二步: 将第一步中的哈希值写入到sgconfig目录下的sg_internal_users.yml文件中
#password is: tsdb123
tsdb:
hash: $2y$12$nRgsuDYm36ZKCTjPf3/CeusU9BSGNDCOGOC.JKT7lhj9tVE.nVtS2
roles:
- tsdb
此处填写的roles: -tsdb角色需要在
第三步: 在sg_roles_mapping.yml文件中添加角色映射
sg_tsdb:
readonly: true
backendroles:
- tsdb
第四步: 在sg_roles.yml文件中添加索引控制。此处添加kibana是为了让用户可以有kibana的访问权限,否则是无法通过kibana进行查询的。
sg_tsdb:
readonly: true
cluster:
- CLUSTER_COMPOSITE_OPS_RO
indices:
'logstash-tsdb-*':
'*':
- READ
'?kibana*':
'*':
- READ
第五步: 生效配置,执行以下命令:
sh bin/sg_update.sh sgconfig/
其中sg_update.sh脚本可以自行编写,主要用于加载sg的各个配置文件。
5.2 kibana
kibana用于进行日志的查询、报表展示,可以理解为es的一个可视化操作界面。
kibana同上述的所有服务,也可以封装为单独的服务包进行安装部署,其最主要的就是kibana.yml的配置。主要配置kibana的端口,es的地址,访问es需要的用户名、密码,证书的地址等信息。
使用5,1中分配的账号进行kibana登录即可查看对应索引的相关信息。
总结
至此,搭建完上述的各个组件,依次检查filebeat的日志是否能够正确收集到对应的日志文件、logstash能否正确接收到filebeat传输过来的信息并且正确解析,检查es是否能够生成索引,kibana是否能够进行不同账号的登录以及对应es索引的日志查询。没有问题之后,分布式日志服务就搭建完毕了。