java - 配置多个 log4j2 记录器

标签 java xml logging configuration log4j2

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

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

我写了一个简单的演示程序用于测试。它创建 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>

由此,我从 NetBeans 收到以下错误消息:

run:
2017-09-18 22:20:13,933 main ERROR Error processing element UserMsgFile [Appenders: null]): CLASS_NOT_FOUND
2017-09-18 22:20:13,936 main ERROR Error processing element userMsg  ([Loggers: null]): CLASS_NOT_FOUND
22:20:14.038 [main] INFO  demo.Logdemo - logger starting...
22:20:14.040 [main] ERROR demo.Logdemo - error message

所有异常消息都会写入控制台,包括用户日志的消息。所以我知道两个记录器都在工作。记录器附加程序写入文件正常。 userLog 记录器不会创建任何文件,它使用几乎相同的附加程序。

看来我没有正确命名某些内容以允许 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>

我是否必须在每个类的 Logger 启动中包含类名称?
编辑:我需要包含包名称。这花了我一段时间才弄清楚。

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

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

最佳答案

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

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 命令。 我将记录器指向附加程序,以将标记的消息转移到单独的文件中。 请注意,为了简洁起见,我已经删除了 xml 文件的大部分内容。

关于java - 配置多个 log4j2 记录器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46277529/

相关文章:

python - 在各种操作系统中保存日志时的最佳做法是什么?

java - 验证有向图和无向图的 DFS 复杂性

android - 无法在 Android Studio 中解析 R,但应用编译正常

c# - 删除 XML 中的流氓符号的最佳方法是什么?

Python 日志记录 : how to save class attributes values in the log file

git - 哪些 Git 提交统计信息很容易提取

java - 将maven项目与java项目结合起来

java - API或任何其他方式使用Java程序获取Kafka服务器的堆大小

java - 如果我对输出的解释是正确的

.net - 没有命名空间的 SelectSingleNode