我目前正在开发一个程序,在其中必须将所有输出写入日志文件。
我需要编写一个日志方法,该方法应按照指定的顺序提供级别、消息、对象值、另一条消息、整数值、另一条消息和另一个整数值的输出。我似乎找不到可以实现这一点的日志方法。我正在使用 Java.util.logging
。这是否可能?
我目前正在开发一个程序,在其中必须将所有输出写入日志文件。
我需要编写一个日志方法,该方法应按照指定的顺序提供级别、消息、对象值、另一条消息、整数值、另一条消息和另一个整数值的输出。我似乎找不到可以实现这一点的日志方法。我正在使用 Java.util.logging
。这是否可能?
logger.log(Level.INFO, "{0},{1},{2},{3},{4},{5}",new Object[]{Message1,object.getValue(),Message2,1,Message3,2});
现在您需要创建一个自定义格式化程序,通过扩展Formatter类来实现
public class DataFormatter extends Formatter {
@Override
public synchronized String format(LogRecord record) {
String formattedMessage = formatMessage(record);
String throwable = "";
String outputFormat = "%1$s, %2$s \n %3$s"; //Also adding for logging exceptions
if (record.getThrown() != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
pw.println();
record.getThrown().printStackTrace(pw);
pw.close();
throwable = sw.toString();
}
return String.format(outputFormat,record.getLevel().getName(),formattedMessage,throwable);
}
}
现在设置新创建的格式化程序
for(int i=0;i<logger.getHandlers().length;i++)
logger.getHandlers()[i].setFormatter(new DataFormatter());
java.util.logging.Logger
的方法 public void log(Level level, String msg, Object params[])
来实现相同的功能。你只需要在消息中给占位符编号,如 {0}
、{1}
等,并传递一个参数数组,就像上面展示的 new Object[] {parameter1, parameter2}
。 - havryliuklogger.error("Error while finding A from DB. a : {} and b : {}", a, b);
logger.info("Nothing found in db for A with a : {} and b : {}", a, b);
java.util.logging
。 - Panu Haaramo这是一个相当老的话题,但我想分享我的两分意见,因为在我的项目中,我也更喜欢使用java.util.logging.Logger。
Lambda使得多个自定义参数的样板代码格式化扩展或多或少过时了,除非你从其应用范围的重复使用中受益。在(我)简单的场景中,日志消息是根据插入它的代码部分进行调整的,因此String.format()
通常更加容易和灵活。
在Java 8之前和lambda之前,Formatter
是推迟消息构造的唯一可能性。唯一的替代方法是,在基于级别的loggable
检查之前提前构造要记录的消息。
使用Java 8 Lambda后,字符串格式化可以推迟到loggable
检查之后,但仍然可以访问原始方法上下文。唯一的小缺点是,由于lambda限制,所有访问的字段都需要是final的。
这里是一个相当简单的片段:
final String val1 = "lambda expression log message";
final Level level = Level.INFO;
Logger.getGlobal().log(level, () ->
String.format("Hello, I'm a %s, evaluated after %s loggable check.", val1, level)
);
Logger.getGlobal().log(level, new RuntimeException(), () ->
String.format("Hello, I'm a %s with a stack trace, evaluated after %s loggable check.", val1, level)
);
希望这可以帮助到一些也想使用内置日志记录的人们 :-)String.format
而不是java.util.logging.Logger
本身进行插入时,无法应用参数格式化。 - BreinaLogger logger = java.util.logging.Logger.getLogger("MyLogger");
logger.log(java.util.logging.Level.INFO, "Test {0}, {1}", new Object[]{2, 3});
结果:
INFO: Test 2, 3