代码之家  ›  专栏  ›  技术社区  ›  Adrian

Log4J-类似SiftingAppender的功能

  •  10
  • Adrian  · 技术社区  · 15 年前

    Log4J

    Logger logger = Logger.getLogger(<thread dependent string>);
    FileAppender appender = new FileAppender();
    appender.setFile(fileName);
    appender.setLayout(new PatternLayout(lp.getPattern()));
    appender.setName(<thread dependent string>);
    appender.setThreshold(Level.DEBUG);
    appender.activateOptions();
    logger.addAppender(appender);
    

    一切都很顺利,直到我们意识到我们使用的另一个图书馆- Spring Framework v3.0.0(使用 Commons Logging )-不使用上述技术,只有从log4.configuration文件初始化的appender才能看到Spring日志数据,但运行时创建的appender不能看到。 所以,回到原点。

    LogBack 有附加物- SiftingAppender

    目前,转移到LogBack不是一个选项,所以,被Log4J困住了,我怎样才能实现类似SiftingAppender的功能,同时保持Spring的快乐呢?

    注:弹簧仅用于 JdbcTemplate

    日志4J。logger.org.springframework=调试

    按指示 here .

    5 回复  |  直到 15 年前
        1
  •  4
  •   Kenston Choi    8 年前

    在Log4j2中,我们现在可以使用 RoutingAppender

    RoutingAppender对LogEvents求值,然后将它们路由到一个下级追加器。目标Appender可以是以前配置的Appender,可以由其名称引用,也可以根据需要动态创建Appender。

    从他们的 FAQ

    如何动态写入单独的日志文件? 你看这条路线。您可以在配置中定义多个路由,并将值放入ThreadContext映射中,以确定将此线程中的后续事件记录到哪个日志文件。

        2
  •  3
  •   Community CDub    7 年前

    slf4j api . 有一个名为 jcl-over-sjf4j 它公开了commons日志接口,但将所有日志记录到slf4j API,该API直接指向实现-LogBack。如果您使用的是maven,以下是依赖项:

    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.5.8</version>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.5.8</version>
    </dependency> 
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>0.9.18</version>
    </dependency>
    

    here

        3
  •  3
  •   bpodgursky    11 年前

    我花了一段时间在log4j中寻找类似SiftingAppender的功能(由于某些依赖关系,我们无法切换到logback),最后得到了一个非常好的编程解决方案,使用MDC并在运行时附加logger:

    //  this can be any thread-specific string
    String processID = request.getProcessID();  
    
    Logger logger = Logger.getRootLogger();
    
    //  append a new file logger if no logger exists for this tag
    if(logger.getAppender(processID) == null){
    
      try{
        String pattern = "%d{yy/MM/dd HH:mm:ss} %p %c{2}: %m%n";
        String logfile = "log/"+processID+".log";
    
        FileAppender fileAppender = new FileAppender(
            new PatternLayout(pattern), logfile, true);
        fileAppender.setName(processID);
    
        // add a filter so we can ignore any logs from other threads
        fileAppender.addFilter(new ProcessIDFilter(processID));
    
        logger.addAppender(fileAppender);
      }catch(Exception e){
        throw new RuntimeException(e);
      }
    }
    
    //  tag all child threads with this process-id so we can separate out log output
    MDC.put("process-id", processID);
    
    //whatever you want to do in the thread
    LOG.info("This message will only end up in "+processID+".log!");
    
    MDC.remove("process-id");
    

    上面附加的筛选器只检查特定的进程id:

    public class RunIdFilter extends Filter {
    
      private final String runId;
    
      public RunIdFilter(String runId) {
        this.runId = runId;
      }
    
      @Override
      public int decide(LoggingEvent event) {
        Object mdc = event.getMDC("run-id");
    
        if (runId.equals(mdc)) {
          return Filter.ACCEPT;
        }
    
        return Filter.DENY;
      }
    }
    

    希望这有帮助。

        4
  •  0
  •   Lumpy Oatmeal    15 年前

    我喜欢包括所有的slf4j门面/路由器/你叫他们什么。还要注意“provided”hack,它防止依赖项进入commons日志;以前我使用的是一个名为version-99.0-does-not-exist的假空commons日志库。

    http://blog.springsource.com/2009/12/04/logging-dependencies-in-spring/

    <dependencies>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
    
            <!-- use provided scope on real JCL instead -->
            <!-- <version>99.0-does-not-exist</version> -->
    
            <version>1.1.1</version>
    
            <scope>provided</scope>
        </dependency>
    
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging-api</artifactId>
    
            <!-- use provided scope on real JCL instead -->
            <!-- <version>99.0-does-not-exist</version> -->
    
            <version>1.1</version>
    
            <scope>provided</scope>
        </dependency>
    
        <!-- the slf4j commons-logging replacement -->
        <!-- if any package is using jakarta commons logging this will -->
        <!-- re-route it through slf4j. -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jcl-over-slf4j</artifactId>
    
            <version>${version.slf4j}</version>
        </dependency>
    
        <!-- the slf4j log4j replacement. -->
        <!-- if any package is using log4j this will re-route -->
        <!-- it through slf4j. -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>log4j-over-slf4j</artifactId>
    
            <version>${version.slf4j}</version>
        </dependency>
    
        <!-- the slf4j java.util.logging replacement. -->
        <!-- if any package is using java.util.logging this will re-route -->
        <!-- it through slf4j. -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>jul-to-slf4j</artifactId>
            <version>${version.slf4j}</version>
        </dependency>
    
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
    
            <version>${version.slf4j}</version>
        </dependency>
    
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
    
            <version>${version.logback}</version>
        </dependency>
    </dependencies>
    
    <properties>
        <version.logback>0.9.15</version.logback>
        <version.slf4j>1.5.8</version.slf4j>
    </properties>
    
        5
  •  0
  •   Steve B.    15 年前

    你看过log4j.NDC和MDC吗?这至少允许您将特定于线程的数据标记到日志中。不完全是你的要求,但可能是有用的。有个讨论 here .