[英]log4j CustomConfigurationFactory creating a new log file for every line of a stack trace?
我有以下CustomConfigurationFactory。 但是,似乎不僅僅是將所有內容都記錄到一個名為“ api”的文件中,而是似乎正在為堆棧跟蹤的每一行創建一個新的日志文件?
import com.example.api.{LoggingConfig, SyslogConfig}
import org.apache.logging.log4j.Level
import org.apache.logging.log4j.core.LoggerContext
import org.apache.logging.log4j.core.appender.ConsoleAppender
import org.apache.logging.log4j.core.config.builder.api._
import org.apache.logging.log4j.core.config.builder.impl.BuiltConfiguration
import org.apache.logging.log4j.core.config.plugins.Plugin
import org.apache.logging.log4j.core.config.{ConfigurationFactory, ConfigurationSource, Order}
@Plugin(name = "CustomConfigurationFactory", category = ConfigurationFactory.CATEGORY)
@Order(50)
class LoggingConfFileConfigurationFactory(loggingConfig: LoggingConfig) extends ConfigurationFactory{
override def getConfiguration(loggerContext: LoggerContext, source: ConfigurationSource): BuiltConfiguration = {
getConfiguration(loggerContext, source.toString(), null)
}
override def getConfiguration(loggerContext: LoggerContext, name: String, configLocation: URI): BuiltConfiguration = {
val builder: ConfigurationBuilder[BuiltConfiguration] = ConfigurationBuilderFactory.newConfigurationBuilder();
createConfiguration(name, builder);
}
override def getSupportedTypes(): Array[String] = {
Array[String]("*")
}
private def createConfiguration(name:String, builder: ConfigurationBuilder[BuiltConfiguration]): BuiltConfiguration = {
builder.setConfigurationName(name)
builder.setStatusLevel(Level.ERROR) //internal log4j level of logging
val consoleAppenderBuilder: AppenderComponentBuilder = builder.newAppender("Stdout", "CONSOLE")
.addAttribute("target", ConsoleAppender.Target.SYSTEM_OUT)
consoleAppenderBuilder.add(builder.newLayout("PatternLayout")
.addAttribute("pattern", "%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"))
builder.add(consoleAppenderBuilder)
if(loggingConfig.appenders.contains("Syslog")) {
builder.add(createSyslogAppender(loggingConfig.syslogConfig, builder))
}
val rootLogger = builder.newRootLogger(Level.valueOf(loggingConfig.level))
for(appender <- loggingConfig.appenders) {
rootLogger.add(builder.newAppenderRef(appender))
}
for(logger <- loggingConfig.loggers) {
builder.add(builder.newLogger(logger.name, logger.level))
}
builder.add(rootLogger)
builder.build()
}
private def createSyslogAppender(syslogConfig: Option[SyslogConfig], builder: ConfigurationBuilder[BuiltConfiguration]) = {
val config = syslogConfig match {
case Some(x) => x
case None => SyslogConfig("syslog-ng", 515, "api", "LOCAL0")
}
val messageFormat = builder.newComponent("KeyValuePair")
messageFormat.addAttribute("key", "class")
messageFormat.addAttribute("value", "%logger{36}")
builder.newAppender("Syslog", "Syslog")
.addAttribute("format", "RFC5424")
.addAttribute("host",
loggingConfig.syslogConfig match {
case Some(x) => x.host
case None => "syslog-ng"
})
.addAttribute("port", config.port)
.addAttribute("protocol", "TCP")
.addAttribute("appName", config.appName)
.addAttribute("includeMDC", "true")
.addAttribute("mdcId", "mdc")
.addAttribute("facility", config.facility)
.addAttribute("newLine", "true")
.addAttribute("messageId", "Log")
.addAttribute("id", config.appName)
.addComponent(
builder.newComponent("LoggerFields")
.addComponent(messageFormat)
)
}
}
這是我的application.conf的相關部分,將其作為loggingConfig構造函數參數注入上述類中:
logging = {
level = "INFO"
appenders = "Stdout,Syslog"
syslog = {
host = "syslog-ng"
port = 515
appname = "api"
facility = "LOCAL0"
}
這是/ var / log / syslog-ng目錄的一些內容。
ls /var/log/syslog-ng/
java.lang.Thread.run(Thread.java
slick.jdbc.Invoker.foreach(Invoker.scala
com.mysql.cj.jdbc.PreparedStatement.execute(PreparedStatement.java
slick.jdbc.StatementInvoker.foreach(StatementInvoker.scala
api
這些是我正在使用的log4j的版本:
"org.apache.logging.log4j" % "log4j-api" % "2.8",
"org.apache.logging.log4j" % "log4j-core" % "2.8",
"com.typesafe.scala-logging" %% "scala-logging" % "3.5.0",
"org.apache.logging.log4j" % "log4j-slf4j-impl" % "2.8"
我希望所有日志都進入“ api”文件,但是我正在為堆棧跟蹤的每一行創建一個新文件。 任何幫助深表感謝。 謝謝!
有關:
Log4j2 Syslog追加器(TCP協議)在多行中發送異常stacktrace並調整錯誤的日志級別
和
這里的問題是,通過TCP發送時,斷行符(“ \\ n”)被認為是syslog消息的結尾。
https://stackoverflow.com/a/40590058/5300930
https://jira.qos.ch/browse/LOGBACK-413
https://github.com/rsyslog/rsyslog/issues/1165
我的解決方法是格式化堆棧跟蹤以對每行使用除換行符以外的內容:
我改變了這個:
logger.error(s"Trace: %s".format(t.getStackTrace.mkString("\n")))
對此:
logger.error(s"Trace: %s".format(t.getStackTrace.mkString(" -> ")))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.