You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

基于Spring与Apache Tomcat的控制台日志最佳打印方式及问题排查

解决Tomcat下Log4j日志时有时无及方法出入参打印问题

我来帮你拆解下你遇到的问题,一步步搞定:

一、先搞定日志“时有时无”的核心问题

你的现有Log4j配置有关键缺失,再加上Tomcat自带日志组件的冲突,才导致日志不稳定。

1. 补全并修正log4j.properties配置

你之前的配置没写完ConsoleAppender的核心配置,下面是完整可用的版本:

# 根日志级别设为debug,输出到控制台
log4j.rootCategory=debug, console
# 你的业务包单独设置debug级别,关闭继承避免重复输出
log4j.logger.com.demo.package=debug, console
log4j.additivity.com.demo.package=false

# 控制台输出器完整配置
log4j.appender.console=org.apache.log4j.ConsoleAppender
# 指定日志输出格式,包含时间、线程、级别、类、行号和内容,方便排查问题
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %-5p %c{1}:%L - %m%n
# 解决Tomcat控制台日志乱码问题
log4j.appender.console.encoding=UTF-8

2. 解决Tomcat自带日志的冲突

Tomcat默认用Java Util Logging(JUL),会和Log4j抢控制台输出,导致部分日志被吞。你需要修改Tomcat启动参数:

  • Linux/Mac:打开bin/catalina.sh,在开头添加:
CATALINA_OPTS="$CATALINA_OPTS -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager"
  • Windows:打开bin/catalina.bat,在开头添加:
set CATALINA_OPTS=%CATALINA_OPTS% -Djava.util.logging.manager=org.apache.logging.log4j.jul.LogManager

二、实现方法出入参日志打印

只靠Log4j配置没法自动打出入参,得结合代码或者AOP来做,给你两种方案:

方案1:手动添加日志(简单直接,适合少量方法)

在需要追踪的方法里直接加日志:

public User getUserById(Long id) {
    // 打印入参
    logger.debug("getUserById 方法入参:id={}", id);
    User user = userDao.selectById(id);
    // 打印出参
    logger.debug("getUserById 方法出参:user={}", user);
    return user;
}

方案2:AOP全局拦截(适合批量处理所有方法)

如果你的项目用Spring,用AOP可以一次性给所有业务方法加出入参日志:

  1. 写一个切面类:
@Component
@Aspect
public class MethodLogAspect {
    private static final Logger logger = LoggerFactory.getLogger(MethodLogAspect.class);

    // 拦截com.demo.package下所有类的所有方法
    @Pointcut("execution(* com.demo.package..*.*(..))")
    public void methodPointcut() {}

    @Around("methodPointcut()")
    public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
        // 获取方法和类信息
        MethodSignature signature = (MethodSignature) joinPoint.getSignature();
        String className = signature.getDeclaringTypeName();
        String methodName = signature.getMethod().getName();
        // 获取入参
        Object[] args = joinPoint.getArgs();

        // 打印入参
        logger.debug("【{}】类的【{}】方法入参:{}", className, methodName, Arrays.toString(args));

        // 执行原方法
        Object result = joinPoint.proceed();

        // 打印出参
        logger.debug("【{}】类的【{}】方法出参:{}", className, methodName, result);

        return result;
    }
}
  1. 开启Spring AOP:如果是注解配置,在启动类加@EnableAspectJAutoProxy;如果是XML配置,加<aop:aspectj-autoproxy/>

三、验证步骤

  1. 替换你的log4j.properties为上面的完整配置;
  2. 修改Tomcat的启动参数;
  3. 重启Tomcat,测试接口,观察控制台日志是否稳定输出,方法出入参是否正常打印。

内容的提问来源于stack exchange,提问作者user6709592

火山引擎 最新活动