Spring Cloud 微服务(七)- 下:日志收集详解
日志收集详解
本文详细介绍日志信息从应用到 Elasticsearch 的具体传输过程,是 日志收集集成 的升级篇。
1. 概述
首先,需要确定日志信息的内容,这里主要讨论 对象内容,同时涉及 文本内容。
1.1. 文本内容
文本内容 只上传日志信息的消息,最终在 Kibana 看到的日志信息,类似我们在控制台看到的:
Figure 1. Kibana 日志
上图只展示 message
字段,无法排序,需要加上时间戳:
时间戳仅用于排序,没有其他用途。
1.2. 对象内容
对象内容 会上传日志信息的 JSON 对象,其中可以包含文本内容提到的消息和其他字段。在 Kibana 中,可以选择需要的字段组合展示:
Figure 2. kibana日志对象
上图,展示出时间、应用、日志级别、日志类和消息;数据多了,界面展示很乱,如果能固定列宽,溢出隐藏,单行展示会比较美。
2. 配置 AmqpAppender
AmqpAppender
的详细配置参考 spring-amqp-logging。
AmqpAppender
会使用一些默认值,合适的默认值不会修改直接延用:
logback-spring.xml
<springProperty scope="context" name="appId" source="spring.application.name"/>
<appender name="AMQP" class="org.springframework.amqp.rabbit.logback.AmqpAppender">
<!--默认值-->
<host>localhost</host>
<!--默认值-->
<port>5672</port>
<!--默认值-->
<virtualHost>/</virtualHost>
<!--默认值-->
<username>guest</username>
<!--默认值-->
<password>guest</password>
<!--默认值 false,改为 true -->
<declareExchange>true</declareExchange>
<!--默认值-->
<exchangeName>logs</exchangeName>
<!--默认值-->
<exchangeType>topic</exchangeType>
<!--默认值-->
<durable>true</durable>
<!--默认值-->
<autoDelete>false</autoDelete>
<!--默认值-->
<routingKeyPattern>%c.%p</routingKeyPattern>
<!--默认值-->
<deliveryMode>PERSISTENT</deliveryMode>
<!--默认值-->
<senderPoolSize>2</senderPoolSize>
<!--默认值-->
<maxSenderRetries>30</maxSenderRetries>
<!--默认值-->
<contentType>text/plain</contentType>
<!--无默认值,设置为 UTF-8 -->
<contentEncoding>UTF-8</contentEncoding>
<!--无默认值,从配置文件读取 -->
<applicationId>${appId}</applicationId>
<!--默认值 false-->
<generateId>false</generateId>
<!--默认值 true -->
<addMdcAsHeaders>true</addMdcAsHeaders>
<!--文本内容:简单按文件格式输出 -->
<layout><pattern>${FILE_LOG_PATTERN}</pattern></layout>
<!--对象内容:与文本内容二选一 -->
<encoder class="net.logstash.logback.encoder.LogstashEncoder">
<excludeMdcKeyName>rootLevel</excludeMdcKeyName>
<shortenedLoggerNameLength>36</shortenedLoggerNameLength>
<fieldNames>
<logger>class</logger>
<thread>thread</thread>
</fieldNames>
</encoder>
</appender>
以上配置会输出什么结果呢?除了在 pattern
中声明的属性,AmqpAppender
还会自动添加一些其他属性,包括:deliveryMode
、contentType
、contentEncoding
、messageId
、timestamp
、appId
等。
停止 Logstash(避免其消费消息),从 RabbitMQ 查看日志信息:
Figure 3. 含追踪信息的日志
追踪信息(traceId
、spanId
、spanExportable
)是由 spring-cloud-starter-sleuth
提供的,设置参数 addMdcAsHeaders=true
,会自动携带追踪信息。
RabbitMQ 中消息包含属性部分和负载部分,与 Logstash 集成时,只使用负载部分,所以不需要设置 addMdcAsHeaders=true。[1] |
---|
追踪信息同时也会出现在负载中:
{
"@timestamp": "2020-07-22T19:25:44.345+08:00",
"@version": 1,
"message": "/actuator/configprops at position 2 of 15 in additional filter chain; firing Filter: 'SecurityContextPersistenceFilter'",
"class": "o.s.security.web.FilterChainProxy",
"thread": "http-nio-8888-exec-7",
"level": "DEBUG",
"level_value": 10000,
"app_id": "peacetrue-microservice-config-center",
"traceId": "a83467a14506d0f6",
"spanId": "a83467a14506d0f6",
"spanExportable": "false",
}
这得益于 logstash-logback-encoder 的支持。
日志信息已经发出,Logstash 会怎么处理呢?
3. 配置 logstash.conf
logstash.conf 的详细配置参考 plugins-inputs-rabbitmq。
Logstash 会使用一些默认值,合适的默认值不会修改直接延用:
logstash.conf
input {
rabbitmq {
#无默认值
host => "rabbitmq"
#默认值
port => 5672
#无默认值,设置为 logs,与 AmqpAppender 相同,如果不存在会自动创建交换机
exchange => "logs"
#无默认值,同上
exchange_type => "topic"
#默认值 false,设置为 true,与 AmqpAppender 相同
durable => true
#无默认值,设置为 # ,匹配所有消息
key => "#"
#默认值"",随机生成,设置为 logstash
queue => "logstash"
#无默认值
type => "logstash"
#默认值
codec => "json"
#默认值 false,只读取负载部分内容,不读取属性
metadata_enabled => false
}
}
Logstash 默认不会读取消息的属性信息,这会加重负载。与之配合,设置 AmqpAppender 的 addMdcAsHeaders
为 false
。Logstash 会向读取的数据中填充 @timestamp=当前时间
、@version="1"
、type="logstash"
属性(如果不存在),然后发送给 Elasticsearch。
4. Elasticsearch
从 Kibana 查看展示的日志详细数据:
{
"_index": "logstash-2020.07.22-000001",
"_type": "_doc",
"_id": "fdFfdnMBkX8Py3sCZ1uY",
"_version": 1,
"_score": 0,
"_source": {
"class": "o.s.s.w.a.ExceptionTranslationFilter",
"level_value": 10000,
"message": "Chain processed normally",
"@timestamp": "2020-07-22T11:53:50.587Z",
"X-B3-TraceId": "f5f45881f350f422",
"traceId": "f5f45881f350f422",
"thread": "http-nio-8888-exec-4",
"level": "DEBUG",
"type": "logstash",
"X-B3-SpanId": "f5f45881f350f422",
"spanExportable": "false",
"app_id": "peacetrue-microservice-config-center",
"@version": 1,
"rootLevel": "DEBUG",
"spanId": "f5f45881f350f422",
"X-Span-Export": "false"
},
...
}
其中,_source
是从 Logstash 发过来的数据,其他是由 Elasticsearch 生成的。
1. 如果想配合属性部分使用,也是可以的,但需要改造 Logstash,本文不讨论
- 三星KNOX远程静默安装漏洞深入分析报告
- 技术分享:MSSQL注入xp_cmdshell
- 通过5个简单序列预测实例学习LSTM递归神经网络
- Google发现Windows 8.1 0day漏洞并公布漏洞验证程序(PoC)
- 携程React Native实践
- 数据分析告诉你:Php最不安全,Nginx比Apache安全
- 用python抓取摩拜单车API数据并做可视化分析(源码)
- 用Pandas在Python中可视化机器学习数据
- Intent 属性详解(下)
- 把复杂json解析成javabean思路:思路:
- Python数据科学计算库的安装和numpy简单
- 4G安全:研究人员发现攻击4G无线上网卡和SIM卡的方法
- Python文学化编程 - Jupyter notebook使用和插件拓展
- PoisonCake(毒蛋糕):内置于手机ROM的恶意代码模块
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- dotnet tool 工具安装提示 Could not find a part of the path 安装失败
- dotnet core 进行 XML 序列化抛出 XmlSerializers dll 文件找不到
- C# dotnet 高性能多线程工具 ExecuteOnceAwaiter 只执行一次的任务
- 一道Postgresql递归树题
- 突击并发编程JUC系列-JDK1.8 扩展类型 LongAdder
- 利用tensorflow训练简单的生成对抗网络GAN
- 《Java从入门到失业》第三章:基础语法及基本程序结构(3.7):运算符(基本算数运算符、原码、反码、补码)
- 《Java从入门到失业》第三章:基础语法及基本程序结构(3.6):基本数据类型及字符集编码(字符编码和char型)
- 《Java从入门到失业》第三章:基础语法及基本程序结构(3.6):基本数据类型及字符集编码(整型、浮点型、布尔型)
- 多图详解Spring框架的设计理念与设计模式
- 《Java从入门到失业》第三章:基础语法及基本程序结构(3.2-3.5):标识符、关键字、注释、变量及常量
- 《Java从入门到失业》第三章:基础语法及基本程序结构(3.1):一个简单的例子
- 详解Java解析XML的四种方法
- 《Java从入门到失业》第四章:类和对象(4.6):类路径
- 《Java从入门到失业》第四章:类和对象(4.5):包