【问题标题】:How can I log initialization of objects created by Blueprint (Aries) during container initialization in Karaf?如何在 Karaf 的容器初始化期间记录 Blueprint (Aries) 创建的对象的初始化?
【发布时间】:2023-03-31 11:50:01
【问题描述】:

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

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

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

使用的技术: - 由 Apache Karaf 实现的 OSGI 容器 - 白羊座实现的蓝图

  1. 我的 OSGI 包从 Karaf 导入 pax 记录器

    org.slf4j.*; provider=paxlogging

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

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

  2. 存在一个类

类服务于模型

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

  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>

相关

【问题讨论】:

    标签: logging osgi apache-karaf blueprint-osgi blueprint


    【解决方案1】:

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

    指向 OSGi R7 日志服务规范的链接是即将到来的日志标准化。基本上,该规范允许将记录器作为 OSGi 服务注入。这在技术上比 karaf(实际上是 pax-logging)今天所做的更干净。 在 karaf,此规范尚未实施。

    【讨论】:

    • @Schneider 我喜欢你在stackoverflow.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 中提供。这东西在后台做事:

    1. 设置自己的单例记录器工厂。
    2. 立即启用 SLF4J API 支持并记录一条消息。
    3. 其中一个单例记录器工厂是 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,
    

    【讨论】:

      猜你喜欢
      • 2013-06-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-22
      • 2012-05-23
      • 1970-01-01
      • 2014-08-17
      相关资源
      最近更新 更多