是否可以获取更改捆绑包状态的日志?

Is it possible to get a log of changing bundles statuses?

我使用 osgi 控制台。命令 ss 非常有用,但我想观察每个包的状态变化以进行调试。可能吗?

是的,这是可能的。

使用日志服务

参见 OSGi Compendium 规范101 日志服务规范下的101.6.1 捆绑事件映射一章:

简而言之:如果有LogService implementation in the container, each Bundle and Service event is logged. The logged records can be read with LogReaderService. Equinox has a built-in implementation, in Felix I normally use the one implemented by Felix.

在容器中实现 LogService 后,您应该以某种方式将结果写入控制台。这里也有几种方法。我可以推荐的一个是:

  • 安装 slf4j 实现包之一(例如:slf4j-simple that simply logs everything to the standard output) together with slf4j-api
  • 安装 Everit Loglistener To SLF4J 将每个日志条目转发到 SLF4J API。 SLF4J 会将条目写入控制台

实现 BundleListener

您可以通过 BundleListener

捕获所有实时捆绑事件

实现 BundleTracker

您可以实现一个 BundleTracker,您可以在其中捕获所有 Bundle 事件。在这种情况下,您还将获得打开跟踪器之前发生的已安装捆绑包(至少已安装)的最后事件。

另一种方法是使用 Byteman。应该是这样的:

####################################################

RULE Bundle state change
CLASS org.eclipse.osgi.framework.internal.core.AbstractBundle
METHOD beginStateChange()
IF TRUE
DO
System.out.println("[STATE CHANGE] " + $this.getBundle() + " > " + $this.getBundle().getState());
ENDRULE

####################################################

RULE Bundle complete state change
CLASS org.eclipse.osgi.framework.internal.core.AbstractBundle
METHOD completeStateChange()
AT EXIT
IF TRUE
DO
System.out.println("[COMPLETE STATE CHANGE] " + $this.getBundle() + " > " + $this.getBundle().getState());
ENDRULE