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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 前端技术 > javascript >内容正文

javascript

qt能使用logback_SpringBoot 中使用 LogBack 配置

發布時間:2024/10/5 javascript 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 qt能使用logback_SpringBoot 中使用 LogBack 配置 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

LogBack是一個日志框架,它與Log4j可以說是同出一源,都出自?CekiGülcü之手。(?log4j的原型是早前由?CekiGülcü貢獻給?Apache基金會的)下載地址?https://logback.qos.ch/download.html

LogBack、Slf4j和Log4j之間的關系

Slf4j是?TheSimpleLoggingFacadeforJava的簡稱,是一個簡單日志門面抽象框架,它本身只提供了日志Facade?API和一個簡單的日志類實現,一般常配合?Log4j,LogBack,java.util.logging使用。?Slf4j作為應用層的Log接入時,程序可以根據實際應用場景動態調整底層的日志實現框架?(Log4j/LogBack/JdkLog…)。

LogBack和?Log4j都是開源日記工具庫,?LogBack是?Log4j的改良版本,比?Log4j擁有更多的特性,同時也帶來很大性能提升。詳細數據可參照下面地址:?Reasonsto prefer logback over log4j。

LogBack官方建議配合?Slf4j使用,這樣可以靈活地替換底層日志框架。

TIPS:為了優化?log4j,以及更大性能的提升,Apache基金會已經著手開發了?log4j2.0, 其中也借鑒和吸收了?logback的一些先進特性,目前?log4j2還處于?beta階段

logback取代log4j的理由

1、更快的實現:?Logback的內核重寫了,在一些關鍵執行路徑上性能提升10倍以上。而且?logback不僅性能提升了,初始化內存加載也更小了。
2、非常充分的測試:?Logback經過了幾年,數不清小時的測試。?Logback的測試完全不同級別的。
3、?Logback-classic非常自然實現了?SLF4j:Logback-classic實現了?SLF4j。在使用SLF4j中,你都感覺不到?logback-classic。而且因為?logback-classic非常自然地實現了?slf4j?, 所 以切換到?log4j或者其他,非常容易,只需要提供成另一個?jar包就OK,根本不需要去動那些通過?SLF4JAPI實現的代碼。
4、非常充分的文檔 官方網站有兩百多頁的文檔。
5、自動重新加載配置文件,當配置文件修改了,?Logback-classic能自動重新加載配置文件。掃描過程快且安全,它并不需要另外創建一個掃描線程。這個技術充分保證了應用程序能跑得很歡在JEE環境里面。
6、?Lilith是?log事件的觀察者,和?log4j的?chainsaw類似。而?lilith還能處理大數量的log數據 。
7、謹慎的模式和非常友好的恢復,在謹慎模式下,多個?FileAppender實例跑在多個JVM下,能 夠安全地寫道同一個日志文件。?RollingFileAppender會有些限制。?Logback的?FileAppender和它的子類包括?RollingFileAppender能夠非常友好地從I/O異常中恢復。
8、配置文件可以處理不同的情況,開發人員經常需要判斷不同的Logback配置文件在不同的環境下(開發,測試,生產)。而這些配置文件僅僅只有一些很小的不同,可以通過,和來實現,這樣一個配置文件就可以適應多個環境。
9、?Filters(過濾器)有些時候,需要診斷一個問題,需要打出日志。在?log4j,只有降低日志級別,不過這樣會打出大量的日志,會影響應用性能。在?Logback,你可以繼續 保持那個日志級別而除掉某種特殊情況,如?alice這個用戶登錄,她的日志將打在?DEBUG級別而其他用戶可以繼續打在?WARN級別。要實現這個功能只需加4行?XML配置。可以參考?MDCFIlter。
10、?SiftingAppender(一個非常多功能的?Appender):它可以用來分割日志文件根據任何一個給定的運行參數。如,?SiftingAppender能夠區別日志事件跟進用戶的?Session,然后每個用戶會有一個日志文件。
11、自動壓縮已經打出來的?log:RollingFileAppender在產生新文件的時候,會自動壓縮已經打出來的日志文件。壓縮是個異步過程,所以甚至對于大的日志文件,在壓縮過程中應用不會受任何影響。
12、堆棧樹帶有包版本:?Logback在打出堆棧樹日志時,會帶上包的數據。
13、自動去除舊的日志文件:通過設置?TimeBasedRollingPolicy或者?SizeAndTimeBasedFNATP的maxHistory屬性,你可以控制已經產生日志文件的最大數量。如果設置?maxHistory12,那那些?log文件超過?12個月的都會被自動移除。

