Как я могу регистрировать инициализацию объектов, созданных Blueprint (Aries) во время инициализации контейнера в Karaf?

Прочитав об этом, я почувствовал, что понял это, и теперь я озадачен. Вот что я ожидаю и что я сделал:

Я ожидаю войти в Karaf, перезагрузить свой пакет и запустить log:tail и в конечном итоге увидеть сообщение журнала, подобное этому:

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

Используемые технологии: - OSGI Container, реализованный Apache Karaf - Blueprint, реализованный Aries

  1. Мой пакет OSGI импортирует регистратор pax из Karaf

    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>

Связанный


person Jonathan Komar    schedule 16.07.2019    source источник


Ответы (2)


Вам не нужна специальная обработка, чтобы включить ведение журнала slf4j в karaf. Просто используйте регистрацию в своем Java-коде, как вы это делали, и позвольте плагину пакета maven создать для вас импорт пакета (специальная конфигурация не требуется).

Ссылка на спецификацию службы журнала OSGi R7 — это предстоящая стандартизация ведения журнала. По сути, эта спецификация позволяет внедрять регистраторы как службы OSGi. Технически это чище, чем то, что сегодня делает karaf (фактически pax-loging). В karaf эта спецификация еще не реализована.

person Christian Schneider    schedule 16.07.2019
comment
@Schneider Мне понравился ваш комментарий здесь stackoverflow.com/q/28882345/1236128. Я думаю, вы могли неправильно понять мой вопрос. У меня есть все эти настройки (за исключением того, что я использую плагин Gradle biz.aQute.bnd). Объекты, созданные ранее, не регистрируются. Мне нужно знать, как это решить. Я предполагаю, что мне нужно запросить менеджера службы и получить ссылку на регистрацию pax на ранней стадии (пока не знаю, как это сделать). - person Jonathan Komar; 16.07.2019
comment
Ах .. речь идет о том, чтобы не пропустить записи в журнале. Вы можете внедрить org.osgi.service.log.LogService в контекст схемы. Регистрация Pax предоставляет эту услугу, и она гарантирует, что ваш код будет выполнен только тогда, когда регистрация pax будет готова. - person Christian Schneider; 16.07.2019
comment
Appeciated, но в документации указано, что LogService устарел в пользу LoggerFactory или Loggers. osgi.org/specification/osgi.cmpn/7.0.0/ service.log.html - person Jonathan Komar; 16.07.2019
comment
Вы должны использовать LogService только как своего рода маркерную службу, чтобы позволить вашему контексту чертежа ждать, пока он будет готов. Вы бы не использовали LogService для ведения журнала. Pax logging также реализует несколько других интерфейсов, но я дал вам logservice, поскольку за ним стоит спецификация ... поэтому вам не нужно зависеть от конкретного интерфейса pax logging. - person Christian Schneider; 16.07.2019
comment
Кажется, я снова столкнулся с той же проблемой, хотя и с обновленной версией Карафа и друзей. Правильно ли в Gradle иметь зависимость compile "org.slf4j:slf4j-api:${slf4jApiVersion}" или мне где-то нужна реализация? Ведение журнала работает для потоков, которые создаются позже, но не для материалов, созданных на ранней стадии начальной загрузки Aries Blueprint. Пакетный импорт org.slf4j;version="[1.7,2)" - person Jonathan Komar; 25.11.2019
comment
API должен быть достаточно хорош в зависимостях. Если ведение журнала работает для некоторых потоков, ваши зависимости верны. Если вы не видите все журналы, возможно, это ошибка в журнале pax. - person Christian Schneider; 25.11.2019

Разобрался с этим:

SLF4J API, скомпилированный в комплекте, является частью истории. Остальное в Karaf/Felix предоставляет org.ops4j.pax.logging.pax-logging-api. Эта штука работает в фоновом режиме:

  1. Настраивает собственные фабрики одноэлементных регистраторов.
  2. Немедленно включает поддержку SLF4J API и регистрирует сообщение.
  3. Одна из фабрик одноэлементных регистраторов — это то, что нужно SLF4J API для создания регистраторов, Slf4jLoggerFactory. Он содержит статическую ссылку на объект PaxLoggingManager (Slf4jLoggerFactory.setPaxLoggingManager(manager), где менеджер — new OSGIPaxLoggingManager(bundleContext)). Метод getLogger в этом синглтоне возвращает объект new Slf4jLogger(name, paxLogger) (где name обычно является именем класса, а paxLogger происходит либо из FallbackLogFactory.createFallbackLog(FrameworkUtil.getBundle(Logger.class), name), либо из m_paxLogging.getLogger(name, Slf4jLogger.SLF4J_FQCN). Slf4jLogger

Итак, необходимо выполнить привязку к этому конкретному Slf4jLoggerFactory (реализует ILoggerFactory), чтобы все классы в комплекте получали правильную ссылку при вызове getLogger(class). Проблема с Aries Blueprint, похоже, заключается в том, что он лениво привязывает API SLF4J к реализации, предоставленной headers org.ops4j.pax.logging.pax-logging-api. Итак, я последовал совету Кристиана Шнайдера и создал ссылку верхнего уровня в 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,
person Jonathan Komar    schedule 23.07.2019