zoukankan      html  css  js  c++  java
  • logback运行时动态创建日志文件

    package com.example.demo.config;
    
    import ch.qos.logback.classic.Level;
    import ch.qos.logback.classic.Logger;
    import ch.qos.logback.classic.LoggerContext;
    import ch.qos.logback.core.ConsoleAppender;
    import ch.qos.logback.core.rolling.RollingFileAppender;
    import org.slf4j.LoggerFactory;
    import org.springframework.stereotype.Component;
    
    import java.util.concurrent.ConcurrentHashMap;
    
    
    @Component
    public class LoggerBuilder {
        private ConcurrentHashMap<String, Logger> container = new ConcurrentHashMap<>();
    
        public Logger getLogger(String name,Class<?> clazz) {
            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,clazz);
                container.put(name, logger);
            }
            return logger;
        }
    
        private Logger build(String name,Class<?> clazz) {
            RollingFileAppender errorAppender = new AppenderFactory().createRollingFileAppender(name, Level.ERROR);
            RollingFileAppender infoAppender = new AppenderFactory().createRollingFileAppender(name, Level.INFO);
            ConsoleAppender consoleAppender = new AppenderFactory().createConsoleAppender();
            LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
            Logger logger = context.getLogger(clazz + " [" + name + "]");
            //设置不向上级打印信息
            logger.setAdditive(false);
            logger.addAppender(errorAppender);
            logger.addAppender(infoAppender);
            logger.addAppender(consoleAppender);
    
            return logger;
        }
    
    }
    

      

    package com.example.demo.config;
    
    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.ConsoleAppender;
    import ch.qos.logback.core.FileAppender;
    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 static ch.qos.logback.core.spi.FilterReply.ACCEPT;
    import static ch.qos.logback.core.spi.FilterReply.DENY;
    
    public class AppenderFactory {
        public RollingFileAppender createRollingFileAppender(String name, Level level) {
    
            LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
    
            RollingFileAppender appender = new RollingFileAppender();
            //这里设置级别过滤器
            appender.addFilter(createLevelFilter(level));
    
            //设置上下文,每个logger都关联到logger上下文,默认上下文名称为default。
            // 但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
            appender.setContext(context);
            //appender的name属性
            appender.setName("file-" + level.levelStr.toLowerCase());
            //设置文件名
            appender.setFile(OptionHelper.substVars("${LOG_HOME}/" + name + "/" + level.levelStr.toLowerCase() + ".log", context));
    
            appender.setAppend(true);
    
            appender.setPrudent(false);
    
            //加入下面两个节点
            appender.setRollingPolicy(createSizeAndTimeBasedRollingPolicy(name,level,context,appender));
            appender.setEncoder(createEncoder(context));
            appender.start();
            return appender;
        }
    
        public ConsoleAppender createConsoleAppender(){
            LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
            ConsoleAppender appender = new ConsoleAppender();
            appender.setContext(context);
            appender.setName("file-console");
            appender.addFilter(createLevelFilter(Level.DEBUG));
            appender.setEncoder(createEncoder(context));
            appender.start();
            return appender;
        }
    
        private SizeAndTimeBasedRollingPolicy createSizeAndTimeBasedRollingPolicy(String name, Level level, LoggerContext context, FileAppender appender) {
            //设置文件创建时间及大小的类
            SizeAndTimeBasedRollingPolicy policy = new SizeAndTimeBasedRollingPolicy();
            //文件名格式
            String fp = OptionHelper.substVars("${LOG_HOME}/" + name + "/backup/" + level.levelStr.toLowerCase() + "-%d{yyyy-MM-dd}.log.%i", context);
            //最大日志文件大小
            policy.setMaxFileSize(FileSize.valueOf("5MB"));
            //设置文件名模式
            policy.setFileNamePattern(fp);
            //设置最大历史记录为30条
            policy.setMaxHistory(30);
            //总大小限制
            policy.setTotalSizeCap(FileSize.valueOf("32GB"));
            //设置父节点是appender
            policy.setParent(appender);
            //设置上下文,每个logger都关联到logger上下文,默认上下文名称为default。
            // 但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
            policy.setContext(context);
            policy.start();
            return policy;
        }
    
        private PatternLayoutEncoder createEncoder(LoggerContext context) {
            PatternLayoutEncoder encoder = new PatternLayoutEncoder();
            //设置上下文,每个logger都关联到logger上下文,默认上下文名称为default。
            // 但可以使用<contextName>设置成其他名字,用于区分不同应用程序的记录。一旦设置,不能修改。
            encoder.setContext(context);
            //设置格式
            encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} %msg%n");
            encoder.start();
            return encoder;
        }
    
        private LevelFilter createLevelFilter(Level level) {
            LevelFilter levelFilter = new LevelFilter();
            levelFilter.setLevel(level);
            levelFilter.setOnMatch(ACCEPT);
            levelFilter.setOnMismatch(DENY);
            levelFilter.start();
            return levelFilter;
        }
    
    }
    ${LOG_HOME} 是 logback-spring.xml中的变量 ,如下
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
        <include resource="org/springframework/boot/logging/logback/base.xml"/>
      <!--spring.application.name 是 application.yml 中设置--> 
      <springProperty scope="context" name="app_name" source="spring.application.name"/> 
      <property scope="context" name="LOG_HOME" value="logs/${app_name}"/> 
    </configuration>

      测试代码如下,使用了swagger

    @RestController
    @RequestMapping("/test")
    @Api(tags = "Test", description = "测试接口")
    public class controller {
    
        @Autowired
        private LoggerBuilder loggerBuilder;
    
        @ApiOperation("测试")
        @PostMapping("/test")
        public ResultVO test(String name) {
            Logger logger = loggerBuilder.getLogger(name,controller.class);
    
            logger.info("测试...我系{}",name);
    
            return ResultVO.success();
        }
    }
    

      以上代码运行在 springboot(2.2.2.RELEASE) + logback、springboot(1.5.8.RELEASE) + logback  均有效

  • 相关阅读:
    函数声明例子
    税收工资分级
    attribute函数
    输出结果有误
    scanf_s()函数与数组,运行环境VS2013
    格式化输出
    功能点介绍和用户场景
    第二次作业合作版
    word count
    第一次作业
  • 原文地址:https://www.cnblogs.com/leohe/p/12117183.html
Copyright © 2011-2022 走看看