1. 程式人生 > >java程式碼實現LogBack動態輸出日誌【無配置檔案純程式碼】

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 
版權宣告:本文為博主原創文章,轉載請附上博文連結!