Karaf 4.2.15集成logstash-gelf log4j2插件无法识别问题求助
Karaf PAX Logging 集成Log4j2 Gelf Appender 问题排查与修复
环境与改造背景
- 运行环境:Karaf v4.2.15,默认采用PAX Logging日志框架,日志配置文件为
org.ops4j.pax.logging.cfg - 改造目标:将旧版本基于log4j v1实现的Graylog appender升级适配为log4j2版本
已完成的前置操作
- 依赖替换:将旧GELF依赖库
org.graylog2/gelfj替换为官方推荐的biz.paluch.logging/logstash-gelf:1.15.0,封装为OSGi Bundle,构建时已配置导出biz.paluch.logging.gelf.log4j2包,且通过shade插件打包了Log4j2Plugins.dat插件描述文件,对应pom配置如下:
<?xml version="1.0" encoding="UTF-8"?> <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>osgi.biz.paluch.logging</groupId> <artifactId>logstash-gelf</artifactId> <version>1.15.0</version> <packaging>bundle</packaging> <name>logstash-gelf OSGi Bundle</name> <description>This OSGi bundle simply wraps logstash-gelf-1.15.0jar artifact.</description> <dependencies> <dependency> <groupId>biz.paluch.logging</groupId> <artifactId>logstash-gelf</artifactId> <version>1.15.0</version> </dependency> </dependencies> <build> <defaultGoal>install</defaultGoal> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-shade-plugin</artifactId> <version>3.3.0</version> <executions> <execution> <phase>package</phase> <goals> <goal>shade</goal> </goals> <configuration> <artifactSet> <includes> <include>biz.paluch.logging:logstash-gelf</include> </includes> </artifactSet> <filters> <filter> <includes> <include>META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat</include> </includes> </filter> </filters> </configuration> </execution> </executions> </plugin> <plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>5.1.2</version> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Export-Package>biz.paluch.logging.gelf.log4j2</Export-Package> <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy> <_removeheaders>Ignore-Package,Include-Resource,Private-Package,Embed-Dependency</_removeheaders> </instructions> </configuration> </plugin> </plugins> </build> </project>
- 启动配置:将封装好的Bundle加入Karaf
startup.properties,设置启动级别为7,期望在应用启动阶段提前加载以输出启动日志,对应配置如下:
# Bundles to be started on startup, with startlevel mvn\:org.apache.karaf.features/org.apache.karaf.features.extension/4.2.15 = 1 mvn\:org.ops4j.pax.url/pax-url-aether/2.6.7 = 5 mvn\:org.ops4j.pax.logging/pax-logging-log4j2/1.11.13 = 8 mvn\:org.ops4j.pax.logging/pax-logging-api/1.11.13 = 8 mvn\:org.fusesource.jansi/jansi/1.18 = 8 mvn\:org.osgi/org.osgi.util.promise/1.1.1 = 9 mvn\:org.apache.felix/org.apache.felix.coordinator/1.0.2 = 9 mvn\:org.osgi/org.osgi.util.function/1.1.0 = 9 mvn\:org.apache.felix/org.apache.felix.configadmin/1.9.22 = 10 mvn\:org.apache.felix/org.apache.felix.fileinstall/3.7.4 = 11 mvn\:org.apache.karaf.features/org.apache.karaf.features.core/4.2.15 = 15 # My bundles mvn\:osgi.biz.paluch.logging/logstash-gelf/1.15.0 = 7
- 状态确认:Bundle已成功安装,状态为Active,Bundle列表信息如下:
START LEVEL 100 , List Threshold: 0 ID │ State │ Lvl │ Version │ Name ────┼──────────┼─────┼────────────────────────────┼─────── 0 │ Active │ 0 │ 5.6.12 │ System Bundle, Fragments: 1 1 │ Resolved │ 1 │ 4.2.15 │ Apache Karaf :: Features :: Extension, Hosts: 0 2 │ Active │ 5 │ 2.6.7 │ OPS4J Pax Url - mvn: 3 │ Active │ 8 │ 1.11.13 │ OPS4J Pax Logging - Log4Jv2 implementation 4 │ Active │ 8 │ 1.11.13 │ OPS4J Pax Logging - API 5 │ Active │ 8 │ 1.18.0 │ jansi 6 │ Active │ 9 │ 1.1.1.201810101357 │ org.osgi:org.osgi.util.promise 7 │ Active │ 9 │ 1.0.2 │ Apache Felix Coordinator Service 8 │ Active │ 9 │ 1.1.0.201802012106 │ org.osgi:org.osgi.util.function 9 │ Active │ 10 │ 1.9.22 │ Apache Felix Configuration Admin Service 10 │ Active │ 11 │ 3.7.4 │ Apache Felix File Install 11 │ Active │ 15 │ 4.2.15 │ Apache Karaf :: Features :: Core 12 │ Active │ 7 │ 1.15.0 │ logstash-gelf OSGi Bundle
- Appender配置:在日志配置中添加Gelf类型appender参数,配置如下:
log4j2.appender.graylog.type = Gelf log4j2.appender.graylog.name = Graylog log4j2.appender.graylog.host = log.server.com log4j2.appender.graylog.port = 12201 log4j2.appender.graylog.originHost = myapp.server.com
故障现象
无论配置为启动阶段加载,还是PAX Logging初始化完成后动态加载,运行时持续报错,提示无法找到Gelf插件,错误信息:
org.ops4j.pax.logging.pax-logging-log4j2 [log4j2] ERROR : Unable to locate plugin type for Gelf Ignored FQCN: org.apache.logging.log4j.spi.AbstractLogger
已尝试两种手动声明插件包的方案,均未生效:
- 在配置文件中添加
log4j2.packages = biz.paluch.logging.gelf.log4j2 - 在启动命令行添加参数
-Dlogj4.plugin.packages=biz.paluch.logging.gelf.log4j2
根因排查方法
按以下顺序逐一排查即可定位问题:
- 检查插件扫描时序:PAX Logging的Log4j2 OSGi插件扫描监听器是在
pax-logging-log4j2Bundle启动时才注册的,若自定义插件Bundle启动级别比pax-logging-log4j2低(启动更早),插件Bundle启动时监听器还未初始化,会错过Bundle启动事件,无法扫描到插件文件。 - 检查配置参数拼写与适配性:
- 手动添加的JVM参数存在拼写错误,
logj4.plugin.packages应为log4j2.plugin.packages - PAX Logging未适配原生Log4j2的
log4j2.packages配置key,该配置在PAX Logging环境下不生效
- 手动添加的JVM参数存在拼写错误,
- 检查OSGi类加载配置:当前Bundle仅导出了
biz.paluch.logging.gelf.log4j2包,Gelf Appender依赖的同项目下其他工具类、数据类包未正确导出,且未声明对Log4j2核心包的依赖,就算扫到插件描述文件也无法完成类加载。 - 检查打包产物有效性:解压构建出的Bundle jar,确认
META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat文件存在且大小正常,避免shade打包时文件被覆盖、损坏,或未被正确纳入产物。
修复步骤
- 调整Bundle启动级别
将logstash-gelf Bundle的启动级别从7修改为9,确保晚于pax-logging-log4j2(启动级别8)启动,保证插件Bundle启动时PAX Logging的扫描监听器已完成注册。修改后startup.properties对应行:
mvn\:osgi.biz.paluch.logging/logstash-gelf/1.15.0 = 9
- 修正插件扫描配置
在org.ops4j.pax.logging.cfg中添加PAX Logging识别的插件包配置,替换之前无效的配置项:
org.ops4j.pax.logging.log4j2.plugin.packages = biz.paluch.logging.gelf.log4j2,biz.paluch.logging.gelf
若使用JVM启动参数指定,修正拼写错误:
-Dlog4j2.plugin.packages=biz.paluch.logging.gelf.log4j2,biz.paluch.logging.gelf
- 修正Bundle构建配置
修改maven-bundle-plugin的配置,移除错误的_removeheaders段,补充必要的包导入导出规则,确保类可被正常加载:
<plugin> <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <version>5.1.2</version> <extensions>true</extensions> <configuration> <instructions> <Bundle-SymbolicName>${project.artifactId}</Bundle-SymbolicName> <Bundle-ActivationPolicy>lazy</Bundle-ActivationPolicy> <Export-Package> biz.paluch.logging.gelf.*;version="${project.version}" </Export-Package> <Import-Package> org.apache.logging.log4j.*;resolution:=required, org.osgi.framework;resolution:=required, *;resolution:=optional </Import-Package> <_versionpolicy>[$(version;==;$(@)),$(version;+;$(@)))</_versionpolicy> </instructions> </configuration> </plugin>
- 验证打包产物
重新构建Bundle后,解压jar包做两项检查:
- 确认
META-INF/org/apache/logging/log4j/core/config/plugins/Log4j2Plugins.dat存在,文件大小不为0 - 确认
biz/paluch/logging/gelf路径下所有类文件均被正确打包,无缺失
- 清理缓存重启验证
删除Karaf目录下data/cache文件夹清理旧Bundle缓存,重启Karaf,若日志中不再出现"Unable to locate plugin type for Gelf"报错,即修复完成。
内容的提问来源于stack exchange,提问作者JamesP
相关产品推荐
相关产品推荐

