使用java.util.logging API将不同级别记录到单独的文件中

时间:2011-10-28 05:56:58

标签: java java.util.logging

我想知道如何使用java.util.logging api,以便根据使用的级别将日志消息写入不同的日志文件中。如果级别是INFO,那么我希望将消息写在/log/info.log中,依此类推。 3定义的级别是严重的,警告和信息。

3 个答案:

答案 0 :(得分: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中获得三个文件,每个文件只包含每个特定日志级别的消息。

注意,我喜欢在构造函数中要求Level的依赖注入样式方法,因此在使用此子类时不能“忘记”调用.setLevel()。我也禁用了.setLevel(),因为调用它和更改会破坏子类“

的语义

为了完整起见,您可以使用java.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);
    }
});

就我个人而言,我仍然更喜欢子类方法,它更不容易出错,并且更具有自我记录的目的和意图。

答案 1 :(得分:0)

因为每个人都讲述了log4j ......这是一个更有用的答案:

添加不同的句柄(文件的文件处理程序)并在处理程序上设置级别。记录器的级别必须允许最详细/放松才能传递给处理程序。

我不使用属性文件来设置jul.Logger,而只是使用一些自制的xml。如果您无法通过属性文件执行此操作,只需使用logger.getHandler()并设置适当的级别。

答案 2 :(得分:-1)

假设您使用log4j来执行日志。 您需要编写自定义appender,并将其添加到每个记录器。

  • 简单说明

在自定义appender中,您只需要一个查看日志类型的if语句,并执行必要的操作。特别是,FileAppenders可以扩展到非常自然地满足这种需求。 http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/FileAppender.html

  • 更优雅的例子

不要自己编码,而是尝试简单地设置配置文件!

http://www.vaannila.com/log4j/log4j-file-appender-example-1.html

这将完全符合您的需要。