Logback 自定义日志使用指导

Logback 在 ECP 工程中的 自定义日志使用指导

22人浏览 / 0人评论

摘要:本文将介绍在 ECP 工程中如何使用 Logback 进行自定义日志配置。主要关注 Logback 的编程式配置使用,包括解决的问题、编程式配置的概念和优势,以及如何使用编程式配置 Logback。

 Logback 框架支持两种配置方式:1,xml配置;2,编程式配置。ecp g工程中已经配置好了xml文件相关信息查看https://htt.histo.cn/article/26

什么是编程是配置

  • Logback 编程式配置是通过编写代码来动态配置和管理 Logback 日志组件的行为和属性。

为什么要使用编程式 Logback?

ecp 中默认配置为xml配置。xml 配置目前只能更改调试日志的调试等级,如果想要根据不同的业务场景去选择日志的输出方式,比如说针对我们特定的一些业务场景,既要输出到控制台又要输出到日志文件,我们只能重启项目才能实现。当遇到类似的问题编程式配置有以下优势

编程式配置相比于 XML 配置优势:

  • 通过编程式配置,可以根据业务规则动态调整系统的配置
  • 通过编程式配置,可以实时更改配置

编程式配置相比于 XML 配置劣势:

  • 复杂的配置需求,可能需要编写更多的逻辑和代码来处理,增加了维护成本
  • XML 配置可以更直观和方便

如何使用编程式 Logback?

  • 在ecp项目中已经引入了logback相关依赖,以下为demo实现四个功能:默认输出到控制台,设置日志的显示方式,设置日志输出级别,设置是否输出到文件
  • 使用步骤如下:
  • 1,创建 Logback 配置类:编写一个配置类,继承ContextAwareBase 类并实现Configurator接口
package cn.histo.desk.logback;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.Configurator;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.ConsoleAppender;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.encoder.LayoutWrappingEncoder;
import ch.qos.logback.core.spi.ContextAware;
import ch.qos.logback.core.spi.ContextAwareBase;
import ch.qos.logback.core.util.StatusPrinter;

/**
 * @author Verite
 */
public class MyConfigurator extends ContextAwareBase implements Configurator {
   /**
    * 定义ConsoleAppender的名称
    */
private static final String CONSOLE = "console";
   /**
    * 定义FileAppender的名称
    */
private static final String FILE = "file";
   /**
    * 定义是否输出到文件
    */
private Boolean isOutPutFile = false;
   /**
    * 文件名称
    */
private String fileName = "defaultFile";
   /**
    * 日志等级默认为 INFO
    */
private Level level = Level.INFO;
   /**
    * 日志输出的显示格式
    */
private String pattern = "MyConfigurator %d{yyyy-mm-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n";

   public MyConfigurator(Boolean isOutPutFile, String fileName, Level level) {
      this.isOutPutFile = isOutPutFile;
      this.fileName = fileName;
      this.level = level;
   }

   public MyConfigurator(Boolean isOutPutFile, String fileName) {
      this.isOutPutFile = isOutPutFile;
      this.fileName = fileName;
   }

   public MyConfigurator(Boolean isOutPutFile, String fileName, String pattern) {
      this.isOutPutFile = isOutPutFile;
      this.fileName = fileName;
      this.pattern = pattern;
   }

   public MyConfigurator(ContextAware declaredOrigin, Boolean isOutPutFile, String fileName, String pattern) {
      super(declaredOrigin);
      this.isOutPutFile = isOutPutFile;
      this.fileName = fileName;
      this.pattern = pattern;
   }

   @Override
   public void configure(LoggerContext loggerContext) {
      addInfo("Setting up default MyConfigurator.");

      ConsoleAppender<ILoggingEvent> consoleAppender = consoleAppender(loggerContext);

      Logger rootLogger = loggerContext.getLogger(Logger.ROOT_LOGGER_NAME);
      rootLogger.addAppender(consoleAppender);
      rootLogger.setLevel(level);
      if (Boolean.TRUE.equals(isOutPutFile)) {
         FileAppender<ILoggingEvent> fileAppender = fileAppender(loggerContext);
         rootLogger.addAppender(fileAppender);
      }
   }
   /**
    * ConsoleAppender 定义
    * @param loggerContext
* @return
    */
private ConsoleAppender<ILoggingEvent> consoleAppender(LoggerContext loggerContext) {
      ConsoleAppender<ILoggingEvent> consoleAppender = new ConsoleAppender<>();
      StatusPrinter.print(loggerContext);

      consoleAppender.setContext(loggerContext);
      consoleAppender.setName(CONSOLE);
      LayoutWrappingEncoder<ILoggingEvent> encoder = new LayoutWrappingEncoder<ILoggingEvent>();
      encoder.setContext(loggerContext);

      // same as
      PatternLayout layout = new PatternLayout();
      layout.setPattern(pattern);
      layout.setContext(loggerContext);
      layout.start();
      encoder.setLayout(layout);

      consoleAppender.setEncoder(encoder);
      consoleAppender.start();
      return consoleAppender;
   }

   /**
    * FileAppender 定义
    * @param loggerContext
* @return
    */
private FileAppender<ILoggingEvent> fileAppender(LoggerContext loggerContext) {
      FileAppender<ILoggingEvent> fileAppender = new FileAppender<>();
      StatusPrinter.print(loggerContext);
      fileAppender.setName(FILE);
      fileAppender.setContext(loggerContext);
      fileAppender.setFile("target\\test\\" + fileName + ".log");

      fileAppender.setAppend(false);
      PatternLayout layout = new PatternLayout();
      layout.setPattern(pattern);
      layout.setContext(loggerContext);
      layout.start();

      LayoutWrappingEncoder<ILoggingEvent> encoder = new LayoutWrappingEncoder<ILoggingEvent>();
      encoder.setContext(loggerContext);
      encoder.setLayout(layout);
      fileAppender.setEncoder(encoder);
      fileAppender.start();
      return fileAppender;
   }


}

 


 
  • 2,使用配置类
package cn.histo.desk.logback;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.spi.Configurator;
import org.junit.Before;
import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * @author Verite
 * @date 2023/6/28 13:42
 */
public class MyTest {

   private final Configurator myConfigurator = new MyConfigurator(true,"bbb", Level.DEBUG);
   private final LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();

   @Before
   public void setUp() {
      this.myConfigurator.setContext(context);
      context.reset();
      this.myConfigurator.configure(context);
   }

   final static Logger logger = LoggerFactory.getLogger(MyTest.class);

   @Test
   public void loggerTest() {
      logger.info("Entering application.");
      logger.debug("Entering application.");
      logger.info("Exiting application.");
   }
}

 


 

总体而言,编程式配置 Logback 可以为 ECP 工程带来更高效、更精确的日志记录和管理,为系统监控和问题排查提供有力支持。

posted @ 2023-07-10 13:23  Verite  阅读(216)  评论(0)    收藏  举报