利用MDC在日志中打印访客ip

本文介绍如何在Java项目中利用MDC与logback集成来记录客户端IP地址的方法。通过在代码中设置MDC并配置logback.xml文件,可以在日志中自动包含IP等上下文信息。


必要条件:

1.项目中具备MDC的jar包(  本人使用的是org.slf4j.MDC  )

2.项目中使用了logback.xml配置日志控制信息


实现:

1. 在java代码中 :

MDC.put("remortIP", IPUtil.getRemortIP(request));  //使用MDC类将Ip设置到logback中,IPUtil类是获取原创ip的工具类,附件中会带上


2.在logback.xml中,为需要打印ip的日志输出,也就是<appender>标签中的<pattern>标签值加上 %X{remortIP}


<pattern>%X{remortIP} </pattern> /**其它配置项自己填写,这里作为举例,只填写了remortIP**/


3.运行项目,查看对应的输出日志,成功打印Ip信息则成功。


注意事项:

1. MDC.put引用的jar包,一定要和项目中logback用的jar是相同的 , 本人用的是org.slf4j的包


2.MDC.put的key值,一定要和<pattern>标签中引用的key值是一致的,这里举例用的都是remortIP

### 日志上下文(MDC)无法输出的解决方案 在 Java 中,使用 MDC(Mapped Diagnostic Context)进行日志追踪时,可能会遇到日志信息无法正常输出的问题。该问题通常与线程上下文管理、日志框架配置或异步任务执行有关。 #### 1. 确保正确设置 MDC 上下文 MDC 是基于线程的上下文存储机制,因此必须确保在日志打印前调用 `MDC.put()` 设置相关键值对。例如: ```java MDC.put("requestUri", "/api/test"); logger.info("处理请求"); ``` 如果未正确设置键值,或者在日志格式中引用了未设置的键,则不会输出预期内容[^4]。 #### 2. 检查日志格式配置 日志格式需要显式引用 `%X{key}` 来输出 MDC 内容。例如,在 Logback 配置文件中,应包含类似以下模式: ```xml <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %X{requestUri} %msg%n</pattern> ``` 若格式中缺少 `%X{key}` 或拼写错误,将导致 MDC 内容不显示[^1]。 #### 3. 处理线程池或异步任务中的 MDC 丢失问题 MDC 数据是绑定到当前线程的,当使用线程池或异步任务(如 `@Async`)时,子线程不会继承父线程的 MDC 上下文,从而导致日志信息缺失。为了解决此问题,可以采用如下方式: - **使用 TransmittableThreadLocal** 使用阿里开源的 [TransmittableThreadLocal](https://github.com/alibaba/transmittable-thread-local) 库,可实现在线程池中传递 MDC 上下文。 ```java ExecutorService executor = TtlExecutors.getTtlExecutorService(Executors.newFixedThreadPool(10)); ``` - **自定义 Task 包装器** 在提交任务前手动复制 MDC 到子线程: ```java Map<String, String> contextMap = MDC.getCopyOfContextMap(); executor.submit(() -> { if (contextMap != null) { MDC.setContextMap(contextMap); } try { // 执行任务逻辑 } finally { MDC.clear(); } }); ``` 这些方法可有效解决线程切换导致的 MDC 数据丢失问题[^4]。 #### 4. 检查日志级别和输出策略 根据日志规范,需合理设置日志级别。生产环境中应避免输出 `DEBUG` 级别日志,同时控制 `INFO` 和 `WARN` 的输出量,以防止因日志过多影响系统性能。例如: ```yaml logging: level: com.example: INFO ``` 若日志级别设置过高(如 `ERROR`),可能导致部分日志被过滤而不输出,造成误判[^2]。 #### 5. 确保 MDC 清理操作 每次请求结束后,应及时清理 MDC 上下文,避免线程复用导致数据污染: ```java try { MDC.put("requestUri", uri); // 处理请求 } finally { MDC.clear(); } ``` 未及时清除上下文可能引发后续请求的日志记录异常。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值