当前位置: 首页 > 面试题库 >

在记录活动中使用readConfiguration方法

鲁丰
2023-03-14
问题内容

为了在小型Java桌面应用程序中使用日志记录,我试图深入了解某些方法的操作。我使用一个非常愚蠢的小型Java程序对其进行测试。

特别是,在测试LogManager.readConfiguration()方法的行为时,我发现了一些奇怪的东西。在所有测试中,LogManager均从JRE目录中lib
/ logging.properties中的属性文件中读取其配置。此时,此文件的内容如下:

handlers=java.util.logging.ConsoleHandler
myapp2.handlers=java.util.logging.ConsoleHandler
myapp2.MyApp2.handlers=java.util.logging.ConsoleHandler
.level=OFF
java.util.logging.ConsoleHandler.level=ALL
java.util.logging.ConsoleHandler.formatter=java.util.logging.SimpleFormatter
java.util.logging.SimpleFormatter.format=%4$s: %5$s [%1$tc]%n
myapp2.level=WARNING
myapp2.MyApp2.level=INFO

Java程序的代码是:

package myapp2;

import java.io.IOException;
import java.util.logging.LogManager;
import java.util.logging.Logger;

public class MyApp2 {

    private static final Logger LOGGER = Logger.getLogger(MyApp2.class.getPackage().getName());
    private static final Logger LOGGER1 = Logger.getLogger(MyApp2.class.getName());

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        LOGGER.severe("severe at MyApp2");
        LOGGER.warning("warning at MyApp2");
        LOGGER.info("info at MyApp2");
        LOGGER1.severe("severe1 at MyApp2");
        LOGGER1.warning("warning1 at MyApp2");
        LOGGER1.info("info1 at MyApp2");
        LOGGER1.setLevel(null);
        LOGGER1.setUseParentHandlers(false);
        LOGGER1.severe("severe2 at MyApp2");
        LOGGER1.warning("warning2 at MyApp2");
        LOGGER1.info("info2 at MyApp2");
        try {
            LogManager.getLogManager().readConfiguration();
        } catch (IOException ex) {
            System.out.println("I/O Exception found");
        } catch (SecurityException ex) {
            System.out.println("Error SecurityException found");
        }
        LOGGER.severe("severe3 at MyApp2"); 
        LOGGER1.severe("severe4 at MyApp2");
    }
}

如果我们在没有围绕readConfiguration()的try-catch的情况下执行它,则将按预期工作,并且输出如下:

SEVERE: severe at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
SEVERE: severe at MyApp2 [dc. maig 08 14:45:38 CEST 2013] 
WARNING: warning at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
WARNING: warning at MyApp2 [dc. maig 08 14:45:38 CEST 2013] 
SEVERE: severe1 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
SEVERE: severe1 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
SEVERE: severe1 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
WARNING: warning1 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
WARNING: warning1 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
WARNING: warning1 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
INFO: info1 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
INFO: info1 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
INFO: info1 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
SEVERE: severe2 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
WARNING: warning2 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
SEVERE: severe3 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
SEVERE: severe3 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]
SEVERE: severe4 at MyApp2 [dc. maig 08 14:45:38 CEST 2013]

但是,如果我们使用try-catch执行,则输出为:

SEVERE: severe at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
SEVERE: severe at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
WARNING: warning at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
WARNING: warning at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
SEVERE: severe1 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
SEVERE: severe1 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
SEVERE: severe1 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
WARNING: warning1 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
WARNING: warning1 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
WARNING: warning1 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
INFO: info1 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
INFO: info1 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
INFO: info1 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
SEVERE: severe2 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
WARNING: warning2 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]
SEVERE: severe3 at MyApp2 [dc. maig 08 14:46:51 CEST 2013]

读取readConfiguration()方法的API后,应该重新初始化日志记录属性,并从先前命名的文件中重新读取日志记录配置。如果是的话,为什么feature3仅显示一次(由于程序中存在两个LOGGER和转发行为,我预计将显示两次)而严重4缺失(我希望显示一次)?有人可以帮我理解这个吗?


问题答案:

我在使用readConfiguration方法时遇到了很多错误。它不是您期望的。我创建了一个小单元测试来说明这一点:

package com.demo;

import java.io.IOException;
import java.io.InputStream;
import java.util.logging.LogManager;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author dhubau
 */
public class LogTest {

    private static final Logger logger = LoggerFactory.getLogger(LogTest.class.getCanonicalName());

