zoukankan      html  css  js  c++  java
  • 基于spring boot 和MDC实现 同一笔记录的日志跟踪实现--1.filter

    同一个项目中,一般包含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
  • 相关阅读:
    div标签和span标签的简单区别
    方法重载的好处及区别
    异步计算工具
    设置"用于统计的冗余字段"要谨慎
    如何建立索引
    NFS,Memcached,Tokyo tyrant实现session共享性能测试
    mysql cache功能小记
    PHP程序员也要学会使用“异常”
    xdebug: var_dump函数设置
    用shell写个简单的log监控程序
  • 原文地址:https://www.cnblogs.com/yaoyuan2/p/10302802.html
Copyright © 2011-2022 走看看