我正在使用 SBT 1.9.9 scalaVersion := "2.13.9" 为我的项目创建自定义 Log4j 插件
当我在 Log4j XML 配置中指定 packages="com.testserver" 时,一切正常。但是,此属性已被弃用,我尝试在不使用包的情况下配置它,但没有成功。
主要问题是Log4j找不到插件,导致出现以下错误:
[info] ERROR StatusConsoleListener Appenders contains an invalid element or attribute "MetadataFileAppender"
我尝试了多种方法,包括遵循 https://logging.apache.org/log4j/2.x/manual/plugins.html
中描述的推荐设置这是我的项目配置的相关部分:
lazy val core = (project in file("core"))
.settings(
name := "core",
)
lazy val server = (project in file("server"))
.dependsOn(core)
.settings(
Compile / mainClass := Some("com.testserver.Hello"),
libraryDependencies ++= Dependencies.log4j ++ Dependencies.allOthers,
name := "server",
)
lazy val root = (project in file("."))
.dependsOn(server)
.settings(
Compile / run / fork := true,
Compile / mainClass := Some("com.testserver.Hello"),
libraryDependencies ++= Dependencies.log4j,
javaOptions ++= Seq(
"-Dlog4j.configurationFile=server/src/universal/conf/log4j2.xml",
)
)
"org.log4s" %% "log4s" % "1.10.0",
"org.apache.logging.log4j" % "log4j-slf4j-impl" % log4jVersion,
"org.apache.logging.log4j" % "log4j-slf4j2-impl" % log4jVersion,
"org.apache.logging.log4j" % "log4j-core" % log4jVersion ,
"org.apache.logging.log4j" % "log4j-api" % log4jVersion
<?xml version="1.0" encoding="UTF-8"?>
<Configuration strict="true" status="info">
<Properties>
<Property name="logPattern" value="%d{dd-MM-yyyy HH:mm:ss.SSS} %msg%n"/>
<Property name="logLocation" value="/tmp/logs"/>
</Properties>
<Appenders>
<MetadataFileAppender name="MetadataFileAppender" foobar="test" location="${sys:logLocation}" />
<Console name="STDOUT">
<PatternLayout pattern="${logPattern}"/>
</Console>
</Appenders>
<Loggers>
<Root level="info">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>
最后是我的插件
package com.testserver
import org.apache.logging.log4j.core.LogEvent
import org.apache.logging.log4j.core.appender.AbstractAppender
import org.apache.logging.log4j.core.config.{ Node}
import org.apache.logging.log4j.core.config.plugins.{Plugin, PluginAttribute, PluginFactory}
@Plugin(name = "MetadataFileAppender", category = Node.CATEGORY , printObject = true)
class MetadataFileAppender(name: String, foobar: String, location: String)
extends AbstractAppender(name, null, null, false, Array.empty) {
println(s"MetadataFileAppender created - my logic here ${name} ${foobar} ${location}}")
def append(event: LogEvent): Unit = {}
}
object MetadataFileAppender {
// Factory method to create the appender with file path and custom metadata content
@PluginFactory
def createAppender(
@PluginAttribute("name") name: String,
@PluginAttribute("foobar") foobar: String,
@PluginAttribute("location") location: String
): MetadataFileAppender = {
new MetadataFileAppender(name, foobar, location)
}
}
问题总结 如果我在 log4j2.xml 中包含已弃用的 packages="com.testserver" 属性,则 MetadataFileAppender 插件可以正常工作。但是,我需要一个避免使用这个已弃用的属性的解决方案。 Log4j 文档提供了使用 Gradle 和 Maven 设置插件发现的指南,但没有专门针对 SBT,理论上这应该无需额外设置即可工作。
我尝试过的 直接配置:遵循 Log4j 文档中的“正确方法”。 重新检查依赖项和导入:确保正确指定所有 Log4j 依赖项。 我尝试了几个 重构 log4j2.xml:验证 XML 语法和属性。 有谁知道在没有软件包属性的情况下在 SBT 中启用插件发现的正确配置,或者是否需要在 SBT 中进行其他设置才能使其工作?
我还尝试了一些解决方法,包括调整编译器设置和从 GitHub 导入 sbt-assemble-log4j2 插件,但到目前为止没有任何效果。 更多信息: https://github.com/mpollmeier/sbt-assemble-log4j2 任何建议或见解将不胜感激!
相关 log4j 文档指出:
注册插件是通过将 Log4j 插件描述符(即 Log4j2Plugins.dat)放入类路径中来完成的。该文件是在编译时使用
注释处理器生成的。您需要如下配置构建工具才能由 Java 编译器使用PluginProcessor
。PluginProcessor
文档仅提供了 Maven 和 Gradle 的示例,但您需要对 SBT 执行相同的操作。 SBT 中没有任何“魔法”可以自动执行此操作。
所以您应该问的问题是:
据我所知,您可以使用 SBT 在 Java 代码上运行 Java 注释处理器,但不能在 Scala 代码上运行,因为它必须与
javac
编译器一起运行。
相关链接: