ELK日志系统交流分享
一、前言
1、为什么需要ELK系统?
公司系统日志现状:
1、多个服务器启动多个服务,日志分布在不同的机器上
2、提供的html页面只能查询某个服务的日志,每次刷新不一定是自己想要的服务器日志
3、新框架的日志只能从服务器上查看,检索与查询需要远程到服务器上
当前多数系统为分布式架构,日志分布在各个服务器,各个服务中。日志被分散到不同的服务器上,当出现bug或者收集数据时,运维人员与开发人员往往需要一个一个服务器查找才能定位到问题,这样的操作是非常非常繁琐的,并且效率十分低下。
所以说我们需要一个可以集中式管理日志的工具。
二、ELK简介
ELK是三个开源软件的缩写,分别表示:Elasticsearch , Logstash, Kibana , 它们都是开源软件。新增了一个FileBeat,它是一个轻量级的日志收集处理工具(Agent),Filebeat占用资源少,适合于在各个服务器上搜集日志后传输给Logstash,官方也推荐此工具。
-
Elasticsearch是个开源分布式搜索引擎,提供搜集、分析、存储数据三大功能。它的特点有:分布式,零配置,自动发现,索引自动分片,索引副本机制,restful风格接口,多数据源,自动搜索负载等。主要负责将日志索引并存储起来,方便业务方检索查询。
-
Logstash 主要是用来日志的搜集、分析、过滤日志的工具,支持大量的数据获取方式。一般工作方式为c/s架构,client端安装在需要收集日志的主机上,server端负责将收到的各节点日志进行过滤、修改等操作在一并发往elasticsearch上去。是一个日志收集、过滤、转发的中间件,主要负责将各条业务线的各类日志统一收集、过滤后,转发给 Elasticsearch 进行下一步处理。
-
Kibana 也是一个开源和免费的工具,Kibana可以为 Logstash 和 ElasticSearch 提供的日志分析友好的 Web 界面,可以帮助汇总、分析和搜索重要数据日志。
三、ELK工作原理
1、架构图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-n23ptTsv-1686144807870)(C:\Users\dongwei\AppData\Roaming\Typora\typora-user-images\image-20221207183019246.png)]
2、logstash
http://doc.yonyoucloud.com/doc/logstash-best-practice-cn/index.html
LogStash事件处理管道具有三个阶段:input->filter->output。input生成事件,filter修改它们,output将它们发送到其他地方。input和output支持编解码器,能够在数据进入或退出管道时对其进行编码或解码,而无需使用单独的过滤器
2.1 输入(Inputs)
input 是logstash的输入插件,支持files,syslog,tcp,redis等等,我们采用的tcp进行输入
input {
tcp {
mode => "server"
host => "0.0.0.0"
port => 8888
codec => json_lines
}
}
2.2 过滤器(filter)
过滤器是Logstash管道中间处理部件。如果事件符合特定条件,则可以将过滤器与条件语句结合使用以对事件执行操作。一些有用的过滤器包括:
1)grok: 解析和构造任意的文本,Grok是目前Logstash中解析非结构化数据到结构化和可查询数据最好的插件。在内置的 120中模式中,就很有可能找到一个满足你的需要的模式。
2)mutate: 对事件字段进行常规转换,可以重命名,删除,替换和修改事件中的字段。
3)drop: 删除整个事件数据,例如删除debug事件。
filter {
grok {
match => {"@timestamp" => "%{TIMESTAMP_ISO8601:log_date}"}
}
date {
match => [ "log_date", "MMM dd yyyy HH:mm:ss" ]
}
if "_grokparsefailure" in [tags] {
drop {}
}
}
2.3输出(Outputs)
输出是Logstash管道的最后一个阶段。事件消息可以经过多个输出接收端,一旦所有的输出都处理完成,就完成了它的任 务。一些常用的输出包括
2.3.1 elastic search
output {
elasticsearch {
hosts => ["http://localhost:9201","http://localhost:9202","http://localhost:9203"]
index => "%{[spring.application.name]}-%{+YYYY.MM.dd}"
user => "elastic"
password => "123456"
}
#输出到logstash 控制台
stdout{
codec => rubydebug
}
}
2.3.2 redis
output {
redis {
host => "hadoop000"
data_type => "list"
db => 2
port => "6379"
key => "logstash-chan-%{+yyyy.MM.dd}"
}
}
2.3.3 kafka
output{
kafka{
topic_id => "test"
# kafka的地址
bootstrap_servers => "192.168.182.22:9092"
# # 一定要注明输出格式
codec => "json"
}
}
3、elasticsearch
3.1 核心概念
名称 | 介绍 | 数据库 |
---|---|---|
索引(index) | 一个索引相当于一个关系型数据库 | testcopy |
映射(mapping) | mapping定义了每个字段的类型等信息 | 表结构 |
文档(document) | 一个document相当于关系型数据库中的一行记录 | 一行记录 |
字段 | 相当于关系型数据库的字段 | 表字段 |
集群 | 集群由一个或多个节点组成 | 数据库集群 |
节点 | 集群的节点,一台机器或一个进程。 | 分库中的某个实例 |
分片和副本 | 副本是分片的副本。分片由主分片(primary shard)和负分片(replia shard)之分; 一个index数据在物理上被分布在多个主分片中,每个主分片只存放部分数据; 每个主分片可以有多个副本,叫副本分片,是主分片的复制。 | 分表 |
3.2 倒排索引
通常的搜索步骤,正向索引结构如下:
文档1的ID→单词1的信息;单词2的信息;单词3的信息…
文档2的ID→单词3的信息;单词2的信息;单词4的信息…
搜索引擎会把正向索引变为反向索引(倒排索引)即把“文档→单词”的形式变为“单词→文档”的形式。倒排索引具体机构如下:
单词1→文档1的ID;文档2的ID;文档3的ID…
单词2→文档1的ID;文档4的ID;文档7的ID…
类似mysql的辅助索引
5、filebeat
Filebeat是用于转发和集中日志数据的轻量级传送工具。Filebeat监视您指定的日志文件或位置,收集日志事件,并将它们转发到Elasticsearch或 Logstash进行索引。
Filebeat的工作方式如下:启动Filebeat时,它将启动一个或多个输入,这些输入将在为日志数据指定的位置中查找。对于Filebeat所找到的每个日志,Filebeat都会启动收集器。每个收集器都读取单个日志以获取新内容,并将新日志数据发送到libbeat,libbeat将聚集事件,并将聚集的数据发送到为Filebeat配置的输出。
非常的轻量级,对服务器性能的影响基本上可以忽略不计
6、logback集成
<dependency>
<groupId>net.logstash.logback</groupId>
<artifactId>logstash-logback-encoder</artifactId>
<version>7.2</version>
</dependency>
在logstash.xml中加入
<appender name="logstash" class="net.logstash.logback.appender.LogstashTcpSocketAppender">
<destination>sv1.k9s.run:45604</destination> <!--logstash所在的服务器以及input中的端口号--》
<encoder charset="UTF-8" class="net.logstash.logback.encoder.LogstashEncoder">
<!--自定义字段,用逗号分割多个字段,为了区分哪个应用以及哪个环境的日志-->
<customFields>{"spring.application.name":"${APP_NAME}","environment":"test"}</customFields>
</encoder>
</appender>
<root level="INFO">
<appender-ref ref="logstash"/>
</root>
<root level="ERROR">
<appender-ref ref="logstash"/>
</root>
或者通过 append方法增加自定义字段
LOG.info(append("doaminId",orgById.getOrgName())
.and(append("module",manageAppInfoObject.getString("appName"))
.and(append("moduleCode",module))
.and(append("clientType","家长"))),"domainId:{},moduleCode:{}",domainCode,module);
四、日志规范
1、使用门面日志框架SLF4J,禁止使用 sout
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger logger = LoggerFactory.getLogger(Abc.class);
2、使用占位符连接日志
正确:
LOG.info(append("doaminId",orgById.getOrgName())
.and(append("module",manageAppInfoObject.getString("appName"))
.and(append("moduleCode",module))
.and(append("clientType","家长"))),"domainId:{},moduleCode: {}",domainCode,module);
错误:
LOG.info("=================================================start=" + (new java.util.Date()).toLocaleString());
使用+操作符进行字符串的拼接,有一定的性能损耗
3、必须输出异常日志,并使用logger.error(msg,e),并且记录后就不要再e.printStackTrace()
正确:
LOG.error("发生运行时异常!原因是:{}",e);
错误:
LOG.error("office 端 登入 错误:" + e.getMessage());
4、分清日志级别
info级别记录的一些输入输出记录,比如请求第三方接口入参与出参
error日志记录的一般是异常信息
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ft1NgxA1-1686144807874)(C:\Users\dongwei\AppData\Roaming\Typora\typora-user-images\image-20221207200112773.png)]
5、禁止在线上环境开启 debug
许多第三方框会有很多debug级别的日志,比如系统集成的定时器 quartz.,hibernate 的sql输出,会输出很多数据,造成空间浪费(一个晚上大概记录了6.7G)
6、改记录的日志的地方一定要记录日志
1)编程语言提示异常
2)业务流程调用的关键节点
3)系统核心角色,组件关键动作,比如登录,退出操作
4)系统或者服务的启动参数
五、扩展
1、通过kibana统计一些业务数据
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NPdBhA9U-1686144807875)(C:\Users\dongwei\AppData\Roaming\Typora\typora-user-images\image-20221207194042298.png)]
2、采集NGINX日志,计算网站日活量
利用filebeat采集access.log输入到nginx中,进行统计
3、各种beat组件
目前Beats包含六种工具:
Packetbeat:网络数据(收集网络流量数据)
Metricbeat:指标(收集系统、进程和文件系统级别的CPU和内存使用情况等数据)
Winlogbeat:windows事件日志(收集Windows事件日志数据)
Auditbeat:审计数据(收集审计日志)
Heartbeat:运行时间监控(收集系统运行时的数据)
nx中,进行统计
3、各种beat组件
目前Beats包含六种工具:
Packetbeat:网络数据(收集网络流量数据)
Metricbeat:指标(收集系统、进程和文件系统级别的CPU和内存使用情况等数据)
Winlogbeat:windows事件日志(收集Windows事件日志数据)
Auditbeat:审计数据(收集审计日志)
Heartbeat:运行时间监控(收集系统运行时的数据)