我想知道如何使用java.util.logging
api,以便根据使用的级别将日志消息写入不同的日志文件。如果级别是 INFO,那么我希望将消息写入 /log/info.log 等。定义的 3 个级别是严重、警告和信息。
3 回答
您使用自定义Handlers
来编写日志记录。
这是一个简单但完整的示例,您可以在此基础上进行构建。
import java.io.IOException;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.LogRecord;
public class LevelBasedFileHandler extends FileHandler
{
public LevelBasedFileHandler(final Level level) throws IOException, SecurityException
{
super();
super.setLevel(level);
}
public LevelBasedFileHandler(final String s, final Level level) throws IOException, SecurityException
{
super(s);
super.setLevel(level);
}
public LevelBasedFileHandler(final String s, final boolean b, final Level level) throws IOException, SecurityException
{
super(s, b);
super.setLevel(level);
}
public LevelBasedFileHandler(final String s, final int i, final int i1, final Level level) throws IOException, SecurityException
{
super(s, i, i1);
super.setLevel(level);
}
public LevelBasedFileHandler(final String s, final int i, final int i1, final boolean b, final Level level) throws IOException, SecurityException
{
super(s, i, i1, b);
super.setLevel(level);
}
@Override
public void setLevel() { throw new UnsupportedOperationException("Can't change after construction!"); }
// This is the important part that makes it work
// it also breaks the contract in the JavaDoc for FileHandler.setLevel()
@Override
public void publish(final LogRecord logRecord)
{
if (logRecord.getLevel().equals(super.getLevel())
{
super.publish(logRecord);
}
}
}
这是如何使用它
try
{
// I use the Anonymous logger here, but any named logger will work as well
final Logger l = Logger.getAnonymousLogger();
l.addHandler(new LevelBasedFileHandler("/tmp/info.log", Level.INFO));
l.addHandler(new LevelBasedFileHandler("/tmp/warn.log", Level.WARNING));
l.addHandler(new LevelBasedFileHandler("/tmp/server.log", Level.SEVERE));
l.info("This is an INFO message");
l.warning("This is a WARNING message");
l.severe("This is a SEVERE message");
}
catch (final IOException e)
{
// ignore this for this example, you should never do this in real code
}
您将在每个文件中获得三个文件,/tmp
其中只有每个特定日志级别的消息。
请注意,我喜欢在构造函数中要求使用 Dependency Injection 风格的方法,因此在使用此子类时Level
您不能“忘记”调用。.setLevel()
我也禁用.setLevel()
了,因为调用它并更改会破坏子类的语义”
只是为了完整起见,您可以使用 ajava.util.logging.Filter
来完成同样的事情。它没有被封装,但它是一种替代方案。它的代码更多,更冗长,因此更不正确。
final FileHandler infoFileHandler = new FileHandler("/tmp/info.log");
infoFileHandler.setFilter(new Filter()
{
public boolean isLoggable(final LogRecord logRecord)
{
return logRecord.getLevel().equals(Level.INFO);
}
});
就我个人而言,我仍然更喜欢子类方法,它更不容易出错,并且在其目的和意图方面更能自我记录。
由于每个人都在谈论 log4j ......这是一个更有用的答案:
添加不同的句柄(文件的文件处理程序)并设置处理程序的级别。记录器的级别必须允许最详细/最宽松的级别才能传递给处理程序。
我不使用属性文件来设置 jul.Logger,而只是一些自制的 xml。如果您不能通过属性文件执行此操作,只需使用 logger.getHandler() 并设置适当的级别。
假设你使用 log4j 来做你的日志。您将需要编写一个自定义附加程序,并将其添加到每个记录器。
- 简单说明
在自定义 appender 中,您只需要一个 if 语句来查看日志类型并执行必要的操作。特别是,可以扩展 FileAppender 以非常自然地满足这种需求。http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/FileAppender.html
- 更优雅的例子
与其编写自己的代码,不如尝试简单地设置一个配置文件!
http://www.vaannila.com/log4j/log4j-file-appender-example-1.html
这将完全满足您的需要。