log4j2中不同appender上的不同级别(包括自定义级别)

时间:2018-06-06 22:56:47

标签: java log4j2

我想将我的两个类中的特殊消息记录到DB中,并且还想在控制台上编写我的所有程序日志。为了实现这一点,我为JDBC appender定义了一个自定义级别(managerLogsLevel),其中intLevel = 50,但我无法设置log4j2.xml来完成我的目的。我的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>

1 个答案:

答案 0 :(得分:1)

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

  

我想将我的两个班级中的特殊信息记录到DB中,并且还想在控制台上编写我的所有程序日志

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

下面的第一个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
  4. 正如我在评论中提到的,另一个考虑因素是在必要时将日志记录策略迁移到另一个日志记录框架是多么容易。如果您迁移到的框架不支持标记概念,Marker解决方案可能会更加困难。它似乎是slf4j does support markers所以如果你移动到一个具有slf4j绑定的框架,那么标记很可能仍然可以工作。