LogBack的結構

LogBack被分為3個組件,?logback-core,logback-classic?和?logback-access。

logback-core提供了LogBack的核心功能,是另外兩個組件的基礎。

logback-classic則實現了?Slf4j的?API,所以當想配合Slf4j使用時,需要將?logback-classic加入?classpath。

logback-access是為了集成?Servlet環境而準備的,可提供?HTTP-access的日志接口。

配置詳解

Github 代碼

代碼已放到 Github ,導入?spring-boot-logback?項目

github?spring-boot-logback

Maven依賴

假如maven依賴中添加了?spring-boot-starter-logging:

? ?org.springframework.boot

? ?spring-boot-starter-logging

那么,我們的Spring Boot應用將自動使用logback作為應用日志框架,Spring Boot啟動的時候,由org.springframework.boot.logging.Logging-Application-Listener根據情況初始化并使用。

但是呢,實際開發中我們不需要直接添加該依賴,你會發現spring-boot-starter其中包含了 spring-boot-starter-logging,該依賴內容就是 Spring Boot 默認的日志框架 logback

配置文件

配置文件 logback-spring.xml

xml version="1.0" encoding="UTF-8"?>

? ? scope="context" name="LOG_HOME" source="logging.path" defaultValue="/data/logs/spring-boot-logback"/>

? ? scope="context" name="LOG_ROOT_LEVEL" source="logging.level.root" defaultValue="DEBUG"/>

? ? scope="context" name="STDOUT" source="log.stdout" defaultValue="STDOUT"/>

? ? name="LOG_PREFIX" value="spring-boot-logback" />

? ? name="LOG_CHARSET" value="UTF-8" />

? ? name="LOG_DIR" value="${LOG_HOME}/%d{yyyyMMdd}" />

? ? name="LOG_MSG" value="- | [%X{requestUUID}] | [%d{yyyyMMdd HH:mm:ss.SSS}] | [%level] | [${HOSTNAME}] | [%thread] | [%logger{36}] | --> %msg|%n "/>

? ? name="MAX_FILE_SIZE" value="50MB" />

? ? name="MAX_HISTORY" value="10"/>

? ? name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

? ? ? ? class="ch.qos.logback.classic.PatternLayout">

? ? ? ? ? ?${LOG_MSG}

? ? name="0" class="ch.qos.logback.core.rolling.RollingFileAppender">

? ? name="FILE_ALL" class="ch.qos.logback.core.rolling.RollingFileAppender">

? ? ? ?${LOG_HOME}/all_${LOG_PREFIX}.log

? ? ? ? class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

? ? ? ? ? ?${LOG_DIR}/all_${LOG_PREFIX}%i.log

? ? ? ? ? ?${MAX_HISTORY}

? ? ? ? ? ? class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">

? ? ? ? ? ? ? ?${MAX_FILE_SIZE}

? ? ? ? class="ch.qos.logback.classic.PatternLayout">

? ? ? ? ? ?${LOG_MSG}

? ? name="FILE_ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">

? ? ? ? class="ch.qos.logback.classic.filter.LevelFilter">

? ? ? ? ? ?ERROR

? ? ? ? ? ?DENY

? ? ? ? ? ?ACCEPT

? ? ? ?${LOG_HOME}/err_${LOG_PREFIX}.log

? ? ? ? class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

? ? ? ? ? ?${LOG_DIR}/err_${LOG_PREFIX}%i.log

? ? ? ? ? ?${MAX_HISTORY}

? ? ? ? ? ? class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">

? ? ? ? ? ? ? ?${MAX_FILE_SIZE}

? ? ? ? class="ch.qos.logback.classic.PatternLayout">

? ? ? ? ? ?${LOG_MSG}

? ? name="org.springframework" ? ? level="ERROR" />

