胖胖的枫叶
主页
博客
产品设计
企业架构
全栈开发
效率工具
数据分析
项目管理
方法论
面试
  • openJdk-docs
  • spring-projects-docs
  • mysql-docs
  • redis-commands
  • redis-projects
  • apache-rocketmq
  • docker-docs
  • mybatis-docs
  • netty-docs
  • journaldev
  • geeksforgeeks
  • 后端进阶
  • 并发编程网
  • 英语肌肉记忆锻炼软件
  • 墨菲安全
  • Redisson-docs
  • jmh-Visual
  • 美团技术
  • MavenSearch
主页
博客
产品设计
企业架构
全栈开发
效率工具
数据分析
项目管理
方法论
面试
  • openJdk-docs
  • spring-projects-docs
  • mysql-docs
  • redis-commands
  • redis-projects
  • apache-rocketmq
  • docker-docs
  • mybatis-docs
  • netty-docs
  • journaldev
  • geeksforgeeks
  • 后端进阶
  • 并发编程网
  • 英语肌肉记忆锻炼软件
  • 墨菲安全
  • Redisson-docs
  • jmh-Visual
  • 美团技术
  • MavenSearch
  • 标签索引
  • 2024年

    • 配置Mac环境
    • 业务知识会计管理
    • 业务知识会计基础
    • 业务知识什么是财务
  • 2023年

    • 项目 Boi
  • 2022年

    • 企业架构故障管理
    • 企业架构开发债务
  • 2021年

    • Python3.8 Matplotlib员工数据分析
    • Python3.8 Matplotlib IP折线图
    • Python3.8 词云 IP地址
    • Redis RediSearch
    • Rust第一个CLI程序
    • Rust所有权
    • Rust函数与控制流
    • Rust变量与数据类型
    • Rust入门
    • 企业架构分布式系统
    • 编程式权限设计
    • Java JVM优化
    • SpringBoot MyBatis 批量
    • SpringBoot 测试Mock
    • SpringBoot Redis布隆过滤器
    • CentOS7 Jenkins 部署
    • SpringBoot WebClient
    • Docker Drone 部署
    • SpringBoot MyBatis
    • SpringBoot Redisson
    • SpringBoot MyBatis 雪花算法
    • Java Netty
    • Redis 扫描
    • CentOS7 Jenkins本地部署分级
    • Mac 安装 Neo4j Jupyter
    • Mac OpenJDK11 JavaFX 环境
    • Mac 安装 Jenv
    • SpringBoot Redis 延时队列
    • SpringBoot MDC日志
    • SpringBoot 定时任务
    • CentOS7 Nginx GoAccess
    • SpringBoot MyBatis 分析
    • SpringBoot Lucene
    • 企业架构分布式锁
    • 学习技巧减少学习排斥心理
    • SpringBoot 动态数据源
    • Docker Compose SpringBoot MySQL Redis
    • SpringBoot 阻塞队列
    • Docker Compose Redis 哨兵
    • Docker Compose Redis 主从
    • 网络通信
  • 2020年

    • SpringBoot 延时队列
    • MySQL基础(四)
    • Java 雪花算法
    • Redis Geo
    • 网络通信 Tcpdump
    • Spring SPI
    • Java Zookeeper
    • SpringBoot JMH
    • 网络通信 Wireshark
    • Docker Compose Redis MySQL
    • CentOS7 Docker 部署
    • Netty 源码环境搭建
    • MySQL基础(三)
    • CentOS7 Selenium运行环境
    • CentOS7 Nginx HTTPS
    • Java JMH
    • SpringBoot 修改Tomcat版本
    • Java Eureka 钉钉通知
    • SpringBoot 错误钉钉通知
    • Java JVM
    • Git 合并提交
    • CentOS7 OpenResty 部署
  • 2019年

    • Redis CLI
    • CentOS7 Nginx 日志
    • 编程式代码风格
    • IDEA 插件
    • Skywalking 源码环境搭建
    • SpringBoot Redis 超时错误
    • 编程式 gRPC
    • Java Arthas
    • Docker Compose Redis 缓存击穿
    • Docker ElasticSearch5.6.8 部署
    • Docker Mysql5.7 部署
    • Spring Redis 字符串
    • Docker Zookeeper 部署
    • Docker Redis 部署
    • SpringBoot Dubbo
    • CentOS7 CMake 部署
    • 应用程序性能指标
    • Java Code 递归
    • CentOS7 ELK 部署
    • CentOS7 Sonarqube 部署
    • Java Selenium
    • Java JJWT JUnit4
    • Spring 源码环境搭建
    • Java JUnit4
    • Java Web JSON Token
    • 编程式 FastDFS
    • Java XPath
    • Redis基础(二)
    • Redis基础(一)
    • Java MyBatis JUnit4
    • Java MyBatis H2 JUnit4
    • MyBatis 源码环境搭建
    • Git 配置
    • Java 核心
    • Java Dubbo
    • Java JavaCollecionsFramework
    • Java Maven
    • Java MyBatis
    • Java Spring
    • Java SpringMVC
    • MySQL
    • Redis
  • 2018年

    • Java HashMap
    • Java HashSet
    • Java Code 交换值
    • Spring Upgrade SpringBoot
    • Mac 编程环境
    • Java Log4j
    • 网络通信 Modbus
    • MySQL基础(二)
    • MySQL基础(一)
    • Java Stack
    • Java Vector
    • CentOS7 RabbitMQ 部署
    • CentOS7 Redis 部署
    • CentOS7 MongoDB 部署
    • CentOS7 基础命令
    • Java Eureka Zookeeper
    • CentOS7 MySQL 部署
    • Git 分支
    • CentOS7 Java环境配置
    • Java LinkedList
    • Java ArrayList
    • Spring Annotation Aop

