当前位置:首页 > 后端开发 > 正文

java 怎么打印log

va打印日志可用System.out、ja va.util.logging或Log4j等工具,支持控制台输出及文件记录

Java开发中,日志记录是调试程序、监控运行状态和排查问题的关键环节,以下是几种主流的日志打印方式及其详细实现方法:

基础方案:标准输出流

最简单直接的方式是通过System.outSystem.err进行控制台输出。

System.out.println("普通信息");      // 标准输出(通常为绿色文本)
System.err.println("错误警告");      // 错误流(红色高亮显示)

这种方式无需额外依赖库,适合临时调试,但缺乏分级管理和持久化能力,例如在循环中批量打印数据时可用格式化字符串增强可读性:

for (int i = 0; i < 5; i++) {
    System.out.printf("第%d次迭代 值=%.2f%n", i, Math.random());
}

JDK自带框架:java.util.logging

自JDK 1.4起内置的日志体系提供了基础架构,核心步骤包括获取Logger实例、设置级别和输出格式,典型用法如下:

import java.util.logging.;
public class JULExample {
    private static final Logger logger = Logger.getLogger(JULExample.class.getName());
    public static void main(String[] args) {
        logger.severe("严重错误发生!");       // SEVERE级别
        logger.warning("潜在风险需要注意");     // WARNING级别
        logger.info("系统启动成功");           // INFO级别
        logger.config("配置参数已加载");        // CONFIG级别
        logger.fine("细节调试信息");           // FINE级别(默认不启用)
        logger.finest("极细粒度追踪");         // FINEST级别(需显式开启)
    }
}

若要修改默认行为,可通过Handler配置处理器,如将日志写入文件并按大小滚动分割:

FileHandler fileHandler = new FileHandler("app.log", true); // 追加模式
fileHandler.setLevel(Level.ALL);                          // 接收所有级别日志
logger.addHandler(fileHandler);
SimpleFormatter formatter = new SimpleFormatter();         // 简单文本格式
fileHandler.setFormatter(formatter);

更复杂的场景可使用XML配置文件定义过滤器、格式化模板等高级特性。

第三方库首选:Log4j系列

作为事实上的行业标杆,Log4j家族(尤其是Log4j 2)具有高度可配置性和卓越性能,基本用法分为三步:引入依赖→获取Logger→记录不同等级的消息,以Maven项目为例,先添加依赖项:

<!-Log4j 2核心组件 -->
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.x</version>
</dependency>

代码实现如下:

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class Log4jDemo {
    private static final Logger log = LogManager.getLogger();
    public static void main(String[] args) {
        log.error("功能异常", new Exception("数据库连接失败"));      // 带堆栈跟踪的错误日志
        log.warn("资源即将耗尽");                                   // 预警提示
        log.info("用户登录ID={}", "admin");                         // 占位符自动填充参数
        log.debug("解析JSON耗时{}毫秒", systemTime());               // 延迟加载的调试信息
        log.trace("进入方法entry()");                              // 最底层执行轨迹
    }
}

其强大之处在于通过log4j2.xml配置文件实现灵活管控,例如下列配置可实现按日期归档、控制台+文件双输出、自定义图案布局:

java 怎么打印log  第1张

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} %msg%n"/>
        </Console>
        <RollingFile name="File" fileName="logs/app.log" filePattern="logs/archive/app-%d{MM-dd-yyyy}.gz">
            <PatternLayout>
                <pattern>%d{ISO8601} [%t] %p %c{1} %m%n</pattern>
            </PatternLayout>
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true"/>
                <SizeBasedTriggeringPolicy size="10MB"/>
            </Policies>
        </RollingFile>
    </Appenders>
    <Loggers>
        <Root level="info">
            <AppenderRef ref="Console"/>
            <AppenderRef ref="File"/>
        </Root>
    </Loggers>
</Configuration>

该配置会每天生成新的压缩日志文件,单个文件超过10MB时自动分割,同时保留最近30天的日志副本。

其他优秀替代方案对比表

特性 java.util.logging Log4j 2 SLF4J+Logback
性能开销 中等 极低 非常低
配置灵活性 有限(代码/XML) 高度自由(XML) 依赖实现框架
门面模式支持
异步写入能力
MDC上下文传递
社区活跃度 较低 很高 极高

最佳实践建议

  1. 合理分级:ERROR仅用于系统级故障,INFO记录重要业务节点,DEBUG用于开发环境排错;
  2. 参数化消息:避免字符串拼接改用占位符,提升性能且支持国际化;
  3. 异常堆栈保留:捕获Throwable后作为第二个参数传入logging方法;
  4. 敏感信息过滤:生产环境关闭DEBUG级别,或使用MDC标记请求ID代替用户凭证打印;
  5. 资源释放:确保所有FileHandler/SocketHandler在使用完毕后正确关闭。

FAQs

Q1: 如何让日志同时输出到控制台和文件?
A: 在Log4j的配置中添加多个Appender即可实现多目标输出,例如上述XML示例中的<Console><RollingFile>组合,或者在代码中手动添加不同的Handler对象,注意不同Handler可以设置独立的过滤条件和格式样式。

Q2: 为什么有时候看不到预期的日志内容?
A: 常见原因包括:①日志级别设置过高(如仅开启INFO却试图打印DEBUG);②配置文件未被正确加载(检查路径拼写错误);③第三方库版本冲突导致静默失败,建议通过logger.isDebugEnabled()等方法预判是否应该产生该条日志,并在启动参数中显式指定日志级别(如-DlogLevel=TRACE)。

0