我非常确定仅凭日志属性本身是无法实现这个功能的。但是,你可以通过编写自定义的格式化器类来达成目的:
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的默认格式化字符串,适用于美国英语区域设置
private static final ZoneId ZONE = ZoneId.systemDefault();
// 方法用于移除类名中的包名部分
private static String stripPackage(String name) {
return name.substring(name.lastIndexOf('.') + 1);
}
// 重写format方法以自定义日志输出格式
@Override
public String format(LogRecord record) {
String formatPattern = System.getProperty(FORMAT_PROPERTY);
if (formatPattern == null) {
formatPattern = LogManager.getLogManager().getProperty(FORMAT_PROPERTY);
}
if (formatPattern == null) {
formatPattern = DEFAULT_FORMAT;
}
// 移除记录器名称中的包名
String loggerName = record.getLoggerName();
loggerName = stripPackage(loggerName);
// 处理源类名和方法名,如果存在则组合并移除包名,否则使用日志记录器名称
String sourceClass = record.getSourceClassName();
String sourceMethod = record.getSourceMethodName();
String source = (sourceClass != null && sourceMethod != null) ?
stripPackage(sourceClass) + ' ' + sourceMethod : loggerName;
// 如果记录中有异常,则获取其堆栈跟踪信息
String stackTrace = "";
if (record.getThrown() != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
record.getThrown().printStackTrace(pw);
stackTrace = System.lineSeparator() + sw.toString();
}
// 准备用于格式化的参数数组
Object[] arguments = {
record.getInstant().atZone(ZONE),
source,
loggerName,
record.getLevel().getLocalizedName(),
formatMessage(record),
stackTrace
};
// 尝试使用指定的格式化字符串进行格式化,如果失败则使用默认格式
try {
return String.format(formatPattern, arguments);
} catch (IllegalFormatException e) {
return String.format(DEFAULT_FORMAT, arguments);
}
}
}
要应用这个自定义格式化器,你可以在日志配置属性中引用它:
java.util.logging.ConsoleHandler.formatter=com.example.NoPackageFormatter
java.util.logging.FileHandler.formatter=com.example.NoPackageFormatter
java.util.logging.SocketHandler.formatter=com.example.NoPackageFormatter
或者,你也可以在代码中编程式地设置它:
import java.util.logging.Logger;
public class MyApplication {
private static final Logger logger;
static {
logger = Logger.getLogger(MyApplication.class.getName());
// 创建并设置自定义格式化器到所有的处理器上
Formatter customFormatter = new NoPackageFormatter();
for (Logger currentLogger = logger; currentLogger != null; currentLogger = currentLogger.getParent()) {
for (Handler handler : currentLogger.getHandlers()) {
handler.setFormatter(customFormatter);
}
}
}
// ... 其他代码
}