payara-micro - Payara Micro:如何使用 slf4j(或 log4j2)登录?
问题描述
我在最近的一个项目中使用 Payara Micro(捆绑的 ueberjar),但我在记录时遇到了困难。似乎 Payara Micro 默认使用 JUL,这不符合我的需求。我想改用 Log4J 2,最好是通过 slf4j。不幸的是,我找不到太多信息。首先,我想参考以下链接...
https://blog.payara.fish/the-basics-of-logging-in-payara-server
...它说:“Payara Micro 也可以调整为使用其他日志框架,如 Logback 和 Log4J2。” 听起来不错,但处理这个问题的唯一来源似乎是以下示例项目:https ://github.com/hei1233212000/payara-micro-log4j2 。然而它是从 2017 年开始的,似乎已经过时了,因为它没有使用 payara micro maven 插件。不过,我想重点是:
- 将必要的日志记录 jar 添加到包中
- 通过将 jars 添加到类路径来调整清单文件
- 使用 Payara Micro 的 SLF4JBridgeHandler
我尝试通过payara micro maven插件将罐子添加为customJars,这确实导致了一个包含MICRO-INF/lib下的那些库的捆绑罐子。从我读到的,罐子也应该在类路径上,尽管它们没有出现在清单文件中。另外,我在 src/main/resources 下添加了以下简单内容的 logging.properties:
handlers=org.slf4j.bridge.SLF4JBridgeHandler
现在,如果我运行捆绑的 jar,它会显示Can't load log handler "org.slf4j.bridge.SLF4JBridgeHandler",然后是丑陋的堆栈跟踪。然而,org.slf4j.bridge.SLF4JBridgeHandler 类在我添加的其中一个 jar 中。我已经尝试使用上面链接的示例中的 groovy 脚本来编辑 Manifest 文件,但我不知道如何正确设置它。我的意思是,脚本有效,我得到了一个经过编辑的清单文件,但它没有添加到捆绑的 jar 中 - 我想我的时机不好。更不用说正如示例的作者所说的那样,这有点骇人听闻。
有趣的是,如果我不将 logging.properties 添加到 jar 中,从而使 Payara Micros 日志记录设置保持不变,我可以重新路由来自 Payara Micro 附带的 3rd 方库(例如休眠)的日志记录输出,同时将其自己的日志记录到安慰。但这不是我的目标,因为我对后面的日志更感兴趣。
所以,如果有人能帮我一把,我将不胜感激。谢谢阅读。为了完整起见,这是我的 pom.xml(我使用的是包配置文件,另一个仅用于黄瓜测试):
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>de.kepes.payara-micro</groupId>
<artifactId>payara-micro</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<failOnMissingWebXml>false</failOnMissingWebXml>
<skipTests>true</skipTests>
<payara-micro.version>5.194</payara-micro.version>
<payara-micro.plugin.version>1.0.6</payara-micro.plugin.version>
<jakarta.version>8.0.0</jakarta.version>
<maven-failsafe.plugin.version>2.22.2</maven-failsafe.plugin.version>
<cucumber.version>5.4.0</cucumber.version>
<websocket.version>1.4.0</websocket.version>
<log4j.version>2.13.0</log4j.version>
<slf4j.version>1.7.30</slf4j.version>
</properties>
<profiles>
<profile>
<id>package</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<plugins>
<plugin>
<groupId>fish.payara.maven.plugins</groupId>
<artifactId>payara-micro-maven-plugin</artifactId>
<version>${payara-micro.plugin.version}</version>
<executions>
<execution>
<id>bundle</id>
<phase>package</phase>
<goals>
<goal>bundle</goal>
</goals>
</execution>
<execution>
<id>start</id>
<goals>
<goal>start</goal>
</goals>
</execution>
</executions>
<configuration>
<useUberJar>true</useUberJar>
<deployWar>true</deployWar>
<payaraVersion>${payara-micro.version}</payaraVersion>
<customJars>
<customJar>
<groupId>org.slf4j</groupId>
<artifactId>jul-to-slf4j</artifactId>
<version>${slf4j.version}</version>
</customJar>
<customJar>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>${slf4j.version}</version>
</customJar>
<customJar>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log4j.version}</version>
</customJar>
<customJar>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>${log4j.version}</version>
</customJar>
<customJar>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log4j.version}</version>
</customJar>
</customJars>
</configuration>
</plugin>
</plugins>
</build>
</profile>
<profile>
<id>test</id>
<properties>
<skipTests>false</skipTests>
</properties>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-failsafe-plugin</artifactId>
<version>${maven-failsafe.plugin.version}</version>
<executions>
<execution>
<goals>
<goal>integration-test</goal>
<goal>verify</goal>
</goals>
</execution>
</executions>
<configuration>
<skip>false</skip>
</configuration>
</plugin>
<plugin>
<groupId>fish.payara.maven.plugins</groupId>
<artifactId>payara-micro-maven-plugin</artifactId>
<version>${payara-micro.plugin.version}</version>
<executions>
<execution>
<id>pre-integration-payara</id>
<phase>pre-integration-test</phase>
<goals>
<goal>start</goal>
</goals>
<configuration>
<daemon>true</daemon>
</configuration>
</execution>
<execution>
<id>post-integration-payara</id>
<phase>post-integration-test</phase>
<goals>
<goal>stop</goal>
</goals>
</execution>
</executions>
<configuration>
<payaraVersion>${payara-micro.version}</payaraVersion>
<deployWar>true</deployWar>
<contextRoot>/</contextRoot>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<dependencies>
<dependency>
<groupId>jakarta.platform</groupId>
<artifactId>jakarta.jakartaee-api</artifactId>
<version>${jakarta.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-java</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>io.cucumber</groupId>
<artifactId>cucumber-junit</artifactId>
<version>${cucumber.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>${websocket.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
解决方案
这仅通过将日志库添加为自定义 JAR 是不可能的,因为在加载这些库之前会初始化日志记录。
但是,有一个如何使用替代日志库的解决方案。您需要以不同的方式运行 Payara Micro。如果你把它放在类路径上并直接运行 Payara Micro 主类,你也可以把自定义日志库放在类路径上,它们将在启动时被拾取,在日志初始化之前。如果当前目录中有 payara-micro.jar、slf4j.jar、log4j.jar 和 jul-to-slf4j.jar,则可以像这样启动 Payara Micro:
java -cp ./payara-micro.jar:slf4j.jar:log4j2.jar:jul-to-slf4j.jar fish.payara.micro.PayaraMicro some.war
或者,您可以将这些日志 JAR 移动到子目录lib
并缩短命令行:
java -cp "./payara-micro.jar:lib/*" fish.payara.micro.PayaraMicro some.war
您可以将相同的参数传递给 Payara Micro JAR 接受的 PayaraMicro 类。
推荐阅读
- c - 您可以在一个套接字接收两个数据包的多播调用中获得两个数据包吗?
- http - Wireshark 不显示 http 协议
- javascript - 通过 API 获取数据后 Google Maps NaN 错误
- c++ - 在 C++ 中,如何使用向量调用派生类?
- java - 侦听器不适用于 java 中的 firebase 数据引用
- android - 在 Flutter 的 Web 视图中仅禁用触摸输入
- excel - ShellExecute可以发送类似于Vba中Shell的命令吗
- ssl - gevent SSL with godaddy error: ssl.SSLError: [SSL: SSLV3_ALERT_CERTIFICATE_UNKNOWN] sslv3 alert certificate unknown (_ssl.c:1051)
- android - flutter:应用关闭时通过接收短信弹出通知
- swift - SwiftUI - 隐藏 ScrollView 的指示器使其停止滚动