java程式碼實現LogBack動態輸出日誌【無配置檔案純程式碼】
需求:
需要傳入某一個檔案或者類或者方法的名字,生成對應日誌檔案,且每一個傳入名字的檔案單獨有一個資料夾,子資料夾為日期,日期資料夾裡面包含warn.log,error.log,debug.log,info.log。通過過濾器實現只打印對應級別的日誌。
遇到的問題:
度娘了很久,網上關於logback的幾乎都是xml進行配置的,但是經過嘗試,xml配置的方式不能直接進行動態的輸出,故此方法暫時淘汰,遂想到用純程式碼的方式,嘗試了許多次才得到正確的結果,所以記錄下來,以免今後少走彎路。
內容:
1.建立LoggerBuilder類,這個類相當於一個日誌工具類,之後其他類需要用日誌的時候,直接呼叫它的方法就好了。
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.core.rolling.RollingFileAppender;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.util.HashMap;
import java.util.Map;
/**
* @author Wzy525110
*/
@Component
public class LoggerBuilder {
private static final Map<String,Logger> container = new HashMap<>();
public Logger getLogger(String name) {
Logger logger = container.get(name);
if(logger != null) {
return logger;
}
synchronized (LoggerBuilder.class) {
logger = container.get(name);
if(logger != null) {
return logger;
}
logger = build(name);
container.put(name,logger);
}
return logger;
}
private static Logger build(String name) {
RollingFileAppender errorAppender =new AppenderTest().getAppender(name,Level.ERROR);
RollingFileAppender infoAppender =new AppenderTest().getAppender(name,Level.INFO);
RollingFileAppender warnAppender =new AppenderTest().getAppender(name,Level.WARN);
RollingFileAppender debugAppender =new AppenderTest().getAppender(name,Level.DEBUG);
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
Logger logger = context.getLogger("FILE-" + name);
//設定不向上級列印資訊
logger.setAdditive(false);
logger.addAppender(errorAppender);
logger.addAppender(infoAppender);
logger.addAppender(warnAppender);
logger.addAppender(debugAppender);
return logger;
}
}
2.建立AppenderTest類,這個類給LoggerBuilder動態提供appender
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.filter.LevelFilter;
import ch.qos.logback.core.rolling.RollingFileAppender;
import ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy;
import ch.qos.logback.core.util.FileSize;
import ch.qos.logback.core.util.OptionHelper;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import java.text.DateFormat;
import java.util.Date;
import java.util.Locale;
/**
* 這個類是給日誌動態提供appender
* @author Wzy525110
*/
@Component
public class GetTheAppender {
/**
* 通過傳入的名字和級別,動態設定appender
* @param name
* @param level
* @return
*/
public RollingFileAppender getAppender(String name, Level level){
DateFormat format = DateFormat.getDateInstance(DateFormat.MEDIUM, Locale.SIMPLIFIED_CHINESE);
LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
//這裡是可以用來設定appender的,在xml配置檔案裡面,是這種形式:
// <appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
RollingFileAppender appender = new RollingFileAppender();
// ConsoleAppender consoleAppender = new ConsoleAppender();
//這裡設定級別過濾器
LevelController levelController = new LevelController();
LevelFilter levelFilter = levelController.getLevelFilter(level);
levelFilter.start();
appender.addFilter(levelFilter);
//設定上下文,每個logger都關聯到logger上下文,預設上下文名稱為default。
// 但可以使用<contextName>設定成其他名字,用於區分不同應用程式的記錄。一旦設定,不能修改。
appender.setContext(context);
//appender的name屬性
appender.setName("FILE-" + name);
//設定檔名
appender.setFile(OptionHelper.substVars("E:/eppLog/"+ name+"/" + format.format(new Date())+"/"+ level.levelStr + ".log",context));
appender.setAppend(true);
appender.setPrudent(false);
//設定檔案建立時間及大小的類
SizeAndTimeBasedRollingPolicy policy = new SizeAndTimeBasedRollingPolicy();
//檔名格式
String fp = OptionHelper.substVars("E:/eppLog/"+ name +"/" + format.format(new Date())+"/"+ level.levelStr + "/.%d{yyyy-MM-dd}.%i.log",context);
//最大日誌檔案大小
policy.setMaxFileSize(FileSize.valueOf("128MB"));
//設定檔名模式
policy.setFileNamePattern(fp);
//設定最大歷史記錄為15條
policy.setMaxHistory(15);
//總大小限制
policy.setTotalSizeCap(FileSize.valueOf("32GB"));
//設定父節點是appender
policy.setParent(appender);
//設定上下文,每個logger都關聯到logger上下文,預設上下文名稱為default。
// 但可以使用<contextName>設定成其他名字,用於區分不同應用程式的記錄。一旦設定,不能修改。
policy.setContext(context);
policy.start();
PatternLayoutEncoder encoder = new PatternLayoutEncoder();
//設定上下文,每個logger都關聯到logger上下文,預設上下文名稱為default。
// 但可以使用<contextName>設定成其他名字,用於區分不同應用程式的記錄。一旦設定,不能修改。
encoder.setContext(context);
//設定格式
encoder.setPattern("%d %p (%file:%line\\)- %m%n");
encoder.start();
//加入下面兩個節點
appender.setRollingPolicy(policy);
appender.setEncoder(encoder);
appender.start();
return appender;
}
}
注意:每一個節點都需要.start(),才能加入到這個類拼湊出來的格式中。
3.建立LevelController類,這個類主要是通過level動態的給日誌生成過濾器
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.filter.LevelFilter;
import static ch.qos.logback.core.spi.FilterReply.ACCEPT;
import static ch.qos.logback.core.spi.FilterReply.DENY;
/**
* 這個類的作用是給日誌通過level設定過濾器
* @author Wzy525110
*/
public class LevelController {
/**
* 通過level設定過濾器
* @param level
* @return
*/
public LevelFilter getLevelFilter(Level level){
LevelFilter levelFilter = new LevelFilter();
levelFilter.setLevel(level);
levelFilter.setOnMatch(ACCEPT);
levelFilter.setOnMismatch(DENY);
return levelFilter;
}
}
這樣,logback的工具類就OK了,可以正常在其他類進行使用了!
測試類如下:
import com.wzy.common.LoggerBuilder;
import ch.qos.logback.classic.Logger;
/**
* @author Wzy525110
*/
public class LogTest {
public static void main(String[] args) {
LoggerBuilder loggerBuilder =new LoggerBuilder();
Logger logger = loggerBuilder.getLogger("test");
logger.debug("shuai1 +++++++++++++++++++++++++++++++++++++debug");
logger.warn("shuai2 +++++++++++++++++++++++++++++++++++++warn");
logger.info("shuai3 +++++++++++++++++++++++++++++++++++++info");
logger.error("shuai4 +++++++++++++++++++++++++++++++++++++error");
}
}
輸出:
使用log4j生成動態日誌檔案-檔名根據時間自動生成 - spring292713
log4j.propertiespeizhi
---------------------
作者:一個奔三的胖墩兒
來源:CSDN
原文:https://blog.csdn.net/weixin_42258128/article/details/81942796
版權宣告:本文為博主原創文章,轉載請附上博文連結!