You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Google App Engine/Cloud Run中Java多行列日志显示异常问题

Java默认日志器多行日志换行符残留问题解决

问题背景

使用java.util.logging默认日志器记录多行日志时,换行确实生效了,但日志输出中仍保留了\n字符,导致日志显示不符合预期。

相关代码片段

import java.util.logging.Logger;

public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
    logger.info("Log => " + prepareWelcomeMessage());
}


private static String prepareWelcomeMessage() {
    StringBuilder stringBuilder = new StringBuilder();

    stringBuilder.append("
 ****************************** WELCOME ****************************** 
");
    stringBuilder.append(" ****************************** TO ****************************** 
");
    stringBuilder.append(" ****************************** THE ****************************** 
");
    stringBuilder.append(" ****************************** DEMO APPLICATION ****************************** 
");
    stringBuilder.append(" ****************************** TO VALIDATE ****************************** 
");
    stringBuilder.append(" ****************************** LOGS ****************************** 
");
    stringBuilder.append(" ****************************** ON APP ENGINE FLEX ****************************** 
");

    return stringBuilder.toString();
}

效果对比

  • 预期效果:日志以清晰的多行形式展示,每行对应一条欢迎标语,无多余的\n字符。
  • 实际效果:换行虽生效,但日志中仍可见\n字符,影响可读性。

解决方案

方案1:使用系统原生换行符

直接用System.lineSeparator()替代硬编码的换行,确保日志框架能正确解析,避免\n字符残留:

private static String prepareWelcomeMessage() {
    StringBuilder stringBuilder = new StringBuilder();
    String lineSeparator = System.lineSeparator();

    stringBuilder.append(" ****************************** WELCOME ****************************** ").append(lineSeparator);
    stringBuilder.append(" ****************************** TO ****************************** ").append(lineSeparator);
    stringBuilder.append(" ****************************** THE ****************************** ").append(lineSeparator);
    stringBuilder.append(" ****************************** DEMO APPLICATION ****************************** ").append(lineSeparator);
    stringBuilder.append(" ****************************** TO VALIDATE ****************************** ").append(lineSeparator);
    stringBuilder.append(" ****************************** LOGS ****************************** ").append(lineSeparator);
    stringBuilder.append(" ****************************** ON APP ENGINE FLEX ****************************** ").append(lineSeparator);

    return stringBuilder.toString();
}

方案2:自定义日志Formatter

如果默认Formatter未正确处理换行,自定义Formatter来替换日志中的转义换行符:

import java.util.logging.Formatter;
import java.util.logging.LogRecord;

public class CustomLogFormatter extends Formatter {
    @Override
    public String format(LogRecord record) {
        String logMsg = formatMessage(record);
        // 将转义的\n替换为系统换行符,消除显示残留
        logMsg = logMsg.replace("\\n", System.lineSeparator());
        return String.format("%s: %s%s", record.getLevel(), logMsg, System.lineSeparator());
    }
}

给Logger绑定自定义Formatter:

import java.util.logging.ConsoleHandler;
import java.util.logging.Logger;

public class DemoApplication {
    private static final Logger logger = Logger.getLogger(DemoApplication.class.getName());

    static {
        ConsoleHandler consoleHandler = new ConsoleHandler();
        consoleHandler.setFormatter(new CustomLogFormatter());
        logger.addHandler(consoleHandler);
        logger.setUseParentHandlers(false); // 避免日志重复输出
    }

    // 主方法及其他代码...
}

方案3:适配App Engine Flex环境配置

在App Engine Flex中,需确保日志收集组件正确处理多行日志。在app.yaml中指定日志配置文件:

runtime: java
env: flex
env_variables:
  JAVA_OPTS: "-Djava.util.logging.config.file=logging.properties"

然后在logging.properties中配置自定义Formatter:

handlers=java.util.logging.ConsoleHandler
java.util.logging.ConsoleHandler.formatter=your.package.path.CustomLogFormatter
java.util.logging.ConsoleHandler.level=INFO

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 09:43:35