Flink Task 日志文件隔离

任务在启动时会先通过 MdcUtils 启动一个 slf4j 的 MDC 环境,然后将 jobId 添加到 slf4j 的 MDC 容器中,随后任务输出的日志都将附带 joid。

MDC 介绍如下:

MDC ( Mapped Diagnostic Contexts ),它是一个线程安全的存放诊断日志的容器。

Logback设计的一个目标之一是对分布式应用系统的审计和调试。在现在的分布式系统中,需要同时处理很多的请求。如何来很好的区分日志到底是那个请求输出的呢?我们可以为每一个请求生一个logger,但是这样子最产生大量的资源浪费,并且随着请求的增多这种方式会将服务器资源消耗殆尽,所以这种方式并不推荐。

一种更加轻量级的实现是使用MDC机制,在处理请求前将请求的唯一标示放到MDC容器中如sessionId,这个唯一标示会随着日志一起输出,以此来区分该条日志是属于那个请求的。并在请求处理完成之后清除MDC容器。

MDC类仅包含静态方法。它允许开发人员将信息放置在诊断上下文 中,随后可以由某些 logback 组件检索这些信息。 MDC每个线程 为基础管理上下文信息。通常,在开始服务新的客户端请求时,开发人员会将相关的上下文信息(例如客户端 ID、客户端的 IP 地址、请求参数等)插入到MDC中。如果配置正确,Logback 组件将自动在每个日志条目中包含此信息。

更具体的使用方法和原理可以查看官方手册: https://logback.qos.ch/manual/mdc.html

原理简单来说则是日志框架会将标记信息存放到 ThreadContextMap 中,而在每次打印日志时都会从 ThreadContextMap中获取 标记信息并附加到日志中。

ThreadContextMap 默认实现类为 DefaultThreadContextMap,可以看到如果要让所有线程都生效,那么还需要在 Properties 中设置 isThreadContextMapInheritable 配置。

java 复制代码
public class DefaultThreadContextMap implements ThreadContextMap, ReadOnlyStringMap {
    public static final String INHERITABLE_MAP = "isThreadContextMapInheritable";
    private static boolean inheritableMap;
    static {
        init();
    }
    static ThreadLocal<Map<String, String>> createThreadLocalMap(final boolean isMapEnabled) {
        if (inheritableMap) {
            return new InheritableThreadLocal<Map<String, String>>() {
                @Override
                protected Map<String, String> childValue(final Map<String, String> parentValue) {
                    return parentValue != null && isMapEnabled //
                    ? Collections.unmodifiableMap(new HashMap<>(parentValue)) //
                            : null;
                }
            };
        }
        return new ThreadLocal<>();
    }

    static void init() {
        inheritableMap = PropertiesUtil.getProperties().getBooleanProperty(INHERITABLE_MAP);
    }
}

了解到MDC 类只包含静态方法,而 Task 会以 "flink-job-id" 作为 key 将 jobid 存放进 MDC 中,这样的话日志隔离也就好办了。

我们只需要自定义一个 Appender 并使用该 Appender,而该 Appender 通过 "flink-job-id" key 获取 MDC 中的 jobId,然后输出到以 jobId 命名的日志中,这样即实现了作业日志文件隔离。

Flink 日志记录:https://nightlies.apache.org/flink/flink-docs-release-1.20/docs/deployment/advanced/logging/

相关推荐
小Ti客栈4 小时前
Spring Boot 集成 Springdoc-OpenAPI 与 Knife4j实现接口文档与可视化调试
java·spring boot·后端
Ai拆代码的曹操5 小时前
Spring 事务 REQUIRES_NEW 嵌套调用:连接池翻倍的秘密
java·后端·spring
动恰客流统计5 小时前
ReID边缘计算视觉统计:餐饮店客流增长的数字化破局路径
java·大数据·运维·人工智能
Ivanqhz6 小时前
Rust &‘static str浅析
java·前端·javascript·rust
weixin_419658319 小时前
Docker 搭建 Jenkins 服务
java·docker·jenkins
captain3769 小时前
多线程线程安全问题
java·java-ee
CoderYanger9 小时前
A.每日一题:1979. 找出数组的最大公约数
java·程序人生·算法·leetcode·面试·职场和发展·学习方法
灵极海10 小时前
LangChain4j RAG 实战完整指南:从入门到踩坑
java·langchain
yaoxin52112310 小时前
476. Java 反射 - 调用方法
java·开发语言
Ivanqhz10 小时前
Rust Lazy浅析
java·javascript·rust