1、Marker介绍

Marker用于给日志事件添加一个额外的、不携带值的分类标签,用于标识日志消息的某种特性或类别。它是一种静态的、逻辑上的标记,不随线程变化。

Marker可以用来区分不同类型的日志事件,比如错误日志、安全审计日志、性能监控日志等,使得在日志分析时能够更容易地过滤和识别出感兴趣的日志条目。

Marker是全局的、可共享的,可以在多个地方重复使用,不绑定到任何特定的执行线程或上下文。

2、MDC与Marker对比

  • 适用场景:当你需要在日志中记录与每个请求或操作相关的具体数据时,MDC非常有用;而当你想要对日志事件进行逻辑分类或过滤时,Marker是更好的选择。
  • 数据类型:MDC存储的是带有具体值的数据(键值对),而Marker只是一种逻辑标记,没有携带具体数据值。
  • 作用范围:MDC作用于线程级,与线程上下文关联;Marker则是全局性的,用于整个应用程序的日志分类。

3、使用示例

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.Marker;
import org.slf4j.MarkerFactory;

public class MarkerUsageExample {

    private static final Logger logger = LoggerFactory.getLogger(MarkerUsageExample.class);
    private static final Marker SECURITY_MARKER = MarkerFactory.getMarker("SECURITY");

    public static void main(String[] args) {
        // 普通信息日志
        logger.info("Application is starting up...");

        // 使用SECURITY_MARKER记录安全相关的日志
        logger.info(SECURITY_MARKER, "User 'admin' logged in successfully.");
        
        // 其他日志记录...
    }
}

接着,假设我们使用Logback作为SLF4J的实现,可以在logback.xml中配置如何处理带有特定Marker的日志。例如,我们可以设定所有带有"SECURITY" Marker的日志都记录到一个单独的文件中,并设置为DEBUG级别。

<configuration>
    <!-- 默认日志记录 -->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <!-- 安全相关的日志记录 -->
    <appender name="SECURITY_FILE" class="ch.qos.logback.core.FileAppender">
        <file>security.log</file>
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %marker - %msg%n</pattern>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="STDOUT" />
    </root>

    <!-- 为带有SECURITY_MARKER的日志设置额外的处理 -->
    <logger name="org.example.MarkerUsageExample" level="debug">
        <appender-ref ref="SECURITY_FILE" />
        <filter class="ch.qos.logback.classic.filter.MarkerFilter">
            <marker>SECURITY</marker>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
    </logger>
</configuration>

在这个配置中,我们为名为"org.example.MarkerUsageExample"的包或类设置了额外的Appender(指向security.log文件),并且添加了一个MarkerFilter,该过滤器仅接受带有"SECURITY" Marker的日志,拒绝其他未标记或标记不同的日志条目。