ilovecomputer66 发表于 2024-2-18 13:20

java中用logback,如何实现,通过代码决定某个log写入哪个文件名的log文件?

本帖最后由 ilovecomputer66 于 2024-2-18 17:20 编辑

目的是想实现,为每场战斗,打印输出到以battleId(我下面代码中,battleId用UUID代替生成)为文件名的log文件中,从而方便测试。我按照网上方法,这么写的。结果无效,不会生成到自己指定的log文件中

Main.java

import java.util.UUID;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.filter.LevelFilter;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;
import ch.qos.logback.core.spi.FilterReply;
import ch.qos.logback.core.util.StatusPrinter;

public class Main {

      public static void main(String[] args) {
                LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
                Logger logger = (Logger) LoggerFactory.getLogger(Main.class);

                // 创建一个FileAppender
                FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
                fileAppender.setContext(loggerContext);

                // 设置encoder
                PatternLayoutEncoder encoder = new PatternLayoutEncoder();
                encoder.setContext(loggerContext);
                encoder.setPattern("[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %logger{36} - %msg%n");
                encoder.start();

                // 设置FileAppender的文件名
                fileAppender.setFile("/log/specificLog/" + UUID.randomUUID().toString());
                fileAppender.setEncoder(encoder);
                fileAppender.start();

                // 设置FileAppender的日志级别
                fileAppender.addFilter(createLevelFilter(Level.INFO));

                // 添加FileAppender到Logger中
                logger.addAppender(fileAppender);

                // 打印logback的内部状态
                StatusPrinter.print(loggerContext);

                logger.info("info");
                logger.error("error");

                // 移除FileAppender
                logger.detachAppender(fileAppender);
                // 停止encoder和FileAppender
                encoder.stop();
                fileAppender.stop();

                // 打印logback的内部状态
                StatusPrinter.print(loggerContext);
      }

      // 创建LevelFilter
      private static LevelFilter createLevelFilter(Level level) {
                LevelFilter levelFilter = new LevelFilter();
                levelFilter.setLevel(level);
                levelFilter.setOnMatch(FilterReply.ACCEPT);
                levelFilter.setOnMismatch(FilterReply.DENY);
                levelFilter.start();
                return levelFilter;
      }
}


logback的配置文件:
<?xml version="1.0" encoding="UTF-8"?>
<!-- 勿对此文件进行格式整理,eclipse自动整理会换行<encoder><pattern>中的格式,导致log也被换行 -->
<configuration>
      <appender name="console"
                class="ch.qos.logback.core.ConsoleAppender">
                <encoder>
                        <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %logger{36} - %msg%n</pattern>
                </encoder>
      </appender>

      <appender name="file"
                class="ch.qos.logback.core.rolling.RollingFileAppender">
                <File>log/MainLog.log</File>
                <rollingPolicy
                        class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
                        <FileNamePattern>log/MainLog-%d{yyyy-MM-dd}.%i.log</FileNamePattern>
                        <MaxHistory>365</MaxHistory>
                        <TimeBasedFileNamingAndTriggeringPolicy
                              class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                              <MaxFileSize>1000MB</MaxFileSize>
                        </TimeBasedFileNamingAndTriggeringPolicy>
                </rollingPolicy>
                <encoder>
                        <pattern>[%-5level] %d{yyyy-MM-dd HH:mm:ss.SSS} %logger{36} - %msg%n</pattern>
                        <charset class="java.nio.charset.Charset">UTF-8</charset>
                </encoder>
      </appender>
      
      <root>
                <level value="error" />
                <level value="warn" />
                <level value="info" />
                <appender-ref ref="file" />
                <appender-ref ref="console" />
      </root>

</configuration>   



通过看打印出来的logback内部状态。最后有一个FileAppender

11:15:57,649 |-INFO in ch.qos.logback.core.FileAppender - File property is set to

ilovecomputer66 发表于 2024-2-18 13:43

补充: 麻烦指出上面写法的错误之处。而不要说换用SiftingAppender结合 MDC。因为我同时并发的战斗可能好几百个。肯定不能全局设置MDC的。只能在每个战斗类实例中,用上面这种很灵活的代码实现

xingdongpai 发表于 2024-2-18 13:49

试试用阿里的反编译跟踪 阿里巴巴Arthas

十九点五厘米 发表于 2024-2-18 15:09

可以参考这个https://blog.csdn.net/W_Meng_H/article/details/132830835

ilovecomputer66 发表于 2024-2-18 15:27

本帖最后由 ilovecomputer66 于 2024-2-18 15:44 编辑

十九点五厘米 发表于 2024-2-18 15:09
可以参考这个https://blog.csdn.net/W_Meng_H/article/details/132830835
并不是。它那是不是代码定义的,还是写死到了xml中。而且就算是它自己要实现的功能,代码都不完整


说白了。我是希望,完全用代码实现打log到指定文件。而完全不需要配置在logback.xml(xml中仅配置默认的log输出,就像我1楼那样)

ilovecomputer66 发表于 2024-2-18 15:28

xingdongpai 发表于 2024-2-18 13:49
试试用阿里的反编译跟踪 阿里巴巴Arthas

你的答案可以灌水全部java的问题

cwl 发表于 2024-2-18 16:13

可以试一下这个方式,动态注册FileAppender,然后通过名称调用就可以了,我这边测试是可以的

package org.example;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.core.FileAppender;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DynamicAppenderExample {

    public static void addFileAppenderToLogger(String loggerName, String logFileName) {
      // 获取Logger上下文
      LoggerContext context = (LoggerContext) LoggerFactory.getILoggerFactory();
      
      // 创建一个新的FileAppender
      FileAppender fileAppender = new FileAppender();
      fileAppender.setContext(context);
      fileAppender.setName("DYNAMIC_APPENDER_" + logFileName);
      fileAppender.setFile(logFileName);
      
      // 设置编码器
      PatternLayoutEncoder encoder = new PatternLayoutEncoder();
      encoder.setContext(context);
      encoder.setPattern("%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{35} - %msg%n");
      encoder.start();
      
      // 将编码器附加到appender
      fileAppender.setEncoder(encoder);
      fileAppender.start();
      
      // 获取或创建Logger实例
      ch.qos.logback.classic.Logger logbackLogger = context.getLogger(loggerName);
      logbackLogger.addAppender(fileAppender);
      logbackLogger.setAdditive(false); // 不向上级logger传递日志
    }

    public static void main(String[] args) {
      String log1Name= "log1";
      String log2Name= "log2";
      addFileAppenderToLogger(log1Name, "log1.log");
      addFileAppenderToLogger(log2Name, "log2.log");
      
      Logger logger1 = LoggerFactory.getLogger(log1Name);
      logger1.info("11111111111111111111");
      
      Logger logger2 = LoggerFactory.getLogger(log2Name);
      logger2.info("2222222222222222222");
   
      addFileAppenderToLogger("log3", "log3.log");
      Logger logger3 = LoggerFactory.getLogger("log3");
      logger3.info("3333333333333");
    }
}
页: [1]
查看完整版本: java中用logback,如何实现,通过代码决定某个log写入哪个文件名的log文件?