【前言】
日誌對一個系統的重要性不言而喻;日誌通常是在排查問題時給人看,一個友好的輸出樣式讓人看到後賞心悅目,排查效率通常也會隨之提高;下面爲大家共享一下通過設置logback日誌輸出格式,打印出令人欣喜的日誌樣式。
【搞一下日誌格式】
一、未指定日誌格式,日誌輸出
1、代碼實現
(1)演示日誌輸出控制器
/*
* Copyright (c) 2019. [email protected] All Rights Reserved.
* 項目名稱:實戰SpringBoot
* 類名稱:CheckMobileController.java
* 創建人:張晗
* 聯繫方式:[email protected]
* 開源地址: https://github.com/dangnianchuntian/springboot
* 博客地址: https://zhanghan.blog.csdn.net
*/
package com.zhanghan.zhboot.controller;
import com.mysql.jdbc.StringUtils;
import com.zhanghan.zhboot.controller.request.MobileCheckRequest;
import com.zhanghan.zhboot.properties.MobilePreFixProperties;
import com.zhanghan.zhboot.util.wrapper.WrapMapper;
import com.zhanghan.zhboot.util.wrapper.Wrapper;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.Map;
@RestController
@Api(value = "校驗手機號控制器", tags = {"校驗手機號控制器"})
public class CheckMobileController {
private static Logger logger = LoggerFactory.getLogger(CheckMobileController.class);
@Autowired
private MobilePreFixProperties mobilePreFixProperties;
@ApiOperation(value = "優雅校驗手機號格式方式", tags = {"校驗手機號控制器"})
@RequestMapping(value = "/good/check/mobile", method = RequestMethod.POST)
public Wrapper goodCheckMobile(@RequestBody @Validated MobileCheckRequest mobileCheckRequest) {
logger.info("good check mobile param {}", mobileCheckRequest.toString());
String countryCode = mobileCheckRequest.getCountryCode();
String proFix = mobilePreFixProperties.getPrefixs().get(countryCode);
if (StringUtils.isNullOrEmpty(proFix)) {
logger.error("good check mobile param is error; param is {}, profix is {}", mobileCheckRequest.toString(), proFix);
return WrapMapper.error("參數錯誤");
}
String mobile = mobileCheckRequest.getMobile();
Boolean isLegal = false;
if (mobile.startsWith(proFix)) {
isLegal = true;
}
Map map = new HashMap();
map.put("mobile", mobile);
map.put("isLegal", isLegal);
map.put("proFix", proFix);
return WrapMapper.ok(map);
}
@ApiOperation(value = "擴展性差校驗手機號格式方式", tags = {"校驗手機號控制器"})
@RequestMapping(value = "/bad/check/mobile", method = RequestMethod.POST)
public Wrapper badCheckMobile(@RequestBody MobileCheckRequest mobileCheckRequest) {
logger.info("bad check mobile param {}", mobileCheckRequest.toString());
String countryCode = mobileCheckRequest.getCountryCode();
String proFix = "";
if (countryCode.equals("CN")) {
proFix = "86";
} else if (countryCode.equals("US")) {
proFix = "1";
} else {
logger.error("bad check mobile param is error; param is {}, profix is {}", mobileCheckRequest.toString(), proFix);
return WrapMapper.error("參數錯誤");
}
String mobile = mobileCheckRequest.getMobile();
Boolean isLegal = false;
if (mobile.startsWith(proFix)) {
isLegal = true;
}
Map map = new HashMap();
map.put("mobile", mobile);
map.put("isLegal", isLegal);
map.put("proFix", proFix);
return WrapMapper.ok(map);
}
}
2、項目部署服務器後訪問打印日誌的效果
二、指定日誌格式,日誌輸出
1、代碼實現
(1)演示日誌輸出控制器(同上)
(2)在項目的resources目錄下增加logback.xml設置打印格式,logback.xml內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 說明: 1、日誌級別及文件 日誌記錄採用分級記錄,級別與日誌文件名相對應,不同級別的日誌信息記錄到不同的日誌文件中 例如:error級別記錄到log_error_xxx.log或log_error.log(該文件爲當前記錄的日誌文件),而log_error_xxx.log爲歸檔日誌,
日誌文件按日期記錄,同一天內,若日誌文件大小等於或大於2M,則按0、1、2...順序分別命名 例如log-level-2013-12-21.0.log
其它級別的日誌也是如此。 2、文件路徑 若開發、測試用,在Eclipse中運行項目,則到Eclipse的安裝路徑查找logs文件夾,以相對路徑../logs。
若部署到Tomcat下,則在Tomcat下的logs文件中 3、Appender FILEERROR對應error級別,文件名以log-error-xxx.log形式命名
FILEWARN對應warn級別,文件名以log-warn-xxx.log形式命名 FILEINFO對應info級別,文件名以log-info-xxx.log形式命名
FILEDEBUG對應debug級別,文件名以log-debug-xxx.log形式命名 stdout將日誌信息輸出到控制上,爲方便開發測試使用 -->
<configuration>
<springProperty scope="context" name="LOG_HOME" source="spring.application.name"/>
<springProfile name="local">
<property name="LOG_PATH" value="D:/www/logs/common"/> <!-- 日誌保存目錄 -->
</springProfile>
<springProfile name="dev">
<property name="LOG_PATH" value="/data/logs/common" /> <!-- 日誌保存目錄 -->
</springProfile>
<property name="appName" value="common"/>
<property name="maxSaveDays" value="365"/><!-- 日誌最大保存天數 -->
<property name="maxFileSize" value="200MB"/><!-- 單個文件最大大小 -->
<appender name="stdout" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) %green([${LOG_HOME},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]) %magenta(${PID:-}) %white(---) %-20(%yellow([%20.20thread])) %-55(%cyan(%.32logger{30}:%L)) %highlight(- %msg%n)</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="rollingFileConsole" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${appName}-log-console-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
<maxHistory>${maxSaveDays}</maxHistory> <!--max save days -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss} %highlight(%-5level) %green([${LOG_HOME},%X{X-B3-TraceId:-},%X{X-B3-SpanId:-},%X{X-Span-Export:-}]) %magenta(${PID:-}) %white(---) %-20(%yellow([%20.20thread])) %-55(%cyan(%.32logger{30}:%L)) %highlight(- %msg%n)</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<appender name="rollingFileInfo" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${appName}-log-info-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
<maxHistory>${maxSaveDays}</maxHistory> <!--max save days -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{"yyyy-MM-dd HH:mm:ss,SSS"}[%X{userId}|%X{sessionId}][%p][%c{0}-%M]-%m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>DENY</onMatch>
<onMismatch>ACCEPT</onMismatch>
</filter>
</appender>
<appender name="rollingFileError" class="ch.qos.logback.core.rolling.RollingFileAppender">
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/${appName}-log-error-%d{yyyy-MM-dd}.%i.log.zip</fileNamePattern>
<maxHistory>${maxSaveDays}</maxHistory> <!--max save days -->
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<maxFileSize>${maxFileSize}</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%d{"yyyy-MM-dd HH:mm:ss,SSS"}[%X{userId}|%X{sessionId}][%p][%c{0}-%M]-%m%n</pattern>
<charset>UTF-8</charset>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<level>ERROR</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- 爲單獨的包配置日誌級別,若root的級別大於此級別, 此處級別也會輸出 應用場景:生產環境一般不會將日誌級別設置爲trace或debug,但是爲詳細的記錄SQL語句的情況,
可將hibernate的級別設置爲debug,如此一來,日誌文件中就會出現hibernate的debug級別日誌, 而其它包則會按root的級別輸出日誌 -->
<!-- <logger name="org.springframework" level="DEBUG" /> -->
<logger name="com.ibatis" level="DEBUG"/>
<logger name="com.ibatis.common.jdbc.SimpleDataSource" level="DEBUG"/>
<logger name="com.ibatis.common.jdbc.ScriptRunner" level="DEBUG"/>
<logger name="com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate"
level="INFO"/>
<logger name="java.sql.Connection" level="DEBUG"/>
<logger name="java.sql.Statement" level="DEBUG"/>
<logger name="java.sql.PreparedStatement" level="DEBUG"/>
<logger name="com.netflix.discovery" additivity="true" level="ERROR"/>
<!-- 生產環境,將此級別配置爲適合的級別,以名日誌文件太多或影響程序性能 -->
<root level="INFO">
<appender-ref ref="rollingFileConsole"/>
<appender-ref ref="rollingFileInfo"/>
<appender-ref ref="rollingFileError"/>
<appender-ref ref="stdout"/>
</root>
</configuration>
3、項目部署服務器後訪問打印日誌的效果
4、查看日誌記錄文件,效果也一樣,效果圖:
三、項目地址
1、地址:https://github.com/dangnianchuntian/springboot
2、代碼版本:1.5.0-Release
【總結】
1、通過設定日誌格式,輸出的樣式更加人性化,錯誤也更加明顯;
2、這個小小的改變,使得在排查程序時更加的賞心悅目,心情上的開心將在無形中增加排錯的效率;