Log4J2 中不同追加器上的不同级别(包括自定义级别)



我想将我的 2 个类中的特殊消息记录到数据库中,并且还想在控制台上写入我的所有程序日志。为了实现这一点,我为 JDBC 追加器定义了一个 intLevel=50 的自定义级别(managerLogsLevel(,但我无法设置 log4j2.xml 来达到我的确切目的。

<CustomLevels>
<CustomLevel name="managerLogsLevel" intLevel="50" />
</CustomLevels>
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{yyyy-MMM-dd hh:mm:ss a } %level %c - %m %n" />
</Console>
<JDBC name="MySQLDatabase" tableName="phonebook_finalproject.eventlog">
<ConnectionFactory class="ir.maktabsharif.core.base.ConnectionFactory"
method="getConnection" />
<Column name="time" isEventTimestamp="true" />
<Column name="name" pattern="%logger" />
<Column name="level" pattern="%level" />
<Column name="description" pattern="%m" />
</JDBC>
</Appenders>
<Loggers>
<Root level="info" additivity="false">
<AppenderRef ref="Console" level="info" />
</Root>
<Logger name="org.hibernate" level="warn" />
<Logger name="ir.maktabsharif.api" level="managerLogsLevel" >
<AppenderRef ref="MySQLDatabase" level="managerLogsLevel" />
<AppenderRef ref="Console" level="info" />
</Logger>
</Loggers>

正如我在评论中提到的,我认为自定义日志级别不是您的用例的最佳解决方案:

我想将我的 2 个类中的特殊消息记录到 DB 中,并且还想在控制台上写入我的所有程序日志

我在评论中提出了两种不同的解决方案,但我想提供更完整的答案以及一些示例。请注意,这些示例不会将消息发送到数据库,但您可以根据需要修改追加程序。这些示例只是为了说明您可以使用的一些常规技术。

下面的第一个 java 类将使用Marker/MarkerFilter方法:

package example;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.Marker;
import org.apache.logging.log4j.MarkerManager;
public class SomeClass {
private static final Logger LOG = LogManager.getLogger();
private static final Marker SPECIAL_MESSAGE = MarkerManager.getMarker("SPECIAL_MESSAGE");   
public static void main(String[] args){
if(LOG.isDebugEnabled())
LOG.debug("This is some debug!");
LOG.info("Here's some info!");
//To log a special kind of message use the same logger but include the marker
LOG.info(SPECIAL_MESSAGE, "Something special goes here");
LOG.error("Some error happened!");
}
}

下一个类(如下(将使用"特殊记录器"方法:

package example;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
public class SomeClass2 {
private static final Logger LOG = LogManager.getLogger();
private static final Logger SPECIAL_LOG = LogManager.getLogger("SPECIAL_LOGGER");   
public static void main(String[] args){
if(LOG.isDebugEnabled())
LOG.debug("This is some debug!");
LOG.info("Here's some info!");
//To log a special kind of message use the special logger
SPECIAL_LOG.info("Something special goes here");
LOG.error("Some error happened!");
}
}

以下是 log4j2.xml 文件,其中包含两种方法的配置:

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Appenders>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</Console>
<File name="SpecialAppender" fileName="logs/special.log" immediateFlush="false"
append="false">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
<MarkerFilter marker="SPECIAL_MESSAGE" onMatch="ACCEPT" onMismatch="DENY"/>
</File>
<File name="SpecialAppenderNoFilter" fileName="logs/specialNoFilter.log" immediateFlush="false"
append="false">
<PatternLayout pattern="%d{yyy-MM-dd HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
</File>
</Appenders>
<Loggers>
<Root level="debug">
<AppenderRef ref="Console" />
</Root>
<!-- This logger uses the MarkerFilter method -->
<Logger name="example.SomeClass" level="debug">
<AppenderRef ref="SpecialAppender" />
</Logger>
<!-- The following logger is used for the "special logger" method -->
<Logger name="SPECIAL_LOGGER" level="info">
<AppenderRef ref="SpecialAppenderNoFilter" />
</Logger>
</Loggers>
</Configuration>

这两种方法非常相似,但确实存在差异:

  1. Marker解决方案要求您创建一个Marker对象,而记录器解决方案需要第二个Logger对象。
  2. Marker解决方案的输出仍为您提供有意义的记录器名称,而记录器解决方案需要一个常规记录器名称,该名称不会提供有关生成消息的位置的任何线索。
  3. Marker解决方案需要在配置文件中MarkerFilter,而记录器解决方案需要在配置中具有专用Logger

正如我在评论中提到的,另一个考虑因素是在必要时将日志记录策略迁移到另一个日志记录框架是多么容易。如果要迁移到的框架不支持标记概念,则Marker解决方案可能会更加困难。看起来 slf4j 确实支持标记,因此如果您移动到具有 slf4j 绑定的框架,那么标记很有可能仍然有效。

最新更新