2012-08-07 35 views
0

比方说,我有四个传统的罐子:从传统应用程序OSGi日志记录?

  1. 我-library.jar
  2. 我-app.jar
  3. 我-其他-app.jar
  4. log4j.jar

“我的应用程序”和“我的其他应用程序”是不相关的应用程序,都具有main()函数。他们都使用“my-library-app”中的各种库函数。所有这三者都通过log4j进行日志记录(真的是slf4j,但我只是想保持简单的例子)。

目前,这两个应用程序设置了两个不同的log4j配置文件,这使得它们登录到两个不同的文件。

现在我想将所有东西都转换成OSGi。因此,我将前三个分别捆绑为一个独立的捆绑包,将实际应用程序的main()转换为Activators,然后捆绑或查找现有的log4j捆绑包。我在同一个OSGi框架中启动了两个应用程序。

但现在两个不同的应用程序不再登录到不同的文件!对?在JVM中只有一个运行的log4j实例,它从一个log4j.properties文件中获取其配置。

因此,也许,而不是捆绑每个我的四个单独罐的,我做三捆:

  1. 我的图书馆
  2. 我的应用加上log4j的
  3. 我的其他应用程序加log4j的

现在我可以为两个不同的应用程序获取不同的日志配置文件。但是我的图书馆的日志调用呢? My Library软件包将锁定到log4j的两个副本中的一个上,现在,从我的库中生成的所有日志消息都会出现在两个日志文件中的一个特定日志文件中 - 让我们说一个用于My App的日志文件。但即使它是来自我的图书馆的日志消息,也是如此,因为来自我的其他应用程序的呼叫!他们会去错误的日志文件。

所以也许捆绑:

  1. 我的图书馆加上log4j的
  2. 我的应用加上log4j的
  3. 我的其他应用程序加log4j的

现在从我的音乐库中的日志消息要自己自己的日志文件,我认为它比其中一些去错了应用程序的日志文件更好,但仍然不是很好。该文件包含来自两个应用程序的日志消息,并且任何旨在用于任一应用程序的日志文件都不具有来自这些应用程序的所有日志消息。

所以也许捆绑:

  1. 我的应用加上我的图书馆加log4j的
  2. 我的其他应用程序加上我的图书馆加log4j的

但现在什么是OSGi的点?我没有分享我的书库或log4j的使用。而在现实中,它可能会更糟 - 会有一堆,我要坚持的多个副本到我所有的实际应用捆绑的,只是因为我想看到的是使他们的应用程序相关的日志消息罐子。

所以也许备份和尝试不同的东西:我不认为这是可能的log4j的,但在(比如说)SLF4J我能回到原来的捆绑计划:

  1. 我的图书馆
  2. 我的应用
  3. 我的其他应用程序
  4. log4j的

然后我做这样的事情在每个线程把MDC信息说什么AP线程来自。响应该MDC信息以确定它所进入的日志文件。

但好像是不会工作!从我的应用程序中的某个线程调用我的库中的某个函数可能会导致从我的库中生成一个新线程,该线程不一定与该MDC相关联。

而且它比这更糟糕:我的图书馆可能有一些线程是由使用我的库中的任何应用程序共享,因此不可能用一些这样的标记关联。

所以,一切的一切,我很为难。任何建议将不胜感激。提前致谢。

+0

本文相关:https://www.tibcommunity.com/blogs/OSGi/2012/06/08/do-we-really-need-subsystems – 2012-08-08 08:55:25

回答

3

如果我理解正确:

  • 你曾经有两个完全独立的应用程序,在不同的JVM上运行。他们确实共享一个图书馆,但仅在文件系统级别上,应用程序并不知道彼此。
  • 现在你用一个JVM和应用程序互相干扰(log4j来进行,但现在可能还有其他的问题也是如此),并且要使用OSGi的解决这个问题。

我认为问题在于你使用OSGi作为应用程序容器,就像一个servlet容器,它将隔离不同的应用程序。您希望MyLibrary“属于”MyApp或MyOther应用程序。就我所见,你真的不希望这些应用程序共享任何东西,只是为了在单个JVM中发挥出色。

这是不是真的有什么的OSGi是为建的,但我能想到的几种可能性:

  • 新的OSGi规范确实支持这一(被称为子系统),但它很新,很可能对你的用例来说太复杂了,据我所知还没有实现。我不建议现在走这条路。

  • 您可以复制包,如果您给它们一个不同的符号名称,可以使用Require-Bundle依赖于特定的包。然后我认为它应该有效,但坦率地说,我认为这有点愚蠢。 OSGi然后添加任何东西,只是复杂的东西,因为你会得到很多几乎相同的捆绑。

  • 你可以开始在单个JVM 2种OSGi的情况下,每一个都有自己的一套束。这应该以一种优雅的方式将你的两个应用程序分开(检查Neil的回答here)。运行多个实例的OSGi是重量十分轻巧,您可以使用相同的包(在文件系统级),如果你做共享代码可以将这些包添加到org.osgi.framework.system.packages.extra属性。我认为这是你最好的选择。

  • 最后,一些OSGi的容器支持这一个专有的方式,如Eclipse处女座和Apache Karaf。 (在处女座称为“计划”,在Karaf中称为“实例”)。这可能值得一看,这取决于你的情况。

希望它能帮助,

弗兰克

2

要做到这一点,最好的办法是消除来自应用程序的日志记录设置(从罐子至少你在OSGi的部署)。然后你添加pax日志到你的OSGi容器。 Pax日志记录支持OSGi上的所有常见日志API。它可以配置一个log4j配置。在配置中,您可以设置log4j记录器和appender来区分这两个应用程序。因此,您可以按照自己的喜好登录一个或两个文件。

您也可以部署的OSGi应用到的Apache Karaf已经包括PAX记录。所以你不想自己设置它。

请参见: http://team.ops4j.org/wiki/display/paxlogging/Pax+Logging

http://karaf.apache.org/

1

这是不是真的特定的OSGi(弗兰克已经写)。

使用MDC通常是加强与应用/运行特定的信息记录方面一个很好的方法。可能有机会使用MDC。一些MDC实现(SLF4J的BasicMDCAdapterLogbackMDCAdapter)使用InheritableThreadLocal。新线程从父线程继承MDC。但是,这需要通过您正在使用的实际实施进行验证。

另一种选择是复制/复制MDC库中的代码,当你产生新的线程。

第三个选项是允许应用程序代码将记录器注入库运行时。因此,库代码将使用由应用程序代码传递的记录器,而不是按类记录器方法。

相关问题