    @Test
    public void testLogs() throws IOException {
        logger.trace("BEFORE");
        logger.debug("BEFORE");
        logger.info("BEFORE");
        logger.warn("BEFORE");
        logger.error("BEFORE");

        InputStream is = LogTest.class.getResourceAsStream("/logging.properties");

        LogManager.getLogManager().readConfiguration(is);

        logger.trace("AFTER");
        logger.debug("AFTER");
        logger.info("AFTER");
        logger.warn("AFTER");
        logger.error("AFTER");
    }
}

启动单元测试时,将读取默认的logging.properties(将所有信息默认为INFO日志记录)。我记录每个级别一次,然后读取自己的logging.properties文件:

# Specify the handlers to create in the root logger
handlers = java.util.logging.ConsoleHandler

# Set the default logging level for the root logger
.level = INFO

# Do not use the root handlers
com.demo.useParentHandlers = false

# DEMO log handlers
com.demo.handlers = java.util.logging.ConsoleHandler

# DEMO log level
com.demo.level = ALL

# Set the default logging level for new ConsoleHandler instances
java.util.logging.ConsoleHandler.level = ALL

之后,我得到以下输出:

May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
INFO: BEFORE
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
WARNING: BEFORE
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
SEVERE: BEFORE
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
INFO: AFTER
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
WARNING: AFTER
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
SEVERE: AFTER

因此,您看到com.demo程序包未记录TRACE或DEBUG级别。当我将以下参数传递给单元测试时:

java.util.logging.config.file = C:\ TEMP \ logging.properties

它给了我以下输出:

May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
FINEST: BEFORE
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
FINE: BEFORE
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
INFO: BEFORE
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
WARNING: BEFORE
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
SEVERE: BEFORE
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
INFO: AFTER
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
WARNING: AFTER
May 24, 2013 11:27:29 AM com.demo.LogTest testLogs
SEVERE: AFTER


 类似资料:
  • 问题内容: 我希望能够在Web应用程序中记录用户活动。我目前正在使用log4j,它对于记录错误等非常有效,但是我不确定记录用户,执行的servlet方法和方法参数的最佳方法是什么。我正在使用Spring Security进行身份验证。 典型的servlet可能看起来像: 如果有两个用户foo和bar,则foo检查他的余额,bar存入两个现金10.00和5.00。我希望日志看起来像: 如果有人可以提

  • 问题内容: 有没有办法一次插入多个记录而不是一次插入? 我有一个非常丑陋的耙子任务,正在做以下事情… 这必须非常低效,并且必须有更好的方法… 问题答案: 该方法也将数组作为参数。 但是,它仍然对每个条目执行一个SQL查询,而不是单个SQL查询。它效率更高,因为它只需要在后台创建一个activerecord对象。 如果要同时从同一客户端插入许多行,请使用带有多个VALUES列表的INSERT语句一次

  • 我有一个从外部数据库获取数据的功能,我可以获得特定的电影信息,如id、名称、类型等。现在,如果电影类型是例如动画,我只希望将这一种类型添加到db中。现在我可以使用isset来解决这个问题,但接下来我会为tyresnull设置db条目,我想避免这种情况。解决这个问题的最佳方法是什么?使用foreach循环?

  • Active Record 提供了一个面向对象的接口, 用以访问和操作数据库中的数据。Active Record 类与数据库表关联, Active Record 实例对应于该表的一行, Active Record 实例的属性表示该行中特定列的值。 您可以访问 Active Record 属性并调用 Active Record 方法来访问和操作存储在数据库表中的数据, 而不用编写原始 SQL 语句。

  • 我在类方法中使用active record import gem来导入从csv文件读取的列表数组,如下代码所示: 根据active record导入文档,我正在尝试将列表的标题和VIN字段设置为冲突目标。如果列表的VIN字段发生冲突,我希望进行更新,而不是创建。 但是现在,每次我运行CSV上传时,它都在从isting.import创建一个新的列表,而不检查它是否冲突。 我哪里出错了?

  • 我已经两天没有解决AR协会的问题了。我知道有一个简单的解决办法,但我想不出来。 我有两个模型,产品和用户,应该联系在一起。一个产品应该属于一个用户,一个用户应该有很多产品。我没有在控制器中设置用户变量,所以我选择了habtm关联。以下是模型: User.rb Product.rb products\u控制器。rb型 _形式。html。erb公司 架构。rb型 所以,即使我知道,用户和产品之间应该有