<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 19, 文章 - 1, 評論 - 21, 引用 - 0
    數據加載中……

    打造一個基于OSGi的Web Application——增加日志輸出功能

    到目前為止,我們的基于OSGi內核的Web Application還沒有任何的日志輸出功能,本章將介紹如何在這個Web應用中配置和輸出日志。

    在前面的配置中,我們的應用中只含有commons-logging.jar,而OSGi容器之外的代碼中,均是通過配置commons logging的Log對象來輸出日志的,在默認的配置下,系統將采用Jdk14Logger來作為輸出日志的實現,這對我們來說是遠遠不夠的。我們下一步將配置更加常用的Log4j在作為我們的日志輸出實現,通過以下幾個步驟:

    一、為Web Application配置Log4j:
      1.在OSGi-Web項目的Java EE Module Dependencies中,增加對log4j.jar的依賴關系。
      2.在WEB-INF/config目錄中,增加一個log4j.properties文件,內容如下:
     1 ### direct log messages to stdout ###
     2 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
     3 log4j.appender.stdout.Target=System.out
     4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
     5 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%- %m%n
     6 
     7 #Default Log File Configuration For OSGi
     8 log4j.appender.OSGiLog=org.apache.log4j.DailyRollingFileAppender
     9 log4j.appender.OSGiLog.DatePattern='.'yyyy-MM-dd
    10 log4j.appender.OSGiLog.File=${osgi.root}/logs/OSGi.log
    11 log4j.appender.OSGiLog.layout=org.apache.log4j.PatternLayout
    12 log4j.appender.OSGiLog.layout.ConversionPattern=%d [%t] %-5p %- %m%n
    13 
    14 log4j.rootLogger=info, stdout
    15 
    16 log4j.logger.org.dbstar=debug, OSGiLog
    17 log4j.logger.org.eclipse=debug, OSGiLog
      3.采用Spring Web的Log4j配置方式,在web.xml中增加如下配置:
     1     <!-- Log4j configuration -->
     2     <context-param>
     3         <param-name>webAppRootKey</param-name>
     4         <param-value>osgi.root</param-value>
     5     </context-param>
     6     <context-param>
     7         <param-name>log4jConfigLocation</param-name>
     8         <param-value>/WEB-INF/config/log4j.properties</param-value>
     9     </context-param>
    10     
    11     <!-- Init log4j -->
    12     <listener>
    13         <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
    14     </listener>
      4.在OSGi-Web項目的Java EE Module Dependencies中,增加spring相關jar的依賴。

    經過以上4個步驟,我們在Web Application中使用commons logging輸出的日志,都可以通過Log4j來顯示了。但是作為OSGi容器內部來說,這還不夠。OSGi規范中推薦使用org.osgi.service.log包中的LogService和LogReaderService來管理和顯示OSGi日志。為了能正常顯示OSGi容器內部的日志,我們還需要將LogService、LogReaderService和OSGi容器外部的Log4j結合起來才行,為了達到這個目的,我們還需要做以下幾個步驟:
      1.為OSGi容器增加一個org.osgi.service.log的實現包。在equinox-SDK-3.6M5開發包中,這個實現jar是:org.eclipse.equinox.log_1.2.100.v20100118.jar,當然,還需要org.eclipse.osgi.services_3.2.100.v20100108.jar,都放置到OSGi-Web工程的WEB-INT/osgi/plugins目錄下面。
      2.為OSGi容器增加Declarative Services支持。在equinox-SDK-3.6M5開發包中,包含了一個DS的實 現:org.eclipse.equinox.ds_1.2.0.v20100125.jar,將這個jar和一個依賴的 jar:org.eclipse.equinox.util_1.0.100.v20090520-1800.jar部署到OSGi容器中,就可以使用 DS服務了。同樣也放到plugins目錄下面去。
      3.新增一個plugin工程,名字為:org.dbstar.osgi.log,我們使用DS方式來獲取服務,相關源代碼如下:
        OSGI-INF/log.xml
    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <scr:component xmlns:scr="http://www.osgi.org/xmlns/scr/v1.1.0" enabled="true" name="logListener" xsi:schemaLocation="http://www.osgi.org/xmlns/scr/v1.1.0 http://www.osgi.org/xmlns/scr/v1.1.0/scr.xsd">
    3   <implementation class="org.dbstar.osgi.log.LogListenerImpl"/>
    4   <reference cardinality="1..1" interface="org.osgi.service.log.LogReaderService" name="LogReaderService" policy="static"/>
    5 </scr:component>
        LogListenerImpl.java
     1 package org.dbstar.osgi.log;
     2 
     3 import org.apache.commons.logging.Log;
     4 import org.apache.commons.logging.LogFactory;
     5 import org.osgi.service.component.ComponentContext;
     6 import org.osgi.service.log.LogEntry;
     7 import org.osgi.service.log.LogListener;
     8 import org.osgi.service.log.LogReaderService;
     9 import org.osgi.service.log.LogService;
    10 
    11 public class LogListenerImpl implements LogListener {
    12     private static final Log logger = LogFactory.getLog(LogListenerImpl.class);
    13 
    14     protected void activate(ComponentContext context) {
    15         LogReaderService service = (LogReaderService) context.locateService("LogReaderService");
    16         service.addLogListener(this);
    17     }
    18 
    19     protected void deactivate(ComponentContext context) {
    20         LogReaderService service = (LogReaderService) context.locateService("LogReaderService");
    21         service.removeLogListener(this);
    22     }
    23 
    24     public void logged(LogEntry entry) {
    25         String msg = getMessage(entry);
    26 
    27         switch (entry.getLevel()) {
    28         case LogService.LOG_DEBUG:
    29             if (logger.isDebugEnabled()) {
    30                 if (entry.getException() == null) {
    31                     logger.debug(msg);
    32                 } else {
    33                     logger.debug(msg, entry.getException());
    34                 }
    35             }
    36             break;
    37         case LogService.LOG_INFO:
    38             if (logger.isInfoEnabled()) {
    39                 if (entry.getException() == null) {
    40                     logger.info(msg);
    41                 } else {
    42                     logger.info(msg, entry.getException());
    43                 }
    44             }
    45             break;
    46         case LogService.LOG_WARNING:
    47             if (logger.isWarnEnabled()) {
    48                 if (entry.getException() == null) {
    49                     logger.warn(msg);
    50                 } else {
    51                     logger.warn(msg, entry.getException());
    52                 }
    53             }
    54             break;
    55         case LogService.LOG_ERROR:
    56             if (logger.isErrorEnabled()) {
    57                 if (entry.getException() == null) {
    58                     logger.error(msg);
    59                 } else {
    60                     logger.error(msg, entry.getException());
    61                 }
    62             }
    63             break;
    64         }
    65     }
    66 
    67     private String getMessage(LogEntry entry) {
    68         StringBuilder msg = new StringBuilder();
    69         if (entry.getBundle() != null) msg.append("[bundle:").append(entry.getBundle()).append("]");
    70         if (entry.getServiceReference() != null) msg.append("[service:").append(entry.getServiceReference())
    71                 .append("]");
    72         msg.append(entry.getMessage());
    73         return msg.toString();
    74     }
    75 }
        META-INF/MANIFEST.MF
     1 Manifest-Version: 1.0
     2 Bundle-ManifestVersion: 2
     3 Bundle-Name: Log Bundle
     4 Bundle-SymbolicName: org.dbstar.osgi.log
     5 Bundle-Version: 1.0.0
     6 Bundle-Vendor: dbstar
     7 Bundle-RequiredExecutionEnvironment: J2SE-1.5
     8 Service-Component: OSGI-INF/log.xml
     9 Import-Package: org.apache.commons.logging;version="1.0.4",
    10  org.osgi.framework;version="1.3.0",
    11  org.osgi.service.component;version="1.1.0",
    12  org.osgi.service.log;version="1.3.0"
    好了,打包成bundle jar然后也扔到plugins目錄下面,然后clean一下server,啟動,現在能看到多了許多日志輸出,現在OSGi內部通過LogService輸出的日志也能由Log4j接管了。

    最后總結一下,LogService和LogReaderService是OSGi規范中提倡的日志標準,在equinox內部實現中大量使用了這種日志,而commons logging是我們開發常規程序時所常用的日志方式。在你的bundle代碼中,具體要采用哪一種日志方式,并沒有強制的要求,大家可以根據各人喜好來選用。
    順便提一句,LogService有些美中不足的是,不能像commons logging那樣,顯示出日志具體是從哪個java類的第幾行輸出的,不知道各位大蝦是否有人知道該如何解決呢,希望不吝賜教:)

    posted on 2010-03-27 00:28 dbstar 閱讀(3338) 評論(3)  編輯  收藏 所屬分類: OSGi

    評論

    # re: 打造一個基于OSGi的Web Application——增加日志輸出功能  回復  更多評論   

    實際上把log4j應用在osgi領域是完全可能的,也很簡單,為何舍近求遠呢...如果粗糙一點設計,可以把log4j.properties作為fragment,如果做的精致一些,log4j.properties放在哪都行,然后啟動時動態生成一個fragment就好了
    2010-03-27 12:03 | romza

    # re: 打造一個基于OSGi的Web Application——增加日志輸出功能  回復  更多評論   

    @romza
    這么做的目的,主要也是為了bundle中使用log的代碼不耦合與commons logging、Log4j,或者其他類似的實現。之所以采用OSGi的LogService,一方面,這是OSGi提出的日志標準,在equinox的實現代碼中,這也是事實標準;另一方面,這種日志方式確實更加靈活,其抽象的API更適合于OSGi環境。將Log4j配置在OSGi之外,也是為了降低這種耦合。
    2010-03-27 13:08 | dbstar

    # re: 打造一個基于OSGi的Web Application——增加日志輸出功能  回復  更多評論   

    你好!
    根據博主的博客進行了osgi日志的配置,但是在寫日志的時候提示log4j的配置沒有加載。
    2013-09-02 17:04 | 菜鳥老了
    主站蜘蛛池模板: 亚洲精品欧洲精品| 亚洲成人免费在线| 亚洲成a人片在线不卡一二三区| 午夜老司机永久免费看片| 亚洲AV无码专区电影在线观看| caoporn国产精品免费| 国产亚洲精久久久久久无码77777 国产亚洲精品成人AA片新蒲金 | a级日本高清免费看| 亚洲热线99精品视频| 久久国产乱子伦精品免费看| 在线观看亚洲人成网站| 国产桃色在线成免费视频| 国产精品亚洲专区在线观看| 精品国产麻豆免费网站| 美女视频黄视大全视频免费的| 四虎国产精品免费久久影院| a毛片成人免费全部播放| 亚洲国产精品特色大片观看完整版| 无码午夜成人1000部免费视频| 亚洲综合小说久久另类区| 全免费a级毛片免费**视频| 日本激情猛烈在线看免费观看| 国产亚洲精品成人AA片新蒲金| 久久精品中文字幕免费| 国产精品亚洲四区在线观看 | 中文字幕无码视频手机免费看| 亚洲乱人伦中文字幕无码| 亚洲无线一二三四区手机| 99爱在线观看免费完整版| 亚洲综合一区二区三区四区五区| 免费国产人做人视频在线观看| 中文字幕乱码免费看电影| 亚洲国产精品线观看不卡| 免费在线观看亚洲| 国内少妇偷人精品视频免费| 亚洲Av无码一区二区二三区| 亚洲麻豆精品国偷自产在线91| 精品无码无人网站免费视频| 亚洲av无码专区首页| 亚洲最大的成网4438| 亚洲国产精品激情在线观看|