前言
公司做的是IOT智能家居产品,最近需要做大数据分析的平台开发。部分定义的元数据需要从后台日志中截取(使用Logstash),然后推送到DataHub(阿里云的数据总线),DataHub再流转到OTS(阿里云的数据表格)。本文主要介绍日志的格式化定义以及如何进行Logstash的配置。
原生logstash 的安装使用可以参考前文:利用logstash截取日志中的数据并推送至Kafka
不同版本的logstash官方使用说明:logstash官网
后台日志格式化约定
-
【强制】使用SLF4J定义变量
不可直接使用日志系统(Log4j、Logback)中的API,有利于统一维护各个类的日志处理方式。
-
【强制】日志变量统一定义成static final且变量名用大写
-
【推荐】日志变量定义为private
由该类独占通过class初始化日志变量时,会以该class作为输出的类名,若混用日志变量,会导致日志输出的类名相同,真正输出日志的类被隐藏起来,不利于排查问题。
正例:
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
private static final Logger LOG = LoggerFactory.getLogger(Abc.class)
- 输出格式规范
logger.info("module={} – fuction={} – data={}","模块","功能点", ”Json串“);
例如:
logger.info("module={} – fuction={} – data={}","cs-api","snDecode", JSON.toJSONString(data));
这里cs-api是模块,snDecode是功能点,JSON.toJSONString(data) 是数据Json串。
输出的案例:
2020-08-19 15:04:12.172 INFO 21382 --- [pool-7-thread-5] c.v.v.c.b.s.helper.VeeBrainLogHelper : module=user - function=login - data={
\"lastLoginTime\":1597820652172,\"phoneModel\":\"iPhone\",\"lastLoginLng\":null,\"ip\":\"14.24.144.69\",\"lastLoginLat\":null,\"userId\":\"5ea3e33bb8a14c36e40108f2\",\"lastLoginType\":null}
Logstash的配置文件及解析
## ipput是配置日志文件的位置(支持正则匹配)
input {
file {
path => "/home/admin/vcoo-app-api/logs/spring.log"
type => "device"
start_position => "beginning"
}
}
## filter 配置的是各个ETL组件
## grok 是正则匹配,符合的就会对各变量进行解析(正则说明可直接百度:logstash grok)
filter{
grok {
match => {
"message" => [
"(?<date>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\.\d{3})\s*%{LOGLEVEL:level}\s*%{DATA:pid}\s*\-\-\-\s*\[(?<current_thread>([a-zA-Z0-9._-]+))\]\s*(?<class_info>([a-zA-Z0-9.]+))\s*\:\s*(?<module_name>([a-zA-Z0-9._-]+))=(?<module>([a-zA-Z0-9._-]+))\s*\-\s*(?<function_name>([a-zA-Z0-9._-]+))\=(?<function>([a-zA-Z0-9._-]+))\s*\-\s*(?<data_name>([a-zA-Z0-9._-]+))\=%{GREEDYDATA:data}",
"(?<date>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\,\d{3})\s*\[(?<current_thread>([a-zA-Z0-9._-]+))\]\s*%{DATA:pid}\s*%{LOGLEVEL:level}\s*\-\s*(?<module_name>([a-zA-Z0-9._-]+))=(?<module>([a-zA-Z0-9._-]+))\s*\-\s*(?<function_name>([a-zA-Z0-9._-]+))\=(?<function>([a-zA-Z0-9._-]+))\s*\-\s*(?<data_name>([a-zA-Z0-9._-]+))\=%{GREEDYDATA:data}",
"(?<date>\d{4}-\d{2}-\d{2}\s\d{2}:\d{2}:\d{2}\.\d{3})\s*%{LOGLEVEL:level}\s*%{DATA:pid}\s*\-\-\-\s*\[(?<current_thread>([a-zA-Z0-9._-]+))\]\s*(?<class_info>([a-zA-Z0-9.]+))\s*\:\s*%{DATA:info}\:%{GREEDYDATA:data}"
]
}
remove_field => ['@timestamp'