Java Log4j

本章内容阐述个人理解,以及使用方法。若有不正确的内容欢迎斧正。睡觉之前赶快记录下来免得有忘记了。

什么是Log?

  • 日志记录的是什么?市面上流行的软件基本都有日志记录功能,作为开发人员的好帮手。日志可以有效的记录程序运行的状态以及运行的异常,比如说操作系统蓝屏了、手机死机了、软件卡死、程序崩溃、写了BUG等等都会有对应的日志留下。

如何利用log?

  • 笔者是一个Java开发人员,本章内容代码部分已Java代码用例。大家都知道日志非常重要,但是经验不足的开发人员往往忽视了这个重要的手段,比如在控制台输出日志,所有输出信息都集中在一起。排除问题非常困难,一旦出现了线上异常信息首先要看的就是日志信息。所以有必要就日志手段多了解下。

我是如何操作的?

  • 最在开发一个客户端应用,并不是GUI那种程序。功能不多但是日志信息却很多,循环监控数据,所以运行期产生的日志也有点多,开发的时候毕竟简单调试还能接受,运行起来日志过于集中眼睛疼,为了方便调试以及排除问题,考虑先将日志经拆分。不同业务或者类型使用不同的log文件来记录。

用例

  • 这里简单的演示下如何将日志信息拆分到不同的文件中。

    添加日志依赖

		<dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

这里解释下为什么是log4j而不是其他的日志框架,因为依赖的某个基础库是使用log4j我也懒的去折腾就用这个吧。

  • log4j配置文件Log4j配置文件(Configreation File)就是记录器级别、存放位置、布局等等。通过该配置文件我们可以创建log4j的运行环境下面演示基础的配置信息。
log4j.debug=false
## 控制台输出
log4j.appender.stdoutAppender=org.apache.log4j.ConsoleAppender
log4j.appender.stdoutAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.stdoutAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{3} - %m%n

## The log level may be one of OFF, FATAL, ERROR, WARN, INFO,
## DEBUG, or ALL. The default level is defined as the first
## element in the list of values for the log4j.rootLogger
## property.
##
# 指定package
log4j.logger.z201.github.io.code.log.log4j = ALL , stdoutAppender
  • 简单的解释下上面的配置信息

    • log4j.appender.stdoutAppender=org.apache.log4j.ConsoleAppender其中stdoutAppender简单的理解可以理解为日志Logger 的标识、ConsoleAppender就是日志的输出地方。
    • log4j.appender.stdoutAppender.layout=org.apache.log4j.PatternLayout其中layout是布局,使用org.apache.log4j.PatternLayout来做布局。
    • log4j.appender.stdoutAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{3} - %m%n这个就是布局的输出格式了。
    • log4j.logger.z201.github.io.code.log.log4j = ALL , stdoutAppender指定程序package使用的log,并且指定日志级别ALL全部输出。
    • 这里简单介绍下log4j日志级别
  • Java用例代码

package z201.github.io.code.log.log4j;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class TestLog4j {

    private static Logger log = LoggerFactory.getLogger(TestLog4j.class);

    @Test
    public void test01(){
        log.info("log info");
        log.error("log error");
        log.warn("log warn");
        log.trace("log trace");
        log.debug("log debug");
    }
}
  • 由于日志级别是ALL所以都会输出。
2018-06-13 00:05:13 INFO  log.log4j.TestLog4j - log info
2018-06-13 00:05:13 ERROR log.log4j.TestLog4j - log error
2018-06-13 00:05:13 WARN  log.log4j.TestLog4j - log warn
2018-06-13 00:05:13 TRACE log.log4j.TestLog4j - log trace
2018-06-13 00:05:13 DEBUG log.log4j.TestLog4j - log debug

