前言
日志在系统中扮演着监护人的身份,它是保障高可靠服务的基础,记录了系统的一举一动。运维层面、业务层面、安全层面都有日志的身影,系统监控、异常处理、安全、审计等都离不开日志的协助。
简而言之,日志是一种可以追踪某些软件运行时所发生事件的方法。软件开发人员可以向他们的代码中调用日志记录相关的方法来表明发生了某些事情。
那么如何进行日志管理呢?——日志系统。
今天的文章将给大家介绍,如何使用ELK进行日志的管理。
ELK介绍
那么,ELK 到底是什么呢?“ELK”是三个开源项目的首字母缩写,这三个项目分别是:Elasticsearch、Logstash 和 Kibana。
Elasticsearch 是一个搜索和分析引擎。Logstash 是服务器端数据处理管道,能够同时从多个来源采集数据,转换数据,然后将数据发送到诸如 Elasticsearch 等“存储库”中。Kibana 则可以让用户在 Elasticsearch 中使用图形和图表对数据进行可视化。官方推荐中新增了Beats。
中文官网:
https://www.elastic.co/cn/what-is/elk-stack
Elasticsearch
这个开源的分布式搜索引擎基于 JSON 开发而来,具有 RESTful 风格。它使用简单,可缩放规模,十分灵活,因此受到用户的热烈好评,而且如大家所知,围绕这一产品还形成了一家专门致力于搜索的公司——Elastic。
Elasticsearch 是使用Java 编写的,它的内部使用 Lucene 做索引与搜索。Lucene可以说是当下最先进、高性能、全功能的搜索引擎库——无论是开源还是私有,但它也仅仅只是一个库。为了解决Lucene使用时的繁复性,于是Elasticsearch便应运而生。
当然,Elasticsearch 不仅仅是 Lucene,并且也不仅仅只是一个全文搜索引擎。它可以被下面这样准确地形容:
- 一个分布式的实时文档存储,每个字段可以被索引与搜索;
- 一个分布式实时分析搜索引擎;
- 能胜任上百个服务节点的扩展,并支持 PB 级别的结构化或者非结构化数据。
Elasticsearch 可以说是ELK的核心组件,我们使用Docker的方式搭建Elasticsearch。
代码语言:javascript复制# 创建 network 方便ELK之间以动态ip的方式进行访问
docker network create elastic
# 拉取指定版本的镜像
docker pull docker.elastic.co/elasticsearch/elasticsearch:7.12.1
# 启动容器,此处以单节点方式运行
docker run --name elasticsearch --net elastic -p 9200:9200 -p 9300:9300 -e "discovery.type=single-node" -d docker.elastic.co/elasticsearch/elasticsearch:7.12.1
Kibana
Elasticsearch 的核心是搜索引擎,所以用户开始将其用于日志用例,并希望能够轻松地对日志进行可视化。有鉴于此,Elastic引入了灵活的可视化工具 Kibana。
Kibana是一个开源的分析和可视化平台,设计用于和Elasticsearch一起工作。还可以在 Elastic Stack 中进行导航,这样便可以进行各种操作了,从跟踪查询负载,到理解请求如何流经整个应用,都能轻松完成。
毕竟在对于人的角度来说,一张图片胜过千万行日志。Kibana 能够自由地选择如何呈现自己的数据。
Kibana 核心产品搭载了一批经典功能:柱状图、线状图、饼图、旭日图,等等。当然啦,还可以搜索自己的所有文档。
Kibana的位置分析功能:借助Elastic Maps,探索位置数据,还可以获得创意并对定制图层和矢量形状进行可视化;Kibana的机器学习功能:借助非监督型 Machine Learning 功能来检测隐藏在 Elasticsearch 数据中的异常情况并探索那些对它们有显著影响的属性;Kibana 关联分析功能:凭借搜索引擎的相关性功能,结合 Graph 关联分析,揭示 Elasticsearch 数据中极其常见的关系。
在ELK中使用Kibana对Elasticsearch 进行可视化,我们使用Docker的方式搭建Kibana。
执行命令:
代码语言:javascript复制# 拉取对应版本的镜像
docker pull docker.elastic.co/kibana/kibana:7.12.1
# 运行容器
docker run --name kibana --net elastic -p 5601:5601 -e "ELASTICSEARCH_HOSTS=http://elasticsearch:9200" -d docker.elastic.co/kibana/kibana:7.12.1
Logstash
在使用ELK进行日志管理时,为了能够轻松地对日志进行采集和可视化,Elastic引入了强大的采集管道 Logstash。
Logstash是一个用ruby开发的开源工具,它可以作为服务器端数据处理管道,同时从多个数据源获取数据,并对其进行转换,然后将其发送到对应的“存储”,最常用的就是Elasticsearch。
Logstash提供了多种多样的input,filters,codecs和output组件,让使用者轻松实现强大的功能。
Input输入:
数据往往以各种各样的形式,或分散或集中地存在于很多系统。Logstash 支持各种输入选择,可以在同一时间从众多常用来源捕捉事件。能够以连续的流式传输方式,轻松地从日志、指标、Web 应用、数据存储以及各种 AWS 服务采集数据。
一些常用的输入为:
- file:从文件系统的文件中读取,类似于tail -f命令
- syslog:在514端口上监听系统日志消息,并根据RFC3164标准进行解析
- redis:从redis service中读取
- beats:从filebeat中读取
Filter实时解析和转换数据:
数据从源传输到存储库的过程中,Logstash 过滤器能够解析各个事件,识别已命名的字段以构建结构,并将它们转换成通用格式,以便更轻松、更快速地分析和实现商业价值。
常用方式:
- 利用 Grok 从非结构化数据中派生出结构
- 从 IP 地址破译出地理坐标
- 将 PII 数据匿名化,完全排除敏感字段
OutPut选择存储库,导出数据
尽管 Elasticsearch 是Logstash的首选输出方向,能够为搜索和分析带来无限可能,但它并非唯一选择。
Logstash 提供众多输出选择,可以将数据发送到要指定的地方,并且能够灵活地解锁众多下游用例。
每一个组件之间存在一个buffer缓冲区,input接收完数据之后,将数据送往buffer缓存起来,filter从buffer拉取数据进行过滤,将过滤后的数据送往buffer缓存起来,output从buffer处拉取过滤后数据,送往目的地存储起来。
三大组件之间的关系如下图所示:
一个多类型的日志输入配置示例(logstash.conf):
代码语言:javascript复制input {
beats{
port => 5077
tags => ["nginx_access_log"]
}
beats{
port => 5088
codec => multiline {
pattern => "^# User@Host:"
negate => true
what => previous
}
tags => ["mysql_slow_log"]
}
}
filter {
if "nginx_access_log" in [tags] {
grok {
match => { "message" => "%{COMBINEDAPACHELOG}" }
}
}
}
output {
if "nginx_access_log" in [tags] {
elasticsearch {
hosts=>["elasticsearch:9200"]
index=>"%{[@metadata][beat]}-%{ YYYY.MM.dd}"
document_type => "%{[@metadata][type]}"
}
}
if "mysql_slow_log" in [tags] {
elasticsearch {
hosts=>["elasticsearch:9200"]
index=>"mysql-slow-log-%{ YYYY.MM.dd}"
}
}
}
若是SpringBoot 等直接输出日志到Logstash可以采用Socket连接方式,其配置为:
代码语言:javascript复制input {
tcp {
host =>"0.0.0.0"
port => 5099
codec => json {
charset => "UTF-8"
}
}
stdin{}
}
filter{
json{
source => "message"
}
}
output {
elasticsearch {
hosts => " elasticsearch:9200"
index => "springboot-logstash-%{ YYYY-MM-dd}"
document_type => "logstash"
}
stdout { codec=> rubydebug }
}
注:此处需要在配置文件增加引入log4j2.xml日志配置,此处省略。
在ELK中使用Logstash 进行日志采集与数据转换等,我们使用Docker的方式搭建Logstash。
执行命令:
代码语言:javascript复制# 拉取镜像
docker pull docker.elastic.co/logstash/logstash:7.12.1
# 启动Logstash
docker run --name logstash --net elastic -v $PWD/logstash.conf:/usr/share/logstash/pipeline/logstash.conf -d docker.elastic.co/logstash/logstash:7.12.1
FileBeat
在使用ELK进行日志管理时,针对客户“我只想对某个文件进行 tail 操作”之类的需求,Elastic加入了一系列轻量型的单一功能数据采集器,并把它们叫做 Beats。
Filebeat就是本地文件的日志数据采集器。作为服务器上的代理安装,Filebeat监视日志目录或特定日志文件,tail file,并将它们转发给Elasticsearch或Logstash进行索引、kafka 等。
Filebeat隶属于Beats。目前Beats包含四种工具:
- Packetbeat(搜集网络流量数据)
- Topbeat(搜集系统、进程和文件系统级别的 CPU 和内存使用情况等数据)
- Filebeat(搜集文件数据)
- Winlogbeat(搜集 Windows 事件日志数据)
Filebeat由两个主要组件组成:prospector和harvester。
这些组件一起工作来读取文件(tail file)并将事件数据发送到您指定的输出启动Filebeat时,它会启动一个或多个查找器,查看您为日志文件指定的本地路径。
对于prospector 所在的每个日志文件,prospector 都会启动一个harvester。每个harvester都会为新内容读取单个日志文件,并将新日志数据发送到libbeat,后者将聚合事件并将聚合数据发送到您为Filebeat配置的输出。
针对上面Logstash中的配置示例,Filebeat的配置可以参考如下。
针对nginx_access_log的filebeat.yml:
代码语言:javascript复制filebeat.input:
- type: log
paths:
- /usr/local/nginx/logs/nginxtest-access.log
fields:
testenv: sport
fields_under_root: true
output.logstash:
hosts: ["logstash:5077"]
若使用Filebeat对日志进行采集,使用Docker的方式搭建Filebeat。
执行命令:
代码语言:javascript复制# 拉取镜像
docker pull docker.elastic.co/beats/filebeat:7.12.1
# 启动容器
docker run --name filebeat --net elastic -v $PWD/filebeat.yml:/usr/share/filebeat/filebeat.yml -v /var/elk/logs:/home/logs/ -d docker.elastic.co/beats/filebeat:7.12.1
通过以上的介绍与部署,相信大家能够对ELK有了初步认识,也能够逐步完成整套组件的搭建,实现日志的收集、过滤以及可视化分析功能。