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

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

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

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

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

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

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

    一、為Web Application配置Log4j:
      1.在OSGi-Web項目的Java EE Module Dependencies中,增加對log4j.jar的依賴關(guān)系。
      2.在WEB-INF/config目錄中,增加一個log4j.properties文件,內(nèi)容如下:
     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相關(guān)jar的依賴。

    經(jīng)過以上4個步驟,我們在Web Application中使用commons logging輸出的日志,都可以通過Log4j來顯示了。但是作為OSGi容器內(nèi)部來說,這還不夠。OSGi規(guī)范中推薦使用org.osgi.service.log包中的LogService和LogReaderService來管理和顯示OSGi日志。為了能正常顯示OSGi容器內(nèi)部的日志,我們還需要將LogService、LogReaderService和OSGi容器外部的Log4j結(jié)合起來才行,為了達到這個目的,我們還需要做以下幾個步驟:
      1.為OSGi容器增加一個org.osgi.service.log的實現(xiàn)包。在equinox-SDK-3.6M5開發(fā)包中,這個實現(xiàn)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開發(fā)包中,包含了一個DS的實 現(xiàn):org.eclipse.equinox.ds_1.2.0.v20100125.jar,將這個jar和一個依賴的 jar:org.eclipse.equinox.util_1.0.100.v20090520-1800.jar部署到OSGi容器中,就可以使用 DS服務(wù)了。同樣也放到plugins目錄下面去。
      3.新增一個plugin工程,名字為:org.dbstar.osgi.log,我們使用DS方式來獲取服務(wù),相關(guān)源代碼如下:
        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,啟動,現(xiàn)在能看到多了許多日志輸出,現(xiàn)在OSGi內(nèi)部通過LogService輸出的日志也能由Log4j接管了。

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

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

    評論

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

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

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

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

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

    你好!
    根據(jù)博主的博客進行了osgi日志的配置,但是在寫日志的時候提示log4j的配置沒有加載。
    2013-09-02 17:04 | 菜鳥老了
    主站蜘蛛池模板: 亚洲AV无码乱码麻豆精品国产| 久久亚洲高清观看| 精品国产香蕉伊思人在线在线亚洲一区二区| 免费二级毛片免费完整视频| 亚洲男人的天堂在线va拉文| 亚洲国产精品特色大片观看完整版| 精品日韩亚洲AV无码一区二区三区 | 一级黄色免费大片| 中文字幕永久免费| 在线观看免费视频资源| 全免费a级毛片免费看无码| 亚洲精品岛国片在线观看| 亚洲不卡av不卡一区二区| 亚洲三级在线播放| 女bbbbxxxx另类亚洲| 中文永久免费观看网站| 精品免费人成视频app| 国产精品国产亚洲区艳妇糸列短篇 | jzzijzzij在线观看亚洲熟妇| 一级毛片免费在线| 蜜桃视频在线观看免费视频网站WWW| 成人女人A级毛片免费软件| 国产精品无码一区二区三区免费| 亚洲无人区午夜福利码高清完整版| heyzo亚洲精品日韩| 亚洲国产成人高清在线观看 | 亚洲不卡中文字幕| 丰满少妇作爱视频免费观看| 黄色免费在线网站| 免费黄网在线观看| 久久综合九九亚洲一区| 亚洲熟女www一区二区三区| 中文字幕乱理片免费完整的| 美女视频黄的全免费视频| 亚洲一级Av无码毛片久久精品| 亚洲精品动漫在线| fc2成年免费共享视频18| 最近中文字幕免费mv视频8| 在线观看亚洲精品福利片| 亚洲一级毛片免费在线观看| 国产成人精品免费视频大全|