我有以下CustomConfigurationFactory。但是,并非只是将所有内容都记录到单个文件中,而是将名称'api'记录下来,它似乎是为堆栈跟踪的每一行创建一个新的日志文件?log4j CustomConfigurationFactory为堆栈跟踪的每一行创建一个新的日志文件?
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 PARAM的相关部分:
logging = {
level = "INFO"
appenders = "Stdout,Syslog"
syslog = {
host = "syslog-ng"
port = 515
appname = "api"
facility = "LOCAL0"
}
下面是一些在/ var /日志的内容/ 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”的文件,而是我得到的每创建一个新文件一行堆栈跟踪。任何帮助深表感谢。谢谢!
相关:
和
Send log4j2 stack traces over syslog