Java util日志(log)记录使用以下输出行格式:

java.util.logging.SimpleFormatter.format = %4$s %2$s %n

这将提供以下输出,其中第一个main是一个package名称,而最后一个main是一个method名称:

Info Main.MySuperPuperClassName Main

如何消除这里的包名?因此,生成的日志(log)行将如下所示:

信息MySuperPuperClassName Main

这样做的目的是不在日志(log)行中输出包名称.

推荐答案

我很确定你不能单独使用日志(log)属性来完成这个任务. 但是,您可以编写自己的Formatter类:

import java.time.ZonedDateTime;
import java.time.ZoneId;

import java.io.StringWriter;
import java.io.PrintWriter;

import java.util.IllegalFormatException;

import java.util.logging.LogManager;
import java.util.logging.LogRecord;
import java.util.logging.SimpleFormatter;

public class NoPackageFormatter
extends SimpleFormatter {
    private static final String FORMAT_PROPERTY =
        "java.util.logging.SimpleFormatter.format";

    private static final String DEFAULT_FORMAT = "%4$s %2$s%6$s%n";
    // Java SE's default for US English locale
    //private static final String DEFAULT_FORMAT =
    //    "%1$tb %1$td, %1$tY %1$tl:%1$tM:%1$tS %1$Tp %2$s%n%4$s: %5$s%6$s%n";

    private static final ZoneId ZONE = ZoneId.systemDefault();

    private static String stripPackage(String name) {
        return name.substring(name.lastIndexOf('.') + 1);
    }

    @Override
    public String format(LogRecord record) {
        String formatString = System.getProperty(FORMAT_PROPERTY);
        if (formatString == null) {
            formatString =
                LogManager.getLogManager().getProperty(FORMAT_PROPERTY);
        }
        if (formatString == null) {
            formatString = DEFAULT_FORMAT;
        }

        String name = record.getLoggerName();
        name = stripPackage(name);

        String sourceClass = record.getSourceClassName();
        String sourceMethod = record.getSourceMethodName();
        String source = sourceClass != null && sourceMethod != null ?
            stripPackage(sourceClass) + ' ' + sourceMethod : name;

        String stackTrace = "";
        if (record.getThrown() != null) {
            StringWriter writer = new StringWriter();
            record.getThrown().printStackTrace(new PrintWriter(writer));
            stackTrace = System.lineSeparator() + writer;
        }

        Object[] args = {
            record.getInstant().atZone(ZONE),
            source,
            name,
            record.getLevel().getLocalizedName(),
            formatMessage(record),
            stackTrace
        };

        try {
            return String.format(formatString, args);
        } catch (IllegalFormatException e) {
            return String.format(DEFAULT_FORMAT, args);
        }
    }
}

要使用它,您可以在日志(log)属性中引用它:

java.util.logging.ConsoleHandler.formatter: com.example.NoPackageFormatter
java.util.logging.FileHandler.formatter:    com.example.NoPackageFormatter
java.util.logging.SocketHandler.formatter:  com.example.NoPackageFormatter

或者,您可以通过编程方式设置它:

private static final Logger logger;

static {
    logger = Logger.getLogger(MyApplication.class.getName());

    Formatter formatter = new NoPackageFormatter();

    for (Logger l = logger; l != null; l = l.getParent()) {
        for (Handler handler : l.getHandlers()) {
            handler.setFormatter(formatter);
        }
    }
}

Java相关问答推荐

Java:根据4象限中添加的行数均匀分布行的公式

Junit with Mockito for java

如何在运行时动态创建表(使用Java、JPA、SprringBoot)

如何正确创建序列图?

为什么Java编译器不区分不同类型的方法?

如何使用Jackson将XML元素与值和属性一起封装

如何将其他属性引用到log4j2 yaml配置中?

WebSockets和Spring Boot安全性出现错误401

如何在Spring Boot中创建可以将值传递给配置的&Enable&Quot;注释?

通过Java列表中的某些字段搜索值

带有可选部分的Java DateTimeForMatter

在线程Java中调用Interrupt()之后调用Join()

在实例化中指定泛型类型与不指定泛型类型之间的区别

未调用OnBackPressedCallback-Activitiy立即终止

TinyDB问题,无法解析符号';上下文&

Bash数组的单引号元素并使用空格连接

Java泛型方法重载

如何在 WebSphere Application Server 内的托管线程上运行 BatchEE 作业(job)?

人们在 IntelliJ 上将-Dhttp.proxyHost=your.proxy.net -Dhttp.proxyPort=8080放在哪里?

如何使用 Java 替换位于特定标记内的 XML 标记的 CDATA 内的值