SpringBoot正确打日志的姿势

前篇
本文简介
前篇侧重 Log4j2 的配置,本篇侧重统一日志处理的应用,以下包含 HTTP 请求的日志处理、Exception 异常日志处理。
HTTP 请求日志
img
1、明确日志记录的内容
示例:用户、IP地址、Method、URI、请求参数、请求体
2、全局拦截 MDCFilter.java
package com.anoyi.config.server;
import lombok.extern.log4j.Log4j2;
import org.slf4j.MDC;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Component;
import org.springframework.web.filter.OncePerRequestFilter;
import javax.servlet.FilterChain;
import javax.servlet.ReadListener;
import javax.servlet.ServletException;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
/**
* 拦截请求信息,添加到日志
*/
@Component
@Log4j2
public class MDCFilter extends OncePerRequestFilter {
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws ServletException, IOException {
try {
MDC.put("user", request.getRemoteUser());
String query = request.getQueryString() != null ? "?" + request.getQueryString() : "";
if (request.getMethod().equals(HttpMethod.POST.name())) {
MultiReadHttpServletRequest multiReadHttpServletRequest = new MultiReadHttpServletRequest(request);
log.info("IP:{}, Method:{}, URI:{} Body:{}", request.getRemoteAddr(), request.getMethod(), request.getRequestURI() + query, multiReadHttpServletRequest.getRequestBody());
chain.doFilter(multiReadHttpServletRequest, response);
} else {
log.info("IP:{}, Method:{}, URI:{}", request.getRemoteAddr(), request.getMethod(), request.getRequestURI() + query);
chain.doFilter(request, response);
}
} finally {
MDC.clear();
}
}
/**
* HttpServletRequest 请求体多读
*/
class MultiReadHttpServletRequest extends HttpServletRequestWrapper {
// 缓存 RequestBody
private String requestBody;
MultiReadHttpServletRequest(HttpServletRequest request) {
super(request);
requestBody = "";
try {
StringBuilder stringBuilder = new StringBuilder();
InputStream inputStream = request.getInputStream();
byte[] bs = new byte[1024];
int len;
while ((len = inputStream.read(bs)) != -1) {
stringBuilder.append(new String(bs, 0, len));
}
requestBody = stringBuilder.toString();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public ServletInputStream getInputStream() throws IOException {
final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(requestBody.getBytes());
return new ServletInputStream() {
public int read() throws IOException {
return byteArrayInputStream.read();
}
@Override
public boolean isFinished() {
return byteArrayInputStream.available() == 0;
}
@Override
public boolean isReady() {
return true;
}
@Override
public void setReadListener(ReadListener readListener) {
}
};
}
@Override
public BufferedReader getReader() throws IOException {
return new BufferedReader(new InputStreamReader(this.getInputStream()));
}
String getRequestBody() {
return requestBody.replaceAll("\n", "");
}
}
}
3、配置日志 Pattern
logging:
pattern:
console: "%d{yyyy-MM-dd HH:mm:ss.SSS} %5p [%15.15t] %-40.40c{1.} [%X{user}] : %m%n%xwEx"
说明: MDC.put("user", request.getRemoteUser()); => %X{user}
© 著作权归作者所有,转载或内容合作请联系作者

● Spring Boot 定制 parent 快速构建应用
● Spring Boot 日志处理你还在用Logback?
● 【双11狂欢的背后】微服务注册中心如何承载大型系统的千万级访问?

本文由博客一文多发平台 OpenWrite 发布!
SpringBoot正确打日志的姿势的更多相关文章
- 如何正确使用日志Log
title: 如何正确使用日志Log date: 2015-01-08 12:54:46 categories: [Python] tags: [Python,log] --- 文章首发地址:http ...
- springboot动态修改日志级别+权限认证
1. springboot动态修改日志级别+权限认证 1.1. 需求 网上找到的动态修改日志级别的方式,基本都是没有权限验证的,或者特地关闭权限验证,但也没给出加上验证的解决方式 修改日志等级也是一个 ...
- Springboot整合log4j2日志全解
目录 常用日志框架 日志门面slf4j 为什么选用log4j2 整合步骤 引入Jar包 配置文件 配置文件模版 配置参数简介 Log4j2配置详解 简单使用 使用lombok工具简化创建Logger类 ...
- springboot logback + log4j2日志管理
springboot的web项目中自带了日志组件: 我们看一下,springboot中找到日志组件. <dependency> <groupId>org.springframe ...
- SpringBoot起飞系列-日志使用(四)
一.SpringBoot中的日志组件 日志是一个系统中不可缺少的组件.在项目中,我们常用的日志组件有JUL.JCL.Jboss-logging.logback.log4j.log4j2.slf4j.. ...
- springboot配置logback日志
springboot配置logback日志 java web 下有好几种日志框架,比如:logback,log4j,log4j2(slj4f 并不是一种日志框架,它相当于定义了规范,实现了这个规范的日 ...
- SpringBoot系列之日志框架使用教程
目录 1.SpringBoot日志级别 1).日志级别简介 2).默认日志级别 3).配置日志级别 4).日志分组设置 2.SpringBoot日志格式设置 1).默认格式原理简介 2).默认日志格式 ...
- SpringBoot系列之日志框架介绍及其原理简介
SpringBoot系列之日志框架介绍及其原理简介 1.常用日志框架简介 市面上常用日志框架:JUL.JCL.jboss-logging.logback.log4j.log4j2.slf4j.etc. ...
- 【SpringBoot】整合日志框架
一.日志框架概述 1.1 日志框架的产生 1.2 市面上的日志框架 二.SLF4j 使用与整合 2.1 如何在系统中使用SLF4j 2.2 如何整合日志框架 2.3 SpringBoot中的日志关系 ...
随机推荐
- springcloud -- sleuth+zipkin整合rabbitMQ详解
为什么使用RabbitMQ? 我们已经知道,zipkin的原理是服务之间的调用关系会通过HTTP方式上报到zipkin-server端,然后我们再通过zipkin-ui去调用查看追踪服务之间的调用链路 ...
- PHP高效产生m个n范围内的不重复随机数(m<=n)
该算法非常巧妙的取随机数的位置(数组的下标),替代取随机数本身,每次取到一个随机数之后,就将其在取值范围中排除,下一次仅会在剩下的数字中取,一次遍历就可以完成随机数的选取,效率相当高. functio ...
- 常见过滤器表格整理,Date,time过滤格式表;常用标签表
一.常用过滤器表 二.date.time过滤器参数表 三.模板常用标签 四.模板标签示例 ①if,for ②url解析标签 ③with缓存标签 ④autoescape的使用 ⑤注释标签(多行注释)一般 ...
- 记录 java 安卓 各类引用包报错处理方法 例如 android.support.v4.app.+ ,io.reactivex.+
可能导致的原因: 1. 引用包不存在(存在也报错就是 版本不对) 2.有资源文件 重名,报错之类的问题 3. 别人提交了资源文件或者配置文件(这是最常见的,特别是新手,我也是),后续遇到再加 解决方法 ...
- 使用foreach语句对数组成员进行遍历
/*** 使用foreach语句对数组成员进行遍历* **/ public class ForeachDemo { public static void main(String[] args) { i ...
- 如何使用Externalizable接口自定义Java中的序列化
Java序列化过程的缺点 我们都知道如何使用Serializable接口序列化/反序列化一个对象,并且如何使用writeObject 和readObject方法自定义序列化过程. 但是这些自定义还不够 ...
- Java编程思想——第17章 容器深入研究 读书笔记(二)
五.List的功能方法 排除Collection已包含的方法外还增加了 boolean addAll(int index, Collection<? extends E> c);从索引位置 ...
- 使用git如何规范地向主线提交代码
使用git向主干分支合并代码通常采用两种方式:第一种是merge,第二种是利用BeyondCompare等工具进行比对,将差异合并到主干: 通过merge合并代码出现冲突时,并不清楚谁的修改和谁的修改 ...
- HDU 1532 Drainage Ditches(最大流 EK算法)
题目网址:http://acm.hdu.edu.cn/showproblem.php?pid=1532 思路: 网络流最大流的入门题,直接套模板即可~ 注意坑点是:有重边!!读数据的时候要用“+=”替 ...
- 19.Tomcat集群架构
1.Nginx+Tomcat集群架构介绍 2.Nginx+Tomcat集群架构实战 [root@lb01 conf.d]# cat proxy_zrlog.cheng.com.conf upstrea ...