springboot使用logback mdc设置日志参数

该博客介绍了如何利用Mapped Diagnostic Context(MDC)在Spring Boot应用中跨层传递日志参数,以便在日志中关联请求信息。通过在Controller层设置MDC上下文,并在Service层中自动携带这些参数,可以更方便地进行问题定位。示例代码展示了如何设置和使用MDC,以及在logback.xml中配置日志格式,确保参数在日志输出中显示。
摘要由CSDN通过智能技术生成

在一个服务内的业务处理通常需要不同类的共同协作来完成,比如controller接收请求,校验参数,然后调用service类的业务处理方法,而service又需要调用持久层的方法来读取和写入数据,为了在日志中,将各个部分的调用参数关联起来,特别是在出现错误或失败的时候,能够快速地定位出现错误的业务信息,可以借助于mdc机制。

1. 设置mdc信息

package com.demo.order.controller;

import com.demo.order.service.OrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


import java.util.HashMap;
import java.util.Random;


@RestController
@RequestMapping("/order")
public class OrderController {

    Logger log = LoggerFactory.getLogger(getClass());
    
    @Autowired
    OrderService orderService;    
    
    @RequestMapping("/add")
    public String add()
    {
        HashMap<String, String> map = new HashMap<String, String>();

        Random rnd = new Random();
        int i = rnd.nextInt(100000);

        map.put("sessionId", "12" + i);

        i = rnd.nextInt(100);
        map.put("userId", "test" + i);

        i = rnd.nextInt(1000);
        map.put("mobile", "138000" + i);

        MDC.setContextMap(map);

        log.info("控制层接收到请求");

        log.info("控制层参数校验");

        log.debug("控制层调用服务层");

        orderService.getOrder();

        log.info("控制层处理完成");

        MDC.clear();

        return "Hello world!";
    }
}

这里只是为了演示方便,实际项目中,可以将参数获取和写入mdc的功能通过拦截器实现。

MDC.setContextMap(),将参数名和参数值以map的形式保存到mdc中。

MDC.put(),可以每次设置一个参数名和参数值。

这里设置的属性名称应与logback.xml文件中的日志pattern中的属性名称一致。

<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] [%X{userId}] [%X{sessionId}] [%X{mobile}] %msg - %logger{20}[%method,%line]%n" />

2. 使用mdc中的信息

package com.demo.order.service;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;


@Service
public class OrderService {

    Logger log = LoggerFactory.getLogger(getClass());

    public String getOrder()
    {
        log.info("服务层接收到请求");

        log.info("服务层调用持久层");

        log.info("服务层执行业务处理");

        log.debug("服务器层输出调试信息");

        log.info("服务层完成业务处理");

        return "123456789";
    }
}

3. 执行测试

通过浏览器访问,查看日志输出。

2022-03-04 14:57:31 INFO  [http-nio-8010-exec-1] [test19] [1251387] [138000270] 控制层接收到请求 - c.f.o.c.OrderController[add,168]
2022-03-04 14:57:31 INFO  [http-nio-8010-exec-1] [test19] [1251387] [138000270] 控制层参数校验 - c.f.o.c.OrderController[add,170]
2022-03-04 14:57:31 DEBUG [http-nio-8010-exec-1] [test19] [1251387] [138000270] 控制层调用服务层 - c.f.o.c.OrderController[add,172]
2022-03-04 14:57:31 INFO  [http-nio-8010-exec-1] [test19] [1251387] [138000270] 服务层接收到请求 - c.f.o.s.OrderService[getOrder,17]
2022-03-04 14:57:31 INFO  [http-nio-8010-exec-1] [test19] [1251387] [138000270] 服务层调用持久层 - c.f.o.s.OrderService[getOrder,19]
2022-03-04 14:57:31 INFO  [http-nio-8010-exec-1] [test19] [1251387] [138000270] 服务层执行业务处理 - c.f.o.s.OrderService[getOrder,21]
2022-03-04 14:57:31 DEBUG [http-nio-8010-exec-1] [test19] [1251387] [138000270] 服务器层输出调试信息 - c.f.o.s.OrderService[getOrder,23]
2022-03-04 14:57:31 INFO  [http-nio-8010-exec-1] [test19] [1251387] [138000270] 服务层完成业务处理 - c.f.o.s.OrderService[getOrder,25]
2022-03-04 14:57:31 INFO  [http-nio-8010-exec-1] [test19] [1251387] [138000270] 控制层处理完成 - c.f.o.c.OrderController[add,176]

可以看到在controller中设置的mdc参数,不管是在controller,还是在service中,输出日志信息时,都自动输出了对应的参数信息。

4. logback.xml配置

<!-- 日志输出格式 -->
<property name="log.pattern" value="%d{yyyy-MM-dd HH:mm:ss} %-5level [%thread] [%X{userId}] [%X{sessionId}] [%X{mobile}] %msg - %logger{20}[%method,%line]%n" />

输出mdc参数的写法为:%X{mobile},其中的字符串为设置的mdc属性名。

由于springboot默认支持logback,所以并不需要单独添加maven依赖。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿20

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值