? ? name="org.apache.commons" ? ? ?level="ERROR" />

? ? name="org.apache.zookeeper" ? ?level="ERROR" ?/>

? ? name="com.alibaba.dubbo.monitor" level="ERROR"/>

? ? name="com.alibaba.dubbo.remoting" level="ERROR" />

? ? level="${LOG_ROOT_LEVEL}">

? ? ? ? ref="${STDOUT}"/>

? ? ? ? ref="FILE_ALL"/>

? ? ? ? ref="FILE_ERROR"/>

配置文件 application.properties

#日志級別從低到高分為TRACE < DEBUG < INFO < WARN < ERROR < FATAL,如果設置為WARN,則低于WARN的信息都不會輸出

logging.level.root=trace

logging.path=/data/logs/spring-boot-logback

節點介紹

logback節點配置詳解

日志會每天新建一個文件夾,日文文件配置的每50兆,一個文本文件,超過新寫入一個

文件夾:20171031

文件夾內容:all_spring-boot-logback0.log

文件夾內容:all_spring-boot-logback1.log

文件夾內容:all_spring-boot-logback2.log

文件夾內容:err_spring-boot-logback0.log

MDC requestUUID

一種多線程下日志管理實踐方式

logback MDC(Mapped Diagnostic Context)與分布式系統的跟蹤系統

Slf4j MDC 使用和 基于 Logback 的實現分析

MDC介紹 -- 一種多線程下日志管理實踐方式

  MDC(Mapped Diagnostic Context,映射調試上下文)是 log4j 和 logback 提供的一種方便在多線程條件下記錄日志的功能。某些應用程序采用多線程的方式來處理多個用戶的請求。在一個用戶的使用過程中,可能有多個不同的線程來進行處理。典型的例子是 Web 應用服務器。當用戶訪問某個頁面時,應用服務器可能會創建一個新的線程來處理該請求,也可能從線程池中復用已有的線程。在一個用戶的會話存續期間,可能有多個線程處理過該用戶的請求。這使得比較難以區分不同用戶所對應的日志。當需要追蹤某個用戶在系統中的相關日志記錄時,就會變得很麻煩。

一種解決的辦法是采用自定義的日志格式,把用戶的信息采用某種方式編碼在日志記錄中。這種方式的問題在于要求在每個使用日志記錄器的類中,都可以訪問到用戶相關的信息。這樣才可能在記錄日志時使用。這樣的條件通常是比較難以滿足的。MDC 的作用是解決這個問題。

  MDC 可以看成是一個與當前線程綁定的哈希表,可以往其中添加鍵值對。MDC 中包含的內容可以被同一線程中執行的代碼所訪問。當前線程的子線程會繼承其父線程中的 MDC 的內容。當需要記錄日志時,只需要從 MDC 中獲取所需的信息即可。MDC 的內容則由程序在適當的時候保存進去。對于一個 Web 應用來說,通常是在請求被處理的最開始保存這些數據。

自定義攔截器 logback requestUUID

/**

* 描述: 自定義攔截器 logback requestUUID

*

* @author yanpenglei

* @create 2017-10-30 16:15

**/

public class ControllerInterceptor extends HandlerInterceptorAdapter {

? ?private Logger LOGGER = LoggerFactory.getLogger(ControllerInterceptor.class);

? ?//在請求處理之前回調方法

? ?@Override

? ?public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {

? ? ? ?String requestUUID = MDC.get("requestUUID");

? ? ? ?if (requestUUID == null || "".equals(requestUUID)) {

? ? ? ? ? ?String uuid = UUID.randomUUID().toString();

? ? ? ? ? ?uuid = uuid.replaceAll("-", "").toUpperCase();

? ? ? ? ? ?MDC.put("requestUUID", uuid);

? ? ? ? ? ?LOGGER.info("ControllerInterceptor preHandle 在請求處理之前生成 logback requestUUID:{}", uuid);

? ? ? ?}

? ? ? ?return true;// 只有返回true才會繼續向下執行,返回false取消當前請求

? ?}

? ?//請求處理之后回調方法

? ?@Override

? ?public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

? ? ? ?/* 線程結束后需要清除,否則當前線程會一直占用這個requestId值 */

? ? ? ?MDC.remove("requestUUID");

? ? ? ?LOGGER.info("ControllerInterceptor postHandle 請求處理之后清除 logback MDC requestUUID");

? ?}

