如何使用log4j2在库中登录到特定文件路径?

问题描述 投票:0回答:1

我有一个 Java 库 (SDK),它将作为 JAR 在其他应用程序中使用。我现在正在使用 log4j2 和 SLF4J 进行日志记录,但是当其他应用程序(也使用 log4j2.xml)使用我的库时,不会创建日志。我需要能够使用特定文件名(滚动附加程序)登录到特定目录和路径。

我尝试过搜索这方面的信息,似乎使用 SLF4J 作为外观是可行的方法,但无论如何我找不到提供我自己的文件路径、格式和配置。

这样做是不好的做法吗?我在 C#、TypeScript 和其他所有语言中都这样做,我似乎只在 Java 中遇到这个问题。

据我了解,SLF4J 为使用我的库的开发人员提供了一个外观来使用他们自己的日志框架。如果我依赖实现我的库的开发人员来包含日志记录库,我如何保证我的日志正在生成?我需要能够在现场解决问题,如果报告错误,我需要能够查看日志以查看出了什么问题。

我是否在此用例中使用了错误的日志记录?有什么方法可以为 log4j2 指定一个不被使用应用程序的配置覆盖的不同配置文件吗?

澄清一下,我有一个“库”,它实际上只是一个 API,其中包含模糊和简化 WebSocket 调用的方法。该 API 将可供其他应用程序使用。我需要记录到特定的文件路径,以确保如果出现问题,我可以通过日志文件进行跟踪,找出问题的根源。我不能依赖 API 的使用者来实现他们自己的日志记录实现并将其配置到特定路径。我有一个 log4j2.xml,但如果使用库也使用自己的 log4j2.xml,则它似乎会被覆盖。

在图像中,蓝色和橙色 JAR 有不同的 log4j2.xml 文件。我无法控制橙色,只能控制蓝色。

请帮忙。

java log4j2 slf4j class-library
1个回答
0
投票

经过一些有用的评论后,我相信解决方案是使用 ConfigurationFactory 指定单独的“私有”LoggerContext 和自定义 log4j2 配置文件作为 ConfigurationSource。不幸的是,似乎没有很多关于这样做的信息。

这对我有用,在我的记录器的构造函数中,我首先检查配置文件是否存在,如果不存在,我调用我的静态 createConfiguration 方法(如下)。如果配置文件存在,我创建一个 ConfigurationFactory 并将其指向我指定的配置文件,然后使用该配置文件作为 ConfigurationSource 和一个新的“私有”LoggerContext 创建自定义配置:

protected CustomLogger() throws IOException {
   // Check if the Configuration file exists
   if (!configFile.isFile()) {
        createConfiguration();
   }

   // Get instance of configuration factory on Startup
   ConfigurationFactory factory = XmlConfigurationFactory.getInstance();

   // Create a "Private" LoggerContext instance
   LoggerContext context = new LoggerContext("PrivateLoggerContext");

   // Locate the source of your configuration
   ConfigurationSource configurationSource = new ConfigurationSource(new 
   FileInputStream(new File(configFilePath)));

   // Get a reference from configuration
   Configuration configuration = factory.getConfiguration(context, configurationSource);

   // Start logging system
   context.start(configuration);

   // Get a reference for logger
   logger = context.getLogger("com.packagename");

   logger.info("TEST");
}

在我的记录器类中,我有一个静态的“createConfiguration”方法,它以编程方式生成配置文件并将其输出到我所需的文件路径(在本例中为“C:/ProgramData/PackageName”,但是我建议允许您的库用户指定路径并仅提供默认值):

public static void createConfiguration() throws IOException {
    // Create the configuration directory if it doesn't exist
    new File("C:/ProgramData/PackageName").mkdirs();

    // Create a ConfigurationBuilder to build out the configuration
    ConfigurationBuilder<BuiltConfiguration> builder = ConfigurationBuilderFactory.newConfigurationBuilder();

    AppenderComponentBuilder consoleAppender = builder.newAppender("console", "Console");
    LayoutComponentBuilder patternLayout = builder.newLayout("PatternLayout").addAttribute("pattern", "%d{MM/dd/yyyy HH:mm:ss.SSSS} [%t] %-5level %logger - %msg%n");
    consoleAppender.add(patternLayout);

    builder.add(consoleAppender);

    LoggerComponentBuilder logger = builder.newLogger("com.packagename", Level.DEBUG);
    logger.addAttribute("additivity", false);
    logger.add(builder.newAppenderRef("console"));

    builder.add(logger);

    builder.writeXmlConfiguration(new FileOutputStream(configFile));
}

最后,在我的库的构造函数中,我像往常一样创建我的记录器:

public Library() {
    Logger logger = new CustomLogger();
}

我希望这个答案对将来可能遇到此问题的人有所帮助,如果有人对此处的代码有任何建议或意见,请随时发表评论。如果需要的话我会编辑。

此答案参考:

© www.soinside.com 2019 - 2024. All rights reserved.