同一个项目中,一般包含controller/servlet、service、dao等。1笔记录的日志贯穿于controller、service、dao中,在并发情况下,那如何找出该笔日志?

可通过以下三种方式实现:

1、filter:依赖servlet容器

2、Interceptor:依赖spring

3、AOP:spring boot中,不能拦截servlet(我试过的,但可能也行)

以下时filter的实现。

首先,包结构:

代码实现:

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration debug="false">
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{requestId}] %p | %logger{20}.%M:%L - %m%n</pattern>
</encoder>
</appender>
<!-- TRACE < DEBUG < INFO < WARN < ERROR -->
<root level="INFO">
<appender-ref ref="console"/>
</root>
</configuration>

MdcLogEnhancerFilter

package com.ebc.slf4j.mdc.filter;
import java.io.IOException; import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse; import org.slf4j.MDC;
import org.springframework.stereotype.Component; import cn.hutool.core.lang.Console;
import cn.hutool.core.util.IdUtil;
@Component
public class MdcLogEnhancerFilter implements Filter {
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain)
throws IOException, ServletException {
MDC.put("requestId", IdUtil.objectId());
filterChain.doFilter(servletRequest, servletResponse);
MDC.remove("requestId");//否则内存溢出
//Console.log("======{}",MDC.get("requestId"));//输出null
}
}

Application

package com.ebc.slf4j.mdc;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.web.servlet.ServletComponentScan; @SpringBootApplication
@ServletComponentScan(basePackages="com.ebc.slf4j.mdc.servlet")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}

下边是业务类

M2Servlet

package com.ebc.slf4j.mdc.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
import com.ebc.slf4j.mdc.service.WelcomeService; @WebServlet("/M2Servlet")
@Slf4j
public class M2Servlet extends HttpServlet {
private static final long serialVersionUID = 1L;
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
log.info("进入了servlet");
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
WelcomeService welcomeService = (WelcomeService) wac.getBean("welcomeService");
String reStr = welcomeService.exec("遥远2");
log.info("service返回:{}",reStr);
}
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
this.doGet(request, response);
}
}

WelcomeService

package com.ebc.slf4j.mdc.service;

import lombok.extern.slf4j.Slf4j;

import org.springframework.stereotype.Service;

@Service
@Slf4j
public class WelcomeService {
public String exec(String name) {
log.info("service接收到:{}",name);
return "hello "+name;
}
}

执行:http://localhost:8080/M2Servlet

结果:

2019-01-22 11:22:03.900 [5c468c5bcbb014209e2ea828] INFO | c.e.s.m.s.M2Servlet.doGet:20 - 进入了servlet
2019-01-22 11:22:03.900 [5c468c5bcbb014209e2ea828] INFO | c.e.s.m.s.WelcomeService.exec:11 - service接收到:遥远2
2019-01-22 11:22:03.900 [5c468c5bcbb014209e2ea828] INFO | c.e.s.m.s.M2Servlet.doGet:24 - service返回:hello 遥远2

