2012-08-07 37 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庫中的代碼,當你產生新的線程。

第三個選項是允許應用程序代碼將記錄器注入庫運行時。因此,庫代碼將使用由應用程序代碼傳遞的記錄器,而不是按類記錄器方法。

相關問題