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

发布于 2024-12-12 03:15:54 字数 120 浏览 0 评论 0原文

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

i would like to know how to use the java.util.logging api, in order to have log message written in different log file depending on the level used. If the level is INFO then i would like to have the message written in /log/info.log and so on. The 3 defined level are severe, warning and info.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

沦落红尘 2024-12-19 03:15:54

您使用自定义处理程序写入日志记录。

这是一个简单但完整的示例,您可以在此基础上进行构建。

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);
    }
});

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

You use custom Handlers to write the Log Records.

Here is a simple, but complete example you can build upon.

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);
        }
    }
}

and here is how to use it

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
}

you will get three files in /tmp each with only the messages for each particular log level in them.

Note, I like the Dependency Injection style approach of requiring the Level in the constructor so you can't "forget" to call .setLevel() when using this sub-class. I also disabled .setLevel() because calling it and changing would break the semantics of the subclass"

Just for completeness you can use a java.util.logging.Filter to acomplish the same thing. It isn't as encapsulated but it is an alternative. It is more code and more verbose, thus more to not get right.

final FileHandler infoFileHandler = new FileHandler("/tmp/info.log");
infoFileHandler.setFilter(new Filter()
{
    public boolean isLoggable(final LogRecord logRecord)
    {
        return logRecord.getLevel().equals(Level.INFO);
    }
});

Personally I still like the sub-class approach better, it is less error prone and more self documenting as of its purpose and intent.

枯叶蝶 2024-12-19 03:15:54

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

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

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

Since everyone tells about log4j... Here is a more useful answer:

Add different handles (file handlers for files) and set the levels on the handlers. The level for the logger has to allow the most verbose/relaxed in order to pass to the handlers.

I do not use the properties file to setup the jul.Logger but just some home-brewed xml. If you can't do it via the properties file, just use logger.getHandler() and set the appropriate levels.

゛时过境迁 2024-12-19 03:15:54

假设您使用 log4j 来记录日志。
您将需要编写一个自定义附加程序,并将其添加到每个记录器中。

  • 简单说明

在自定义附加程序中,您只需使用一个 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

这将完全满足您的需要。

Assuming you use log4j to do your logs.
You will need to Write a custom appender, and add it to each logger.

  • Simple Instructions

In the custom appender , you simply have an if statement that looks at the log type, and does the necessary action. In particular, there are FileAppenders that can be extended to very naturally accomodate this need. http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/FileAppender.html

  • More elegant example

Rather than coding your own , try to simply setup a config file !

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

This will do exactly what you need .

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文