? ?//整個請求處理完畢回調方法

? ?@Override

? ?public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {

? ? ? ?/*整個請求線程結束后需要清除,否則當前線程會一直占用這個requestId值 */

? ? ? ?MDC.clear();

? ? ? ?LOGGER.info("ControllerInterceptor afterCompletion 整個請求處理完畢清除 logback MDC requestUUID");

? ?}

}

對日志進行格式化,時候用到

name="LOG_MSG" value="- | [%X{requestUUID}] | [%d{yyyyMMdd HH:mm:ss.SSS}] | [%level] | [${HOSTNAME}] | [%thread] | [%logger{36}] | --> %msg|%n "/>

/**

* 描述:攔截器配置

*

* @author yanpenglei

* @create 2017-10-30 16:54

**/

@Configuration

public class MyWebMvcConfigurer extends WebMvcConfigurerAdapter {

? ?@Override

? ?public void addInterceptors(InterceptorRegistry registry) {

? ? ? ?/**

? ? ? ? * 多個攔截器組成一個攔截器鏈

? ? ? ? * addPathPatterns 用于添加攔截規則

? ? ? ? * excludePathPatterns 用于排除攔截

? ? ? ? */

? ? ? ?registry.addInterceptor(new ControllerInterceptor()).addPathPatterns("/**");

? ? ? ?super.addInterceptors(registry);

? ?}

}

日志切面

@Aspect

@Component

