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
  • 相关阅读:
    n8n 基于node 的流程自动化工具
    kubectl-trace 基于bpftrace 的kubernetes 集群性能分析工具
    bcc 基于bpf 分析linux 系统性能的强大工具包
    使用arthas 生成火焰图分析jvm
    openjdk11 stretch基础镜像无法找到对应openjdk dbg 包的问题
    async-profiler 容器使用常见问题
    使用jattach 在host 节点查看容器jvm信息
    使用async-profiler简单分析zeebe 工作流引擎的性能
    minio select api 试用
    使用zeebe DebugHttpExporter 查看zeebe 工作流信息
  • 原文地址:https://www.cnblogs.com/yaoyuan2/p/10302802.html
Copyright © 2011-2022 走看看