如何在 Karaf 的容器初始化期间记录 Blueprint (Aries) 创建的对象的初始化?
Posted
技术标签:
【中文标题】如何在 Karaf 的容器初始化期间记录 Blueprint (Aries) 创建的对象的初始化?【英文标题】:How can I log initialization of objects created by Blueprint (Aries) during container initialization in Karaf? 【发布时间】:2019-11-25 03:11:52 【问题描述】:读完之后,我觉得我明白了,现在我感到困惑。以下是我的期望和我所做的:
我希望登录到 Karaf,重新加载我的包,然后运行 log:tail
并最终看到如下日志消息:
13:28:47.265 INFO [Blueprint] You just created a class called: MyClass.
使用的技术: - 由 Apache Karaf 实现的 OSGI 容器 - 白羊座实现的蓝图
我的 OSGI 包从 Karaf 导入 pax 记录器
org.slf4j.*; provider=paxlogging
据我了解,这意味着对 Karaf 的单例记录器的引用将在运行时提供给我的应用程序,该应用程序仅使用 API。
我的类使用SLF4J接口,所以我的项目中存在依赖slf4j-api:slf4j-api:1.7.26
。
存在一个类
类服务于模型
public class MyClass
private static final Logger LOGGER = LoggerFactory.getLogger(MyClass.class);
public MyClass()
LOGGER.info("You just created a class called: ", this);
@Override
public String toString() return "MyClass" ;
我只是遵循 OSGI LoggerFactory 的规范:
此 API 的使用者不得实现此类型https://osgi.org/specification/osgi.cmpn/7.0.0/service.log.html#org.osgi.service.log.LoggerFactory
-
白羊座创造了一个:
蓝图 XML
<?xml version="1.0" encoding="UTF-8" ?>
<blueprint xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.osgi.org/xmlns/blueprint/v1.0.0 http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<description>
A sample Blueprint XML to demonstrate
the initialization procedure in the hopes of reproducing a problem.
</description>
<bean id="myclass1" class=com.stack.MyClass/>
</blueprint>
相关
How handle different logging solutions in OSGi (Apache Felix) Activating an OSGI LogListener before other services?【问题讨论】:
【参考方案1】:在 karaf 中启用 slf4j 登录不需要特殊处理。 只需像您一样登录您的 java 代码,然后让 maven bundle 插件为您创建一个包导入(无需特殊配置)。
指向 OSGi R7 日志服务规范的链接是即将到来的日志标准化。基本上,该规范允许将记录器作为 OSGi 服务注入。这在技术上比 karaf(实际上是 pax-logging)今天所做的更干净。 在 karaf,此规范尚未实施。
【讨论】:
@Schneider 我喜欢你在***.com/q/28882345/1236128 的评论。我想你可能误读了我的问题。我有所有的设置(除了我使用 Gradle biz.aQute.bnd 插件)。不记录早期创建的对象。我需要知道如何解决这个问题。我的猜测是,我需要尽早查询服务管理器并获取对 pax 日志记录的参考(尚不确定如何执行此操作)。 啊..它是关于不丢失日志条目。您可以将 org.osgi.service.log.LogService 注入到蓝图上下文中。 Pax 日志记录提供此服务,它将确保您的代码仅在 pax 日志记录准备好时执行。 Appeciated,但文档指出 LogService 已被弃用,取而代之的是 LoggerFactory 或 Loggers。 osgi.org/specification/osgi.cmpn/7.0.0/service.log.html 您只能将 LogService 用作一种标记服务,让您的蓝图上下文等待它准备好。您不会使用 LogService 来记录内容。 Pax 日志还实现了一些其他接口,但我给了你一个日志服务,因为它背后有一个规范......所以你不需要依赖 pax 日志特定的接口。 API 在依赖项中应该足够好。如果日志记录适用于某些线程,那么您的依赖关系是正确的。如果您没有看到所有日志,那么这可能是 pax 日志记录中的错误。【参考方案2】:想通了:
捆绑包中编译的 SLF4J API 是故事的一部分。其余部分由 org.ops4j.pax.logging.pax-logging-api
在 Karaf / Felix 中提供。这东西在后台做事:
-
设置自己的单例记录器工厂。
立即启用 SLF4J API 支持并记录一条消息。
其中一个单例记录器工厂是 SLF4J API 创建记录器所需的,Slf4jLoggerFactory。它持有对
PaxLoggingManager
对象(Slf4jLoggerFactory.setPaxLoggingManager(manager)
,其中经理是new OSGIPaxLoggingManager(bundleContext)
)的静态引用。此单例中的方法getLogger
返回一个new Slf4jLogger(name, paxLogger)
对象(其中名称通常是类名,而paxLogger 来自FallbackLogFactory.createFallbackLog(FrameworkUtil.getBundle(Logger.class), name)
或m_paxLogging.getLogger(name, Slf4jLogger.SLF4J_FQCN)
。Slf4jLogger
因此,有必要绑定到这个特定的Slf4jLoggerFactory
(实现ILoggerFactory
),以便捆绑包中的所有类在调用getLogger(class)
时都能获得正确的引用。 Aries Blueprint 的问题似乎在于它懒惰地将 SLF4J API 绑定到headers org.ops4j.pax.logging.pax-logging-api
提供的实现。因此,我按照 Christian Schneider 的建议在 Blueprint 中创建了一个***引用,强制 Blueprint 等待 Pax Manager 准备好:
<reference id="logService" interface="org.osgi.service.log.LogService" availability="mandatory" activation="eager"/>
那么其他高层管理者可以通过depends-on
来依赖这个:
<bean id="MyRegistry" class="com.foo.MyRegistry" scope="singleton" factory-method="getSingletonInstance" depends-on="logService">
当然,我需要在我的 OSGI MANIFEST.MF 中添加以下内容
Import-Package:
org.slf4j;version="[1.7.0,2.0.0)",
org.osgi.service.log,
【讨论】:
以上是关于如何在 Karaf 的容器初始化期间记录 Blueprint (Aries) 创建的对象的初始化?的主要内容,如果未能解决你的问题,请参考以下文章
无法从 Karaf 2.2.0 OSGi 容器中的根上下文运行 WAR