轉載自 logback 中列印自定義參數 (ip 服務名)
由于應用日志被類似ELK的架構收集到了統一的日志管理平台,是以叢集部署的多台伺服器日志會沖突,老闆希望在列印的日志内容中加上伺服器IP加以區分,以此為前提。
一、解決方案
1.1 ClassicConverter實作類
我們建立一個類
com.xxx.utils.IPConverterConfig
并繼承
ch.qos.logback.classic.pattern.ClassicConverter
,内容如下:
package com.xxx.utils;
import ch.qos.logback.classic.pattern.ClassicConverter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* 功能描述: 将ip列印到日志
*
* @author geekziyu
* @version 1.0.0
*/
public class IPConverterConfig extends ClassicConverter {
// 每次 log.info() 都會調用該 converter,是以緩存一下伺服器ip
private String cache;
@Override
public String convert(ILoggingEvent event) {
if (cache != null) {
return cache;
}
String result = "unknown";
try {
result = InetAddress.getLocalHost().getHostAddress();
} catch (UnknownHostException e) {
e.printStackTrace();
}
cache = result;
return result;
}
}
1.2 <conversionRule>标簽
在
logback.xml
中加入
<!--配置規則類的位置-->
<conversionRule conversionWord="ip" converterClass="com.xxx.utils.IPConverterConfig" />
1.3 修改列印格式:
繼續修改
logback.xml
中的
<appender>
-
<encoder>
<pattern>
:
<appender ...(屬性省略沒寫)...>
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%ip] %level [%thread] %logger{36}%msg%n</pattern>
</encoder>
</appender>
注意,列印時用 %ip 來表示該變量。
二、測試效果
2.1 logback.xml
以列印日志到Console為例:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--配置規則類的位置-->
<conversionRule conversionWord="ip" converterClass="com.xxx.utils.IPConverterConfig" />
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%ip] %level [%thread] %logger{36} %msg%n</pattern>
</encoder>
</appender>
<root level="info">
<appender-ref ref="STDOUT"/>
</root>
</configuration>
2.2 測試類Main
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Main {
private static final Logger log = LoggerFactory.getLogger(Main.class);
public static void main(String[] args) {
log.info("Hello World!");
}
}
2.3 運作結果
![](https://img.laitimes.com/img/9ZDMuAjOiMmIsIjOiQnIsIyZuBnL4ETMxAjMzYTNx0SOzkzN0kTM0EjMxEDMyIDMy0iMxUDMzcTMvwVMwIjMwIzLcJTM1AzM3EzLcd2bsJ2Lc12bj5ycn9Gbi52YuAjMwIzZtl2Lc9CX6MHc0RHaiojIsJye.png)
三、補充
3.1 日志檔案的配置
以下
logback.xml
是寫入檔案的代碼:
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="LOG_PATH" value="/opt/app/logs" />
<!--配置規則類的位置-->
<conversionRule conversionWord="ip" converterClass="com.xxx.utils.IPConverterConfig" />
<!-- 輸出日志到檔案,可選擇按照時間與每個檔案大小進行滾動 -->
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/biz.log</file>
<rollingPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>/opt/app/logs/logback/biz-%d{yyyy-MM-dd_HH}.%i.txt</fileNamePattern>
<!-- 每個檔案最大100MB,即在機關時間(例如一個小時)内,可能會産生多個檔案,各檔案以1、2、3…阿拉伯數字來标示 -->
<maxFileSize>100MB</maxFileSize>
<!-- 保留60天(或小時,根據fileNamePattern來決定機關)的曆史日志 -->
<maxHistory>60</maxHistory>
<!-- 所有歸檔檔案(不包括目前檔案)的總大小不超過1GB -->
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%date{yyyy-MM-dd HH:mm:ss.SSS} [%ip] %level [%thread] %logger{36} %msg%n</pattern>
</encoder>
</appender>
<!--将上面配置的“FILE” appender包裝成異步方式來提高性能,但是在高并發寫日志請求的情況下預設會丢棄低級别日志,當然也可以選擇配置不丢棄日志,但業務線程阻塞,注意隻有logback-classic
1.0.4+才支援AsyncAppender -->
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
<!-- 注意一個AsyncAppender隻能引用一個appender,不能引用多個 -->
<appender-ref ref="FILE" />
<!-- 隊列大小(整型,預設值為256,相當于最大可以同時緩存256個寫日志請求到記憶體),值越大,高并發寫日志請求的情況下越能提升程式性能,但同時也會占用更多的堆記憶體。建議結合壓測來調整合适的隊列大小 -->
<queueSize>256</queueSize>
<!-- 門檻值(整型,預設值為隊列大小queueSize的20%)。預設當隊列的剩餘空間小于此門檻值時, 則會丢棄TRACE、DEBUG、INFO級别的日志,保留WARN、ERROR級别的日志
。如果設定為0,表示不丢棄日志,但當隊列滿時,業務線程(不是寫日志的異步線程)會阻塞 -->
<discardingThreshold>0</discardingThreshold>
</appender>
<root level="INFO">
<appender-ref ref="ASYNC_FILE" />
</root>
</configuration>