5

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

4

3 回答 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);
    }
});

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

于 2011-10-28T06:23:20.923 回答
0

由于每个人都在谈论 log4j ......这是一个更有用的答案:

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

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

于 2011-10-28T06:30:55.993 回答
-1

假设你使用 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

这将完全满足您的需要。

于 2011-10-28T06:06:52.453 回答