为了演示我的问题,假设我们有一个简单的应用程序,它有一个顶级包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")
}
}
1条答案
按热度按时间af7jpaap1#
非常感谢@PiotrP.Karwasz指出build. gradle中混合依赖项的问题。为了让它正常工作,我们需要解决这个问题。[修复是删除这一行,偷偷在那里:实现'log4j:log4j:1.2.17' ]
我没有意识到的另一件事是log4j 2在一个单独的地方寻找它的属性,而不是以前版本的log4j [ log42.xml与log4j.xml和log4j2.propertieslog4j.properties]。所以说,请参考下面的log4j配置,它能够确保我的应用程序中的所有错误级别(并且只有错误级别)消息出现在logs/real.log下
请注意,关键的事情是ThresholdFilter抛出除ERROR级别以外的所有日志语句。我相信这只在最新的2.x log4j中支持,但不要引用我的话;^)