public class LogAspect {

? ?private static final Logger log = LoggerFactory.getLogger(LogAspect.class);

? ?private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";

? ?private static final String STRING_START = "\n>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>\n";

? ?private static final String STRING_END ? = "\n<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<;

? ?@Pointcut("execution(* io.ymq.logback.controller..*(..))")

? ?public void serviceLog() {

? ?}

? ?@Around("serviceLog()")

? ?public Object around(ProceedingJoinPoint joinPoint) {

? ? ? ?try {

? ? ? ? ? ?MethodSignature signature = (MethodSignature) joinPoint.getSignature();

? ? ? ? ? ?Method method = signature.getMethod();

? ? ? ? ? ?Class> targetClass = method.getDeclaringClass();

? ? ? ? ? ?StringBuffer classAndMethod = new StringBuffer();

? ? ? ? ? ?Log classAnnotation = targetClass.getAnnotation(Log.class);

? ? ? ? ? ?Log methodAnnotation = method.getAnnotation(Log.class);

? ? ? ? ? ?if (classAnnotation != null) {

? ? ? ? ? ? ? ?if (classAnnotation.ignore()) {

? ? ? ? ? ? ? ? ? ?return joinPoint.proceed();

? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ?classAndMethod.append(classAnnotation.value()).append("-");

? ? ? ? ? ?}

? ? ? ? ? ?if (methodAnnotation != null) {

? ? ? ? ? ? ? ?if (methodAnnotation.ignore()) {

? ? ? ? ? ? ? ? ? ?return joinPoint.proceed();

? ? ? ? ? ? ? ?}

? ? ? ? ? ? ? ?classAndMethod.append(methodAnnotation.value());

? ? ? ? ? ?}

? ? ? ? ? ?String target = targetClass.getName() + "#" + method.getName();

? ? ? ? ? ?String params = JSONObject.toJSONStringWithDateFormat(joinPoint.getArgs(), dateFormat, SerializerFeature.WriteMapNullValue);

? ? ? ? ? ?log.info(STRING_START + "{} 開始調用--> {} 參數:{}", classAndMethod.toString(), target, params);

? ? ? ? ? ?long start = System.currentTimeMillis();

? ? ? ? ? ?Object result = joinPoint.proceed();

? ? ? ? ? ?long timeConsuming = System.currentTimeMillis() - start;

? ? ? ? ? ?log.info("\n{} 調用結束 + STRING_END, classAndMethod.toString(), target, JSONObject.toJSONStringWithDateFormat(result, dateFormat, SerializerFeature.WriteMapNullValue), timeConsuming);

? ? ? ? ? ?return result;

? ? ? ?} catch (Throwable throwable) {

? ? ? ? ? ?log.error(throwable.getMessage(), throwable);

? ? ? ?}

? ? ? ?return null;

? ?}

}

測試 logback

瀏覽器訪問:http://127.0.0.1:8080/index/?content="我是測試內容"

@RestController

@RequestMapping(value = "/index")

public class IndexController {

? ?private final Logger LOGGER = LoggerFactory.getLogger(this.getClass());

? ?/**

? ? * http://127.0.0.1:8080/index/?content="我是測試內容"

? ? *

? ? * @param content

? ? * @return

? ? */

? ?@Log("首頁IndexController")

? ?@RequestMapping(value="", method= RequestMethod.GET)

? ?public String index(@RequestParam String content) {

? ? ? ?LocalDateTime localDateTime = LocalDateTime.now();

? ? ? ?LOGGER.trace("請求參數:content:{}", content);

? ? ? ?LOGGER.debug("請求參數:content:{}", content);

? ? ? ?LOGGER.info("請求參數:content:{}", content);

? ? ? ?LOGGER.warn("請求參數:content:{}", content);

? ? ? ?LOGGER.error("請求參數:content:{}", content);

? ? ? ?return localDateTime + ",content:" + content;

? ?}

}

前面的?07E94BA525CF4C97851E4B9E4ABB4890?就是通過?logback?的 MDC 做到的

首頁IndexController 開始調用--> io.ymq.logback.controller.IndexController#index 參數:["\"我是測試內容\""]|

- | [07E94BA525CF4C97851E4B9E4ABB4890] | [20171101 10:02:35.589] | [DEBUG] | [DESKTOP-VG43S0C] | [http-nio-8080-exec-1] | [i.y.l.controller.IndexController] | --> 請求參數:content:"我是測試內容"|

- | [07E94BA525CF4C97851E4B9E4ABB4890] | [20171101 10:02:35.589] | [INFO] | [DESKTOP-VG43S0C] | [http-nio-8080-exec-1] | [i.y.l.controller.IndexController] | --> 請求參數:content:"我是測試內容"|

- | [07E94BA525CF4C97851E4B9E4ABB4890] | [20171101 10:02:35.589] | [WARN] | [DESKTOP-VG43S0C] | [http-nio-8080-exec-1] | [i.y.l.controller.IndexController] | --> 請求參數:content:"我是測試內容"|

- | [07E94BA525CF4C97851E4B9E4ABB4890] | [20171101 10:02:35.590] | [ERROR] | [DESKTOP-VG43S0C] | [http-nio-8080-exec-1] | [i.y.l.controller.IndexController] | --> 請求參數:content:"我是測試內容"|

- | [07E94BA525CF4C97851E4B9E4ABB4890] | [20171101 10:02:35.606] | [INFO] | [DESKTOP-VG43S0C] | [http-nio-8080-exec-1] | [i.y.logback.config.commons.LogAspect] | -->

首頁IndexController 調用結束 io.ymq.logback.controller.IndexController#index 返回值:"2017-11-01T10:02:35.589,content:\"我是測試內容\"" 耗時:23ms

從上圖可以看到,日志輸出內容元素具體如下:

requestUUID:一次請求是唯一的時間日期:精確到毫秒日志級別:ERROR,WARN,INFO,DEBUGorTRACE主機名:進程ID:類路徑:分隔符:-->標識實際日志的開始日志內容:

日志切面的響應:

首頁IndexController 開始調用--> io.ymq.logback.controller.IndexController#index 參數:["\"我是測試內容\""]|

首頁IndexController 調用結束 io.ymq.logback.controller.IndexController#index 返回值:"2017-11-01T10:02:35.589,content:\"我是測試內容\"" 耗時:23ms

代碼已放到 Github ,導入?spring-boot-logback?項目

github?spring-boot-logback

slf4j-logback 日志以json格式導入ELK

出處:

公眾號:搜云庫技術團隊

總結

以上是生活随笔為你收集整理的qt能使用logback_SpringBoot 中使用 LogBack 配置的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。