配置log4j,以便将在“ERROR”级别发出的任何日志记录器语句路由到单独的文件

rks48beu  于 2023-05-17  发布在  其他
关注(0)|答案(1)|浏览(120)

为了演示我的问题,假设我们有一个简单的应用程序,它有一个顶级包com.foo,以及ui(com.foo.ui)和server(com.foo.server)的子包。我还没有能够编造一个log4j属性文件,这将确保以下内容:

* all ERROR level logging statements in packages including and descending from com.foo are
captured in a separate file under logs/main.log

* any and all messages at any levels (DEBUG,TRACE,INFO,WARN,ERROR) go to both stdout and the file appender.

下面是我尝试过的两个log4j配置和这个玩具应用程序的所有代码。我在运行这个玩具应用程序时遇到的挑战是logs/main.log包含所有级别的消息,而不仅仅是ERROR级别的消息。

首次尝试

#Define root logger options
log4j.rootLogger=TRACE, file, stdout

#Define stdout appender
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
logrj.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-5p %c{1} - %m%n

#Define rolling file appender
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=logs/main.log
log4j.appender.file.Append=true
log4j.appender.file.ImmediateFlush=true
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=5
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %d{Z} [%t] %-5p (%F:%L) - %m%n
log4j.appender.error-log.filter.b=org.apache.log4j.varia.LevelMatchFilter
log4j.appender.error-log.filter.LevelToMatch = ERROR
log4j.appender.error-log.filter.AcceptOnMatch = true
log4j.appender.error-log.Threshold = ERROR

#Define loggers
log4j.logger.com.foo.log4j=TRACE, file, stdout

第二次尝试**

#Define root logger options
log4j.rootLogger=TRACE, file, stdout

#Define stdout appender
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
logrj.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%-5p %c{1} - %m%n

#Define rolling file appender
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=logs/main.log
log4j.appender.file.Append=true
log4j.appender.file.ImmediateFlush=true
log4j.appender.file.MaxFileSize=10MB
log4j.appender.file.MaxBackupIndex=5
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d %d{Z} [%t] %-5p (%F:%L) - %m%n
log4j.appender.error-log.filter.b=org.apache.log4j.varia.LevelRangeFilter
log4j.appender.error-log.filter.LevelMin = ERROR
log4j.appender.error-log.filter.LevelMax = ERROR
log4j.appender.error-log.filter.AcceptOnMatch = true
log4j.appender.error-log.Threshold = ERROR

#Define loggers
log4j.logger.com.foo.log4j=TRACE, file, stdout

构建依赖

以下是我使用的构建依赖项:

plugins {
    // Apply the scala plugin to add support for Scala
    id 'scala'

    // Apply the java-library plugin for API and implementation separation.
    id 'java-library'
}

repositories {
    // Use jcenter for resolving dependencies.
    // You can declare any Maven/Ivy/file repository here.
    jcenter()
}

dependencies {
    // Use Scala 2.13 in our library project
    implementation 'org.scala-lang:scala-library:2.13.2'
    implementation 'org.apache.logging.log4j:log4j-api:2.17.0'
    implementation 'org.apache.logging.log4j:log4j-core:2.17.0'

    // Use Scalatest for testing our library
    testImplementation 'junit:junit:null'
    testImplementation 'org.scalatest:scalatest_2.13:3.1.2'
    testImplementation 'org.scalatestplus:junit-4-12_2.13:3.1.2.0'
    implementation 'log4j:log4j:1.2.17'

    // Need scala-xml at test runtime
    testRuntimeOnly 'org.scala-lang.modules:scala-xml_2.13:1.2.0'
}

班级

下面是App中的三个简单的小类:

------------------------------------
package com.foo

import com.foo.server.Server
import com.foo.ui.UI

object Application extends App {
  val server = Server()
  val ui = new UI(server)
  ui.message("hello")
}

------------------------------------
package com.foo.ui

import com.foo.server.Server
import org.apache.log4j.LogManager

class UI(server: Server) { // mine

  val log = LogManager.getLogger(this.getClass)

  def message(string: String): Unit = {
    log.trace("ui got message " + string)
    server.message(string)
  }
}

------------------------------------
package com.foo.server

import org.apache.log4j.LogManager

case class Server() {
  val log = LogManager.getLogger(this.getClass)

  def message(string: String): Unit = {
    log.info("server got message "+ "message")
    log.error("server raised erorr on  message "+ "message")
  }
}
af7jpaap

af7jpaap1#

非常感谢@PiotrP.Karwasz指出build. gradle中混合依赖项的问题。为了让它正常工作,我们需要解决这个问题。[修复是删除这一行,偷偷在那里:实现'log4j:log4j:1.2.17' ]
我没有意识到的另一件事是log4j 2在一个单独的地方寻找它的属性,而不是以前版本的log4j [ log42.xml与log4j.xml和log4j2.propertieslog4j.properties]。所以说,请参考下面的log4j配置,它能够确保我的应用程序中的所有错误级别(并且只有错误级别)消息出现在logs/real.log下

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="TRACE">
    <Appenders>

        <Console name="CONSOLE" target="SYSTEM_OUT">
            <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n" />
        </Console>

        <RollingFile name="real.log" fileName="logs/real.log"
              append="true" immediateFlush="false" filePattern="logs/$${date:yyyy-MM}/%d{MM-dd-yyyy}-%i-real.log">
            <PatternLayout pattern="%d %-5p [%t] %c (%F:%L) - %m%n"/>
            <Policies>
                <TimeBasedTriggeringPolicy />
                <SizeBasedTriggeringPolicy size="10 MB"/>
            </Policies>
            <Filters>
                <ThresholdFilter level="ERROR" onMatch="ACCEPT" onMismatch="DENY" />
            </Filters>
        </RollingFile>

    </Appenders>
    <Loggers>
        <Root level="ERROR">
            <AppenderRef ref="real.log" />
            <AppenderRef ref="CONSOLE"/>
        </Root>

        <Logger name="com.foo.ui" level="TRACE" />
    </Loggers>
</Configuration>

请注意,关键的事情是ThresholdFilter抛出除ERROR级别以外的所有日志语句。我相信这只在最新的2.x log4j中支持,但不要引用我的话;^)

相关问题