当前位置: 首页 > 知识库问答 >
问题:

对多个类使用log4j2

陆安国
2023-03-14

这里的答案:https://stackoverflow.com/questions/7624895/how-to-use-log4j-with-multiple-classes#=是我找到的最好的答案。这已经是过去几年的想法了,现在有些事情已经不同了。

我的目标是在所有将消息打印到日志(控制台和文件)的java类中共享一个记录器。

我使用的是log4j2:http://logging.apache.org/log4j/2.x/manual/configuration.html

import org.apache.logging.log4j.Logger;

public class App {
    private static final Logger LOGGER = Logger.getLogger("GLOBAL");
    public static void main(){
        ...calling other classes
  }
}
import org.apache.logging.log4j.Logger;
public class secondClass {
    private final Logger LOGGER = Logger.getLogger("GLOBAL");
    public void writeLog(){
      LOGGER.log(Level.INFO, "A simple string");
  }
}
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="warn">
    <Properties>
        <Property name="basePath">/var/log</Property>
    </Properties>

    <Appenders>
        <RollingFile name="fileLogger" fileName="${basePath}/myApp.log" filePattern="${basePath}/myApp-%d{yyyy-MM-dd}.log">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>

       <Console name="console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="java.util.logging.Logger" level="ALL" additivity="true">
            <appender-ref ref="fileLogger" level="ALL" />
        </Logger>
        <Root level="ALL" additivity="false">
            <appender-ref ref="console" />
        </Root>
    </Loggers>
</Configuration>

我(或多或少)知道我应该使用LogManager,事实是我应该将其称为:

private static final Logger logger = LogManager.getLogger(MyApp.class);

或者,在main()中,可能如下所示:

private static Logger LOGGER = null;

@BeforeClass
public static void setLogger() {
    System.setProperty("log4j.configurationFile","log4j.xml");
    LOGGER = LogManager.getLogger();
}

因为,我相信,使用LogManager我可以将日志指向xml文件以获得其设置。但是当我构建并运行它时,CLI rage在第一个日志时退出,报告:异常出现在myapp.modules.database. (database.java:67) 的线程“main”java.lang.NullPointerException中

..和许多其他搜索结果都超过了6年。

pom.xml:

<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-api</artifactId>
    <version>2.10.0</version>
</dependency>
<dependency>
    <groupId>org.apache.logging.log4j</groupId>
    <artifactId>log4j-core</artifactId>
    <version>2.10.0</version>
</dependency>

共有1个答案

鲜于致远
2023-03-14

您在几个层面上是错误的:您将JDK的记录器与log4j2的记录器混合在一起,您没有记录到几个追加器,等等。

以下是您应该做的:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.example</groupId>
    <artifactId>log4j2test</artifactId>
    <version>0.1</version>
    <packaging>jar</packaging>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-api</artifactId>
            <version>2.10.0</version>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.10.0</version>
        </dependency>
    </dependencies>
</project>

这基本上是你唯一没有错误的地方。

package so47656300;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class App {

  private static final Logger logger = LogManager.getLogger(App.class);

  public static void main(String[] args) {
    logger.info("App.main - starting");
    new SecondClass();
    logger.info("App.main - ending");
  }
}
package so47656300;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class SecondClass {

  private static final Logger logger = LogManager.getLogger(SecondClass.class);

  public SecondClass() {
    logger.info("SecondClass - starting");
    logger.info("SecondClass - ending");
  }
}
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
    <Properties>
        <Property name="basePath">/var/log</Property>
    </Properties>
    <Appenders>
        <RollingFile name="fileLogger" fileName="${basePath}/myApp.log" filePattern="${basePath}/myApp-%d{yyyy-MM-dd}.log">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
            </Policies>
        </RollingFile>

        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout pattern="[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} [%t] %c{1} - %msg%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Root level="INFO">
            <AppenderRef ref="console"/>
            <AppenderRef ref="fileLogger"/>
        </Root>
    </Loggers>
</Configuration>
    null
[INFO ] 2017-12-05 16:52:32.218 [main] App - App.main - starting
[INFO ] 2017-12-05 16:52:32.221 [main] SecondClass - SecondClass - starting
[INFO ] 2017-12-05 16:52:32.222 [main] SecondClass - SecondClass - ending
[INFO ] 2017-12-05 16:52:32.222 [main] App - App.main - ending
[INFO ] 2017-12-05 16:52:32.218 [main] App - App.main - starting
[INFO ] 2017-12-05 16:52:32.221 [main] SecondClass - SecondClass - starting
[INFO ] 2017-12-05 16:52:32.222 [main] SecondClass - SecondClass - ending
[INFO ] 2017-12-05 16:52:32.222 [main] App - App.main - ending
 类似资料:
  • 场景:一个应用程序有多个实体。每个实体表示一个数据库表。所有数据库表都有一个主键列,但列名不同。 实体示例: 服务类示例: 问题:如果我像下面这样声明dao接口: 将参数作为发送到JPararePository中,然后我的方法在服务类中运行良好。 但是Spring不允许在没有列的情况下创建类。所以我必须声明一个ID列。同样,在我的数据库中,每个表都有一个主列,但所有表的该列的名称是不同的。例如,表

  • 问题内容: 我是Hibernate的新手,必须支持使用Hibernate的现有应用程序。这是一个纯报表应用程序-无需插入/更新/删除-仅选择 我可以看到在同一类的多个字段中使用了@Id注释的现有POJO对象 我的理解是,对于复合主键-您需要使用@Embeddable和@EmbeddedId 但是,这没有在我的课程中定义,奇怪的是代码可以编译并正常运行 这是我的代码的示例: 在pojo中还有更多字段

  • 问题内容: 我的外观很好,似乎无法找出如何在一个jQuery选择器语句中选择与某些类匹配的所有元素,例如: 关于如何实现这一目标的任何想法?唯一的其他选择是 但是我正在使用很多类来执行此操作,因此它需要很多代码。 问题答案: 这应该工作: 您必须在$()的第一个参数中全部添加多个选择器,否则,您将为jQuery提供要在其中搜索的上下文,这不是您想要的。 这与您在CSS中所做的相同。

  • 问题内容: 在hibernate状态下,查询似乎有些困难。我正在两个表上执行内部联接。 产品表: 仓库表: 联接结果: 当我运行查询.. 因此,对于每个结果,我都会得到一个包含a 和a 的对象。 这是预期的。问题是hibernate将产品的ID和名称分配给仓库对象的ID和名称属性。在创建Warehouse项目时,好像联接结果中的前两列已经结束了。产品对象始终包含正确的数据。 关于解决此问题的任何建

  • 我可以重写,以便它将其数据存储在map中,但这意味着每个方法还需要传递另一个参数。变成,变成,看起来太难看了。操作还需要传递。 据我所知,另一种方法是创建一个存储库,它将管理的数据,并调用操作来重新初始化它。 这种方法的问题是,如果我们有两个(A和B),并且活动容器是A,因此包含在A中呈现的项,容器B仍然会监听的更改。如果检查是方法中的活动容器,我可以添加检查,但我不确定应该这样做。

  • 我正在使用Netty4创建一个需要为多个客户端连接提供服务的服务器。ServerBootstrap由父线程组和工作线程组构成。根据ServerBootStrap上的文档。group()方法it “为父(接收器)和子(客户端)设置EventLoopGroup。这些EventLoopGroup用于处理SocketChannel和Channel的所有事件和IO。” 据我所知,ParentExecutor