Java 配置多个log4j2记录器

Java 配置多个log4j2记录器,java,xml,logging,configuration,log4j2,Java,Xml,Logging,Configuration,Log4j2,我想将系统日志与用户日志分开。系统日志是开发人员和维护人员将看到的东西。用户日志向用户提供系统信息,但不提供所有技术细节。我想将不同的日志消息存储在不同的文件中,一个用于技术人员,一个用于用户 我研究了许多选项,包括自定义级别和过滤器。我可以在消息的开头添加一个关键字,过滤器可以用来识别用户消息。我正在尝试为使用标准错误级别的用户消息添加一个单独的记录器 我已经编写了一个简单的测试演示程序。它创建2个记录器,然后生成一些错误消息 package demo; import java.io.IOEx

我想将系统日志与用户日志分开。系统日志是开发人员和维护人员将看到的东西。用户日志向用户提供系统信息,但不提供所有技术细节。我想将不同的日志消息存储在不同的文件中,一个用于技术人员,一个用于用户

我研究了许多选项,包括自定义级别和过滤器。我可以在消息的开头添加一个关键字,过滤器可以用来识别用户消息。我正在尝试为使用标准错误级别的用户消息添加一个单独的记录器

我已经编写了一个简单的测试演示程序。它创建2个记录器,然后生成一些错误消息

package demo;
import java.io.IOException;
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Logdemo {
private final static Logger logger = LogManager.getLogger();
private final static Logger userLog = LogManager.getLogger("demo.userMsg");

public static void main(String[] args) throws IOException {
    try {
        ((Object) null).toString();
    } catch (Exception e) {
        logger.error("error message", e);
    }
    try {
        ((Object) null).toString();
    } catch (Exception e) {
        logger.fatal( "User level Red message" ,e);
    }
    try {
        ((Object) null).toString();
    } catch (Exception e) {
        userLog.error( "User level Amber message" ,e); 
    }
    logger.info("Errors Logged");
    userLog.info("Lunch is served.");
  }
}
在配置文件中,我有:

    <Loggers>
        <Root level="all">
            <AppenderRef ref="RollingFile" level="ALL"/>
            <AppenderRef ref="Console" level="ALL"/>
        </Root>
        <userMsg name="demo.userMsg" level = "all">
            <AppenderRef ref="UserMsgFile" level="ALL"/>
        </userMsg> 
    </Loggers>
</Configuration>
所有异常消息都会写入控制台,包括userLog的消息。所以我知道两个伐木工人都在工作。记录器appender写入到文件OK。userLog logger没有创建任何文件,它使用几乎相同的appender

似乎我没有正确地命名一些东西,以允许log4j2找到记录器。我尝试了各种命名组合,以使其正确,但我不知道问题是什么

另一件我还没有做的事情是在不同的类中使用userLog记录器。我不需要知道用户日志消息是由哪个类生成的,所以我希望在所有类中使用相同的记录器名称,而不使用类标识符。我想我做不到

因此,我的问题是: 我在配置文件中犯了什么错误? 编辑: 下面的配置条目有效。这给了两个伐木工人。有两个问题。一个是记录器的名称是包名。另一个原因是我没有正确使用Logger这个词

    <Loggers>
    <Logger name="demo" level="all">  <!-- name = package name -->
        <AppenderRef ref="UserLogFile" level="ALL" />
    </Logger>
    <Root level="all">
        <AppenderRef ref="Console" level="ALL"/>
        <AppenderRef ref="SystemLogFile" level="ALL"/>
    </Root>
</Loggers>
我必须在每个类的记录器初始化中包含类名吗? 编辑:我需要包含包名。我花了一段时间才弄明白

我遇到的另一个问题是打开log4j2的调试消息。这是通过以下方式实现的:

    <Configuration status="WARN">  <!-- to debug, set status="TRACE"  -->

我改变了我的方法。我已将标记功能与添加的记录器一起使用。在日志消息中添加标记允许我使用不同的appender来处理用户消息。 示例代码如下所示:

import java.io.IOException;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.MarkerManager;
import org.apache.logging.log4j.Marker;

    public class Logdemo {

    private final static Logger logger = LogManager.getLogger();
    static final Marker usrMkr = MarkerManager.getMarker("USR");

    public static void main(String[] args) throws IOException {
        logger.info("logger starting...");

        try {
            ((Object) null).toString();
        } catch (Exception e) {
            logger.fatal( usrMkr,"User message" );
        }
        try {
            ((Object) null).toString();
        } catch (Exception e) {
            logger.debug( "Debug error message" ,e); 
        }
        logger.info("Errors Logged");
      }
    }
配置文件的相关部分如下所示:

     <RollingFile
       name="UserLogFile" 
       fileName="${basePath}/UserMsg.log"
       immediateFlush="false"
       filePattern="logs/$${date:yyyy-MM}/user-%d{MM-dd-yyyy}-%i.log">
       <MarkerFilter marker="USR" onMatch="ACCEPT" onMismatch="DENY"/>
     </RollingFile>
</Appenders>

<Loggers>
    <Logger name="demo" level="all">
        <AppenderRef ref="UserLogFile" level="ALL"/>
    </Logger>
    <Root level="all">
        <AppenderRef ref="Console" level="ALL"/>
        <AppenderRef ref="RollingFile" level="ALL"/>

    </Root>

</Loggers>
我使用添加的MarkerFilter命令创建了一个appender。 我将记录器指向appender,以将标记的消息转移到单独的文件中。
请注意,为了简洁起见,我已经将xml文件的大块内容砍掉了。

Hi dazz,您的两种方法都应该有效。我注意到您说过,在日志消息中添加一个标记允许我使用不同的appender来处理用户消息,但是不使用标记也可以做到这一点。我认为使用标记是正确的,因为如果不使用标记,则必须创建多个记录器,而且我发现可读性较差。另外,如果使用演示记录器的唯一原因是分配UserLogFile appender,那么您实际上不需要此记录器。因为你的appender有一个MarkerFilter,你可以把它分配给根记录器,它应该以同样的方式工作。Hi D.B在经历了记录器学习曲线的陡峭爬升之后,还有很长的路要走,我编写的代码完成了这项工作。我可以看出,演示记录器是不需要的,但我认为有了它,在几年后,当我忘记我做了什么的时候,我将更容易阅读代码。
     <RollingFile
       name="UserLogFile" 
       fileName="${basePath}/UserMsg.log"
       immediateFlush="false"
       filePattern="logs/$${date:yyyy-MM}/user-%d{MM-dd-yyyy}-%i.log">
       <MarkerFilter marker="USR" onMatch="ACCEPT" onMismatch="DENY"/>
     </RollingFile>
</Appenders>

<Loggers>
    <Logger name="demo" level="all">
        <AppenderRef ref="UserLogFile" level="ALL"/>
    </Logger>
    <Root level="all">
        <AppenderRef ref="Console" level="ALL"/>
        <AppenderRef ref="RollingFile" level="ALL"/>

    </Root>

</Loggers>