Ich habe die folgende CustomConfigurationFactory. Anstatt nur alles in einer einzigen Datei zu protokollieren, nenne es "api", scheint es eine neue Protokolldatei für jede Zeile eines Stack-Trace zu erstellen.log4j CustomConfigurationFactory Erstellen einer neuen Protokolldatei für jede Zeile eines Stack-Trace?
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)
)
}
}
Hier ist der relevante Teil meiner application.conf, die in der obigen Klasse, die als loggingConfig Konstruktor param injiziert wird: sind
logging = {
level = "INFO"
appenders = "Stdout,Syslog"
syslog = {
host = "syslog-ng"
port = 515
appname = "api"
facility = "LOCAL0"
}
Hier sind einige der Inhalte des/var/log/syslog-ng-Verzeichnis.
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
Dies sind die Versionen von log4j Ich verwende:
"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"
ich alle Protokolle erwarten in den ‚api‘ Datei zu gehen, sondern stattdessen eine neue Datei für jeden Ich erhalte erstellt Linie einer Stapelspur. Jede Hilfe wird sehr geschätzt. Vielen Dank!
Verwandte:
und
Send log4j2 stack traces over syslog