0

某些日志记录级别似乎已损坏?

我直接从 GlassFish 3.1.2.2 实例运行 Java web start(我将从现在开始调用JWS )应用程序。客户端有一个像这样的静态记录器:

private final static Logger LOGGER;
static {
    LOGGER = Logger.getLogger(App.class.getName());
    // Not sure how one externalize this setting or even if we want to:
    LOGGER.setLevel(Level.FINER);
}

在 main 方法中,我从对日志记录功能的一些简单测试开始我的逻辑:

alert("isLoggable() INFO? " + LOGGER.isLoggable(Level.INFO));     // Prints TRUE!
alert("isLoggable() FINE? " + LOGGER.isLoggable(Level.FINE));     // ..TRUE
alert("isLoggable() FINER? " + LOGGER.isLoggable(Level.FINER));   // ..TRUE
alert("isLoggable() FINEST? " + LOGGER.isLoggable(Level.FINEST)); // ..FALSE

我的警报方法将显示JOptionPane“真正的 GUI 日志记录”对话框。无论如何,您会在我添加到代码片段的评论中看到打印输出。正如预期的那样,记录器启用了级别INFOFINEFINER但不是FINEST

在我的警报方法之后,我输入:

// Info
LOGGER.info("Level.INFO");
LOGGER.log(Level.INFO, "Level.INFO");

// Fine
LOGGER.fine("Level.FINE");
LOGGER.log(Level.FINE, "Level.FINE");

// Finer
LOGGER.finer("Level.FINER");
LOGGER.log(Level.FINER, "Level.FINER");
LOGGER.entering("", "Level.FINER", args); // <-- Uses Level.FINER!

// Finest
LOGGER.finest("Level.FINEST");
LOGGER.log(Level.FINEST, "Level.FINEST");

我转到我的 Java 控制台并单击“高级”选项卡,然后勾选“启用日志记录”。好的,让我们启动应用程序。猜猜会发生什么?只有 Level.INFO 打印!这是我的证明(看底部):

在此处输入图像描述

我已经尽力在我的计算机上搜索日志文件,看看 Level.FINE 和 Level.FINER 是否最终出现在文件系统的某个位置。但是,我无法在任何地方找到日志消息。

问题总结

  1. 为什么在提供的示例中似乎记录Level.FINELevel.FINER不起作用?

  2. 我在我的静态初始化块中设置了日志记录级别,但我肯定想将此设置外部化为某种配置文件,可能与我在 GlassFish 上部署的 EAR 文件一起打包。或者为什么不在我们从服务器下载的 JNLP 文件中手动写入一些属性。这有可能吗?

4

1 回答 1

0

问题 1 的解决方案。

在对该主题进行了更多阅读之后,我得出结论,Java 中的记录器使用处理程序来发布他的日志。轮到这个处理程序有他自己的一套“墙”来处理他处理的级别。但是这个处理程序不需要直接附加到我们的记录器上!您会看到伐木工是organized in a hierarchical namespace和一个孩子伐木may inherit他父母的处理程序。如果是这样,那么By default a Logger will log any output messages to its parent's handlers, and so on recursively up the tree(请参阅Java 日志记录概述 - Oracle)。

我并不是说我现在已经了解了全部情况,而且我肯定没有找到任何关于这一切与 Java Web Start 应用程序的关系的引用。肯定有一些差异。无论如何,我确实设法一起编写了这个静态初始化块来解决我的直接问题:

static {
    LOGGER = Logger.getLogger(App.class.getName());
    /*
     * This logic can be externalized. See the next solution!
     */
    // DEPRECATED: LOGGER.setLevel(Level.FINER);
    if (LOGGER.getUseParentHandlers())
        LOGGER.getParent().getHandlers()[0].setLevel(Level.FINER);
    else
        LOGGER.setLevel(Level.FINER);
}

问题 2 的解决方案。

LogManager API 文档为以下解决方案提供了非常需要的信息。在您的 JRE 安装的子目录中,有一个名为“lib”的子目录,您将在其中找到一个“logging.properties”文件。这是我的文件在我的 Windows 机器上的完整路径:

C:\Program Files (x86)\Java\jre7\lib\logging.properties

在这里你可以改变很多口味。您可以做的一件很酷的事情是更改全局日志记录级别。在我的文件中,这是在第 29 行完成的(为什么我们在“级别”前面只看到一个点?所有记录器的根父级都称为“”!)。这将产生大量的输出;在我的机器上,我每秒收到大约一千条日志消息。因此,改变全球水平甚至不足以被视为一种选择。相反,在您指定记录器级别的位置添加一个新行。就我而言,我添加了这一行:

martinandersson.com.malivechat.app.App.level = FINER

但是,您可能仍然看不到任何结果。在解决方案 1 中,我谈到了记录器如何连接到处理程序。默认处理程序在logging.properties中指定,很可能在第 18 行。这是我的行的内容:

handlers= java.util.logging.ConsoleHandler

同样在之前,我谈到了这些处理程序如何依次使用级别来解决应该困扰他们的问题。所以,找到这样的行(现在应该在第 44 行?):

java.util.logging.ConsoleHandler.level = INFO

..就我而言,我将“INFO”换成了“FINER”。问题解决了。

但!

我对此事的最初调查仍未提供答案,如何将这些属性设置得更接近应用程序部署。更具体地说,我想将这些属性附加到一个单独的文件中,与我在 GlassFish 或类似文件上部署的应用程序 EAR 文件捆绑在一起。你有更多信息吗?请分享!

于 2013-04-20T15:36:30.617 回答