在 Karaf 的容器初始化期间,如何记录由 Blueprint (Aries) 创建的对象的初始化?

How can I log initialization of objects created by Blueprint (Aries) during container initialization in Karaf?

看完之后,我觉得我明白了,现在我感到困惑。这是我的期望和我所做的:

我希望登录到 Karaf,重新加载我的包,然后 运行 log:tail 并最终看到如下日志消息:

13:28:47.265 INFO [Blueprint] You just created a class called: MyClass.

使用的技术: - 由 Apache Karaf 实现的 OSGI 容器 - Aries

实施的蓝图
  1. 我的 OSGI 包从 Karaf 导入 pax 记录器

    org.slf4j.*; provider=paxlogging

据我了解,这意味着将在 运行 时向我的应用程序提供对 Karaf 单例记录器的引用,该应用程序仅使用 API。

  1. 我的classes使用SLF4J接口,所以我的项目中存在依赖slf4j-api:slf4j-api:1.7.26

  2. 一个 class 存在

Class服务模特

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 的规范:

Consumers of this API must not implement this type https://osgi.org/specification/osgi.cmpn/7.0.0/service.log.html#org.osgi.service.log.LoggerFactory

  1. 白羊座创造了一个:

蓝图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>

相关

您不需要特殊处理即可在 karaf 中启用 slf4j 日志记录。 只需像您一样在您的 java 代码中使用日志记录,然后让 maven bundle 插件为您创建一个包导入(不需要特殊配置)。

OSGi R7 日志服务规范的 link 是即将到来的日志记录标准化。基本上这个规范允许将记录器作为 OSGi 服务注入。这在技术上比 karaf(pax-logging 事实上)今天所做的更清洁。 在 karaf 中,此规范尚未实现。

明白了:

包中编译的 SLF4J API 是故事的一部分。其余部分由 org.ops4j.pax.logging.pax-logging-api 在 Karaf / Felix 中提供。这个东西在后台做事:

  1. 设置自己的单例记录器工厂。
  2. 立即启用 SLF4J API 支持并记录消息。
  3. 单例记录器工厂之一是 SLF4J API 创建记录器所需要的,Slf4jLoggerFactory. It, which holds a static reference to the PaxLoggingManager object (Slf4jLoggerFactory.setPaxLoggingManager(manager), where manager is new OSGIPaxLoggingManager(bundleContext)). The method getLogger within this singleton returns a new Slf4jLogger(name, paxLogger) object (where name is usually a class name and the paxLogger is either from a FallbackLogFactory.createFallbackLog(FrameworkUtil.getBundle(Logger.class), name) or 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 中创建了一个 top-level 引用,强制 Blueprint 等待 Pax Manager 准备就绪:

 <reference id="logService" interface="org.osgi.service.log.LogService" availability="mandatory" activation="eager"/>

然后其他 top-level 经理可以依赖于此 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,