日志处理
日志分类
系统日志:项目运行中产生的,一般用于帮助开发人员找错排错。
操作日志:项目操作产生的,适用于记录一些业务上的必要操作中需要记录下来的日志。常见于记账,支付,重要信息变动等场景。
如何处理日志信息
首先是必须字段的设计
如果是系统日志,一般包含以下信息:时间戳,日志级别,日志消息,线程id,链路id,用户信息,系统状态等信息
如果是操作日志,需要记录操作人,操作时间,操作内容,操作数据库,相关业务id等信息
其次是日志框架的设计。例如在接口上记录操作信息,首先使用AOP声明自定义注解,在注解的切面上就可以采用反射获取到方法的操作信息并记录到数据库中。如果数据库中存储信息过多,一种思路是可以使用按照时间进行分表操作,另一种是可以在后期同步到非关系型数据库。另外也可以借助日志框架为我们记录日志。
Java的日志框架有哪些?
Log4j(1999):由 Ceki Gülcǔ 开发,2001 年被开源后加入 Apache 基金会成为 Apache Log4j,提供了强大的日志功能。不过,Log4j有比较明显的性能短板,在 Logback 和 Log4i2 推出后逐渐式微,最终Apache 在 2015 年宣布终止开发 Log4j并全面迁移至 Log4j2。
java.util.logging (2002.2):Java 标准库中自带的一个简单的日志实现,简称JUL,随Java 1.4发布,但功能和性能落后于 Log4j。
Slf4j(2005):Simple Logging Facade for Java,由 Ceki推出。Slf4j是一个日志门面,它并不是具体的日志实现,而是提供了一套统一的接口。开发人员只需要编写 SLF4J的 API代码,而不需要直接调用具体的日志实现,这样就可以轻松地在不同的日志实现之间切换。
Logback (2006):由 Ceki开发,优于 Log4j,支持 SIf4j。目前,Logback 已经成为 Java 社区最被广泛接受的日志实现层
Log4j2(2012):Apache Log4j2,提供了插件化结构和异步化输出。虽然 Log4j2 在多线程场景下对比Logback 有性能提升,但并未能撼动 Logback 的地位。spring-jcl (2017):JCL 全称为 Jakarta Commons Logging,是Apache 提供通用日志接口。spring-jcl 是spring 用于处理日志打印的模块,从JCL改造而来,目的是同时适配 Slf4j 和 JCL。
分布式环境下如何做日志处理?
没有日志系统之前,我们的日志可能分布在多台服务器上。每次需要查看日志,我们都需要登录每台机器。然后,使用grep、wc等 Linux 命令来对日志进行搜索。这个过程是非常麻烦并且耗时的!并且,日志量不大的时候,这个速度还能忍受。当日志量比较多的时候,整个过程就是非常慢。
从上面我的描述中,你已经发现,没有对日志实现集中管理,主要给我们带来了下面这几点问题
- 开发人员登录线上服务器查看日志比较麻烦并且存在安全隐患
- 日志数据比较分散,难以维护,不方便检索
- 日志数量比较大的时候,查询速度比较慢
- 无法对日志数据进行可视化展示
ELK
下图是一个最简单的 ELK 日志系统架构

Logstash:Logstash 主要用于日志的搜集、分析和过滤,支持对多种日志类型进行处理。在 ELK 日志系统中,Logstash 负责日志的收集和清洗。
Elasticsearch:ElasticSearch 一款使用 Java 语言开发的搜索引擎,基于 Lucence 。可以解决使用数据库进行模糊搜索时存在的性能问题,提供海量数据近实时的检索体验。在 ELK 日志系统中Elasticsearch 负责日志的搜素。
Kibana:Kibana 是专门设计用来与 Elasticsearch 协作的,可以自定义多种表格、柱状图、饼状图、折线图对存储在 Elasticsearch 中的数据进行深入挖掘分析与可视化。ELK 日志系统中,Logstash 主要负责对从 Elasticsearch 中搜索出来的日志进行可视化展示。