日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

logback自定义日志格式

發(fā)布時間:2024/1/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 logback自定义日志格式 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

logback自定義日志格式

1.ClassicConverter

繼承ClassicConverter

package com.demo.conf;import ch.qos.logback.classic.pattern.ClassicConverter; import ch.qos.logback.classic.spi.ILoggingEvent;import java.net.InetAddress; import java.net.UnknownHostException;/*** 配置日志中顯示IP*/ public class IPLogConfig extends ClassicConverter {@Overridepublic String convert(ILoggingEvent event) {try {return InetAddress.getLocalHost().getHostAddress();} catch (UnknownHostException e) {e.printStackTrace();}return null;} }

然后再logback.xml中配置

<!--配置規(guī)則類的位置--> <conversionRule conversionWord="ip" converterClass="com.demo.conf.IPLogConfig" /><appender name="Console" class="ch.qos.logback.core.ConsoleAppender"><layout><pattern>%ip -%date{HH:mm:ss} %highlight(%-5level)[%yellow(%thread)]%green(%logger{56}.%method:%L) -%msg%n"</pattern></layout></appender>

2.實現(xiàn)PropertyDefiner

logback提供自定義屬性接口PropertyDefiner

實現(xiàn)PropertyDefiner:getPropertyValue()方法

public class GetIpProperty implements PropertyDefiner{@overridepublic String getPropertyValue() {try {InetAddress address = InetAddress.getLocalHost();return address.getHostAddress();} catch (UnknownHostException e) {e.printStackTrace();} return null;}//.... }

然后在logback.xml配置文件中,定義自定義標(biāo)簽define name代表標(biāo)簽,class指向處理的類。在初始化時調(diào)用getPropertyValue()

<configuration><define name="ip" class="com.lay.config.log.GetIpProperty"></define><appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"><encode><parttern>${ip}-%date{HH:mm:ss} %highlight(%-5level)[%yellow(%thread)]%green(%logger{56}.%method:%L) -%msg%n"</parttern></encode></appender> </configuration>

3.SLF4JMDC

Logback是在logback-classic模塊中實現(xiàn)了SLF4J的MDC功能。

MDC中管理的數(shù)據(jù)(簡稱MDC數(shù)據(jù))是以單個線程為單位進行訪問的,即對MDC數(shù)據(jù)的操作(如put, get)只對當(dāng)前線程有效,所以也永遠是線程安全的。
在服務(wù)端,為每個請求分配一個線程進行處理,所以每個服務(wù)端線程處理的請求,都具有唯一的MDC上下文數(shù)據(jù)。

子線程不會自動繼承父線程的MDC數(shù)據(jù)。所以在創(chuàng)建子線程時,可以先調(diào)用MDC的getCopyOfContextMap()方法以返回一個Map<String, String>對象,從而獲取父線程的MDC數(shù)據(jù),然后再在子線程的開始處,最先調(diào)用MDC的setContextMap()方法為子線程設(shè)置父線程的MDC數(shù)據(jù)。從而能夠在子線程中訪問父線程的MDC數(shù)據(jù)。

在使用java.util.concurrent.Executors管理線程時,使用同樣的方法讓子線程繼承主線程的MDC數(shù)據(jù)。

但是,在Web應(yīng)用中,一個請求可能在不同的階段被多個線程處理。這時,只是在服務(wù)端的處理線程中設(shè)置MDC數(shù)據(jù),并不能保證請求的某些信息(如用戶的認(rèn)證信息等)總是能夠被處理線程訪問到。為了在處理一個請求時能夠保證某些信息總是可訪問,建議使用Servlet Filter,在請求到來時就將信息裝入到MDC中,在完成所有的后續(xù)處理后,再次通過過濾器時將MDC數(shù)據(jù)移除。

public class MyFilter implements Filter {public void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {...MDC.put(MY_KEY, myValue);...try {chain.doFilter(request, response);} finally {if (MDC.contains(MY_KEY)) {MDC.remove(MY_KEY);}}

Logback自帶的ch.qos.logback.classic.helpers.MDCInsertingServletFilter能夠?qū)TTP請求的hostname, request URI, user-agent等信息裝入MDC,只需在web.xml中設(shè)置(建議MDCInsertingServletFilter作為第一個Filter配置,原因請讀者思考),后續(xù)處理過程就可以直接訪問如下請求參數(shù)的值:

req.remoteHost
req.xForwardedFor
req.method
req.requestURI
req.requestURL
req.queryString

req.userAgent

源碼如下

package com.lay.log.core.filter;import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.slf4j.MDC;import javax.servlet.*; import javax.servlet.http.HttpServletRequest; import java.io.IOException; import java.net.InetAddress; import java.net.UnknownHostException;/*** @Description:* @Author: lay* @Date: Created in 11:22 2019/3/19* @Modified By:IntelliJ IDEA*/ public class LogFilter implements Filter {private static final Logger log = LoggerFactory.getLogger(LogFilter.class);@Overridepublic void init(FilterConfig filterConfig) {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {log.info("start log filter");this.insertIntoMDC(request);log.info("log filter....");try {chain.doFilter(request, response);} finally {log.info("log filter....");this.clearMDC();log.info("end log filter");}}void insertIntoMDC(ServletRequest request) {MDC.put("req.remoteHost", request.getRemoteHost());if (request instanceof HttpServletRequest) {HttpServletRequest httpServletRequest = (HttpServletRequest) request;MDC.put("req.requestURI", httpServletRequest.getRequestURI());StringBuffer requestURL = httpServletRequest.getRequestURL();if (requestURL != null) {MDC.put("req.requestURL", requestURL.toString());}String requestNo = httpServletRequest.getHeader("Request-No");if (requestNo != null && !requestNo.equals("")) {MDC.put("req.requestNo", requestNo);}MDC.put("req.method", httpServletRequest.getMethod());MDC.put("req.queryString", httpServletRequest.getQueryString());MDC.put("req.userAgent", httpServletRequest.getHeader("User-Agent"));MDC.put("req.xForwardedFor", httpServletRequest.getHeader("X-Forwarded-For"));MDC.put("req.hostIp", getHostIp());}}void clearMDC() {MDC.remove("req.remoteHost");MDC.remove("req.requestURI");MDC.remove("req.queryString");MDC.remove("req.requestURL");MDC.remove("req.method");MDC.remove("req.userAgent");MDC.remove("req.xForwardedFor");MDC.remove("req.requestNo");MDC.remove("req.ho stIp");}@Overridepublic void destroy() {}public String getHostIp() {try {InetAddress address = InetAddress.getLocalHost();return address.getHostAddress();} catch (UnknownHostException e) {e.printStackTrace();}return null;} }

配置

@Component public class ApplicationConfig {@Beanpublic FilterRegistrationBean filterRegistrationBean() {FilterRegistrationBean registrationBean = new FilterRegistrationBean();Filter actionFilter = new MDCInsertingServletFilter();registrationBean.setFilter(actionFilter);List<String> urlPatterns = new ArrayList<>();urlPatterns.add("/*");registrationBean.setUrlPatterns(urlPatterns);return registrationBean;} }

使用

<configuration><!-- 彩色日志 --><!-- 彩色日志依賴的渲染類 --><conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/><conversionRule conversionWord="wex"converterClass="org.springframework.boot.logging.logback.WhitespaceThrowableProxyConverter"/><conversionRule conversionWord="wEx"converterClass="org.springframework.boot.logging.logback.ExtendedWhitespaceThrowableProxyConverter"/><!-- 彩色日志格式 --><property name="CONSOLE_LOG_PATTERN"value="${CONSOLE_LOG_PATTERN:-%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){faint} %clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} %clr(--){faint} %clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint} %m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}}"/>/><property name="MDC_LOG_PATTERN" value="IP:%X{req.remoteHost} -url:%X{req.requestURI} -Method:%X{req.method} - QueryString:%X{req.queryString} - device:%X{req.userAgent} -ips:%X{req.xForwardedFor} - %m%n "></property><appender name="Console" class="ch.qos.logback.core.ConsoleAppender"><layout><pattern>${MDC_LOG_PATTERN}</pattern></layout></appender><root level="INFO"><appender-ref ref="Console"/><!--<appender-ref ref="Sentry"/>--></root> </configuration>

可以看到 MDC_LOG_PATTERN 中獲取了從MDC過濾器中的參數(shù),這樣我們就能打印出來了

總結(jié)

以上是生活随笔為你收集整理的logback自定义日志格式的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。