基于spring boot 和MDC实现 同一笔记录的日志跟踪实现--1.filter的更多相关文章

  1. 基于Spring Boot/Spring Session/Redis的分布式Session共享解决方案

    分布式Web网站一般都会碰到集群session共享问题,之前也做过一些Spring3的项目,当时解决这个问题做过两种方案,一是利用nginx,session交给nginx控制,但是这个需要额外工作较多 ...

  2. step6----->往工程中添加spring boot项目------->修改pom.xml使得我的project是基于spring boot的,而非直接基于spring framework

    文章内容概述: spring项目组其实有多个projects,如spring IO platform用于管理external dependencies的版本,通过定义BOM(bill of mater ...

  3. 基于Spring Boot的图片上传

    package com.clou.inteface.domain.web.user; import java.io.File; import java.io.IOException; import j ...

  4. Https系列之三:让服务器同时支持http、https,基于spring boot

    Https系列会在下面几篇文章中分别作介绍: 一:https的简单介绍及SSL证书的生成二:https的SSL证书在服务器端的部署,基于tomcat,spring boot三:让服务器同时支持http ...

  5. 基于Spring Boot,使用JPA动态调用Sql查询数据

    在<基于Spring Boot,使用JPA操作Sql Server数据库完成CRUD>,<基于Spring Boot,使用JPA调用Sql Server数据库的存储过程并返回记录集合 ...

  6. 基于Spring Boot,使用JPA调用Sql Server数据库的存储过程并返回记录集合

    在上一篇<基于Spring Boot,使用JPA操作Sql Server数据库完成CRUD>中完成了使用JPA对实体数据的CRUD操作. 那么,有些情况,会把一些查询语句写在存储过程中,由 ...

  7. 基于Spring Boot、Spring Cloud、Docker的微服务系统架构实践

    由于最近公司业务需要,需要搭建基于Spring Cloud的微服务系统.遍访各大搜索引擎,发现国内资料少之又少,也难怪,国内Dubbo正统治着天下.但是,一个技术总有它的瓶颈,Dubbo也有它捉襟见肘 ...

  8. 基于Spring Boot和Shiro的后台管理系统FEBS

    FEBS是一个简单高效的后台权限管理系统.项目基础框架采用全新的Java Web开发框架 —— Spring Boot 2.0.3,消除了繁杂的XML配置,使得二次开发更为简单:数据访问层采用Myba ...

  9. Cola Cloud 基于 Spring Boot, Spring Cloud 构建微服务架构企业级开发平台

    Cola Cloud 基于 Spring Boot, Spring Cloud 构建微服务架构企业级开发平台: https://gitee.com/leecho/cola-cloud

随机推荐

  1. PrototypePattern(23种设计模式之一)

    设计模式六大原则(1):单一职责原则 设计模式六大原则(2):里氏替换原则 设计模式六大原则(3):依赖倒置原则 设计模式六大原则(4):接口隔离原则 设计模式六大原则(5):迪米特法则 设计模式六大 ...

  2. loj10131 暗的连锁

    传送门 分析 首先我们知道如果在一棵树上加一条边一定会构成一个环,而删掉环上任意一条边都不改变连通性.我们把这一性质扩展到这个题上不难发现如果一条树边不在任意一个新边构成的环里则删掉这条边之后可以删掉 ...

  3. Luogu 3942 将军令

    之前写那个(Luogu 2279) [HNOI2003]消防局的设立的时候暴力推了一个树形dp,然后就导致这个题不太会写. 贪心,先把树建出来,然后考虑按照结点深度排个序,每次取出还没有被覆盖掉的深度 ...

  4. img中 src 中文路径解决办法

    最近有个项目场景如下:需要后台遍历图片.视频所在的文件夹,获取的到的路径传递到JSP页面,使用<img src="具体的路径">显示图片.遇到的问题:如果图片的路径.图 ...

  5. C# 与Java初始化顺序及异同(转)

    C#初始化顺序 类成员变量初始化先于类的构造函数 静态成员变量先于实例变量 子类成员变量先于父类成员变量(java相反) 父类构造函数先于子类构造函数 参考实例: using System; //us ...

  6. jQuery的Validate插件

    http://www.runoob.com/jquery/jquery-plugin-validate.html 项目中的:: $(function () { $('#createDepartment ...

  7. C# GDI

    绘制实心矩形 using (Graphics gp = Graphics.FromImage(bmBlank)) { //... ; Rectangle rec = , y, , );//画一个白块, ...

  8. 获取GridView控件总列数

    GridView控件,它不管是放在MasterPage母版页内,还是放在Page单独网页内,它不管是自动显示列AutoGenerateColumns="true",还是手动定列Au ...

  9. oracle sql 字段行转列

    数据库中原先如图: 现在要吧WHMM行转列: conncect by用于确定列的个数

  10. 如何在页面中使用svg图标

    1.svg图标长啥样 注意:图标的宽高无所谓,使用时可以根据需求修改,fill后面是颜色的填充,可修改图标颜色. <svg viewBox="0 0 1024 1024" v ...