[英]Configuring multiple log4j2 loggers
我想将系统日志与用户日志分开。 系统日志是开发人员和维护人员将要查看的内容。 用户日志为用户提供了系统信息,而没有所有技术细节。 我想将不同的日志消息存储在不同的文件中,一个用于技术人员,一个用于用户。
我研究了许多选项,包括自定义级别和过滤器。 我可以在消息的开头添加一个关键字,过滤器可以使用该关键字来识别用户消息。我正在尝试为使用标准错误级别的用户消息添加一个单独的记录器。
我已经编写了一个简单的演示程序进行测试。 它创建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消息)均写入控制台。 所以我知道两个记录器都在工作。 记录器附加程序将文件写入OK。 使用几乎相同的附加程序的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文件的大块。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.