尝试改造拆分日志

不同的日志级别输出到不同的日志文件中。简单介绍下日志级别LEVEL:OFF(关闭)FATAL(致命的) ERROR(错误)WARN(警告) INFO(信息)DEBUG (调试) ALL(所有) 输出日志的策略是由LEVEL决定的。

  • 修改log4j配置文件
log4j.debug=false
## 控制台输出
log4j.appender.stdoutAppender=org.apache.log4j.ConsoleAppender
log4j.appender.stdoutAppender.layout=org.apache.log4j.PatternLayout
log4j.appender.stdoutAppender.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{3} - %m%n

#info日志信息
log4j.logger.infoFile=INFO,infoFile
log4j.appender.infoFile=org.apache.log4j.RollingFileAppender
log4j.appender.infoFile.Append=true
log4j.appender.infoFile.File=logs/infoFile.log
log4j.appender.infoFile.encoding=UTF-8
log4j.appender.infoFile.maxBackupIndex=30
log4j.appender.infoFile.MaxFileSize=15MB
log4j.appender.infoFile.Threshold=INFO
log4j.appender.infoFile.FILE.DatePattern='.'yyyy-MM-dd-HH-mm'.log'
log4j.appender.infoFile.layout=org.apache.log4j.PatternLayout
log4j.appender.infoFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%5p] - %F(%L) - %m%n

#error日志信息
log4j.logger.errorFile=ERROR,errorFile
log4j.appender.errorFile=org.apache.log4j.RollingFileAppender
log4j.appender.errorFile.Append=true
log4j.appender.errorFile.File=logs/errorFile.log
log4j.appender.errorFile.encoding=UTF-8
log4j.appender.errorFile.maxBackupIndex=30
log4j.appender.errorFile.MaxFileSize=15MB
log4j.appender.errorFile.Threshold=ERROR
log4j.appender.errorFile.FILE.DatePattern='.'yyyy-MM-dd'.log'
log4j.appender.errorFile.layout=org.apache.log4j.PatternLayout
log4j.appender.errorFile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} [%5p] | %m%n

## The log level may be one of OFF, FATAL, ERROR, WARN, INFO,
## DEBUG, or ALL. The default level is defined as the first
## element in the list of values for the log4j.rootLogger
## property.
##
# system logs
log4j.logger.z201.github.io.code.log.log4j=ALL , infoFile , errorFile ,  stdoutAppender

  • 再次简单解释下配置的loggererrorFile 和 infoFile这是两个文件输出。
    • Append 是否运行追加内容。
    • File 文件存放地址
    • encoding 日志编码集
    • maxBackupIndex 最大存储文件个数
    • MaxFileSize 单个文件最大大小
    • Threshold 输出级别
    • FILE.DatePattern 切割日志的时候文件名称格式化
  • 依然是运行上面的Java代码,除了控制台会输出日志还会生成两个日志文件 infoFile、errorFile。依次看下日志文件中的内容。
# 文件 infoFile.log
2018-06-13 00:12:40 [ INFO] - TestLog4j.java(13) - log info
2018-06-13 00:12:40 [ERROR] - TestLog4j.java(14) - log error
2018-06-13 00:12:40 [ WARN] - TestLog4j.java(15) - log warn

# 文件 errorFile.log
2018-06-13 00:12:40 [ERROR] | log error

这里有一个疑问为什么infoFile里面输出的内容多点。这依然和日志的LEVEL有关系,由于INFO级别大小的问题,INFO级别的日志会输出别它大的级别日志。也就是设置成INFO的时候会输出 WARN 、ERROR、FATAL。而且log4j建议使用 DEBUG、INFO、WARN、ERROR这四种。

补充一点内容

实际上日志的拆分我们已经大概目的了,现在补充下其他的Appenders便于参考业务场景使用。

  • org.apache.log4j.ConsoleAppender(控制台) org.apache.log4j.FileAppender(文件)
  • org.apache.log4j.DailyRollingFileAppender(每天产生一个日志文件)
  • org.apache.log4j.RollingFileAppender(文件大小到达指定尺寸的时候产生一个新的文件)
  • org.apache.log4j.WriterAppender(将日志信息以流格式发送到任意指定的地方)

还有 Layouts的使用,列举下。

  • org.apache.log4j.HTMLLayout(以HTML表格形式布局)
  • org.apache.log4j.PatternLayout(可以灵活地指定布局模式)
  • org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
  • org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等信息)

简单的拆分日志就到这里了,log4j在日常开发中非常重要。确实不应该忽视它的存在,应该正确的使用。

END

最近更新: 2025/12/27 18:51
Contributors: 庆峰
Prev
Mac 编程环境
Next
网络通信 Modbus