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

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

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

    honzeland

    記錄點滴。。。

    常用鏈接

    統計

    Famous Websites

    Java

    Linux

    P2P

    最新評論

    Svn revision retrieve and logging to database

    最近接到兩個很小的tickets,兩個都是為了項目開發時的方便:一是將logs寫入到數據庫中,以方便日志的查詢;一是在build時,在war包加入svn revision info。
    1) logging to database
    經過調查,決定采用log4j的org.apache.log4j.jdbc.JDBCAppender,于是采用:
    # logging to db
    log4j.logger.com.example=DEBUG, DATABASE
    log4j.additivity.com.example=false
    log4j.appender.DATABASE=org.apache.log4j.jdbc.JDBCAppender
    log4j.appender.DATABASE.url=jdbc:postgresql://localhost:5432/test
    log4j.appender.DATABASE.driver=org.postgresql.Driver
    log4j.appender.DATABASE.user=pguser
    log4j.appender.DATABASE.password=post
    log4j.appender.DATABASE.sql=INSERT INTO debug_log(created, logger, priority, message) VALUES (to_timestamp('%d{ISO8601}','YYYY-MM-DD HH:MI:SS.MS'),'%c.%M:%L','%p','%m')
    log4j.appender.DB.layout=org.apache.log4j.PatternLayout
    log4j.appender.DATABASE.layout.ConversionPattern=%d{ISO8601} %p %c.%M:%L %m
    很直觀,用起來還很方便,但是不久就出現了問題,tomcat拋出了exception。只好把之前fixed ticket reopen,提交新的comments:Unfortunately, org.apache.log4j.jdbc.JDBCAppender that ships with the Log4j distribution is not able to process logging messages that have characters like ' (single quote) and , (comma) in it. When logging messages contains characters like single quote or comma, the program will throw an exception.
    重新google了,找到了一個plusjdbc,Looking further, I found an alternative JDBCAppender package (org.apache.log4j.jdbcplus.JDBCAppender) from http://www.dankomannhaupt.de/projects/index.html. It can solve this problem. 長嘆了一下。

    最后采用:
    log4j.appender.DATABASE=org.apache.log4j.jdbcplus.JDBCAppender
    log4j.appender.DATABASE.url=jdbc:postgresql://localhost:5432/test
    log4j.appender.DATABASE.dbclass=org.postgresql.Driver
    log4j.appender.DATABASE.username=pguser
    log4j.appender.DATABASE.password=post
    log4j.appender.DATABASE.sql=INSERT INTO debug_log(created, logger, priority, message) VALUES (to_timestamp('@LAYOUT:1@', 'YYYY-MM-DD HH:MI:SS.MS'),'@LAYOUT:3@','@LAYOUT:2@','@LAYOUT:4@')
    log4j.appender.DATABASE.layout=org.apache.log4j.PatternLayout
    log4j.appender.DATABASE.layout.ConversionPattern=%d{ISO8601}#%p#%c.%M:%L#%m
    log4j.appender.DATABASE.layoutPartsDelimiter=#
    log4j.appender.DATABASE.buffer=1
    log4j.appender.DATABASE.commit=true
    log4j.appender.DATABASE.quoteReplace=true
    問題解決,但是中間有點小波折,在我的項目中,log4j.jar(>1.2.9)重復了,在$CATALINA_HOME/lib下有一份,在web工程下的WEB-INF/lib下也有一份,而plus-jdbc.jar放置在$CATALINA_HOME/lib下,結果啟動Tomcat,出現
    log4j:ERROR A "org.apache.log4j.jdbcplus.JDBCAppender" object is not assignable to a "org.apache.log4j.Appender" variable.
    log4j:ERROR The class "org.apache.log4j.Appender" was loaded by
    log4j:ERROR [WebappClassLoader^M
      delegate: false^M
      repositories:^M
    ----------> Parent Classloader:^M
    org.apache.catalina.loader.StandardClassLoader@1ccb029^M
    ] whereas object of type
    log4j:ERROR "org.apache.log4j.jdbcplus.JDBCAppender" was loaded by [org.apache.catalina.loader.StandardClassLoader@1ccb029].
    log4j:ERROR Could not instantiate appender named "DATABASE".
    原來是兩個JDBCAppender實例不在同一個classlaoder里面,將WEB-INF/lib下的log4j.jar刪除掉,重啟就沒問題了,按理,將$CATALINA_HOME/lib下的plus-jdbc.jar移到WEB-INF/lib下,應該也沒問題,沒有測試。

    2)Add build revision info in war file and read it on tomcat startup
    這個經歷比較慘痛,兩個問題,如何獲取revision? And how to read it when tomcat startup? 第二個問題倒是沒什么,采用javax.servlet.ServletContextListener就可以實現,很簡單,走彎路的是第一個問題,google后發現有兩種常見的實現:
    As I have learned, there are totally two solutions to get svn revision info.

    First, retrieve the svn revision from local file($BASE_HOME/.svn/entries). Just parsing the xml file, get the revision property and write it to a properties file.(就是該死的xml,遠在烏克蘭的同事,該文件卻不是xml的,也只怪自己調研不充分,還得折騰了半天,后來發現,最新版的svn為了performance的考慮,采用meta data來實現entries)

    Second, retrieve the svn revision from the remote repository. The solution always use a svn client to perform a demand with remote server to retrieve the revision info. Installing a snv client and using SvnAnt? are most commonly used at present. SvnAnt? is an ant task that provides an interface to Subversion revision control system and encapsulates the svn client. It uses javahl - a native (JNI) java interface for the subversion api if it can find the corresponding library. javahl is platform-dependent.

    Because of needing interaction with the server(服務器在國外,更新很慢), now I employ the first solution. But I found a flaw of this method when i was going off duty. Generally, we may update our project with svn before committing. This may make a mismatch with svn revision between remote server and local file. Svn revision in local file is usually updated when we update our project. But when we take a commit after update, the svn revision in the remote server will change to a new one.

    So, the case is that if we update, commit, and then build, we may get a mismatch with the newest svn revision, and build the error revision into our ROOT.war. If we update , then build ,without commit, we can get right revision info.

    下面是第一版實現:
        <!--  retrieve the svn revision from the remote repository
        <path id="svnant.lib" >
            <fileset dir="${lib.dir}">
                <include name="svnant.jar"/>
                <include name="svnClientAdapter.jar"/>
                <include name="svnjavahl.jar"/>
            </fileset>
        </path>
       
        <taskdef name="svn" classpathref="svnant.lib" classname="org.tigris.subversion.svnant.SvnTask" />
       
        <target name="get-svn-revision">
            <svn username="*******" password="******" javahl="true">
                    <status urlProperty="https://example.com" path="." revisionProperty="svn.revision" />
            </svn>
            <echo>svn revision: ${svn.revision}</echo>
        </target>   
        -->
       
        <!--  retrieve the svn revision from local file(.svn/entries). The file may contain several  'wc-entries.entry.revision' elements.
        The property will get several values seperated by ',' when using xmlproperty task.  Then the svn revison expected will be the
        max one of these property values.
         -->
        <property name="svn.revision.file" value=".svn/entries" />
        <!-- This property is used to run xmlproperty task successfully with a low version of svn client (under 1.3.1). Don't  sure whether it really makes sense -->
        <property name="build.id" value="foo" />
        <target name="get-svn-revision">
            <xmlproperty file="${svn.revision.file}" collapseAttributes="true"/>
            <echo>svn revision: ${wc-entries.entry.revision}</echo>
        </target>

        <!--
            If the file doesn't contain any 'wc-entries.entry.revision' element, the content of the property file will be: revision = ${wc-entries.entry.revision};
            If contain a 'wc-entries.entry.revision' element, mark this value as $revision_value, then  the content will be: revision = $revision_value;
            If contain several 'wc-entries.entry.revision' elements, mark these values as $value1, $value2, ..., respectively, then the content will be: revision = $value1,$value2,..., seperated by a ',';
        -->
        <property name="svn.revision.propertyfile" value="${build.dir}/revision.properties" />
        <target name="write-svn-revision-to-file" depends="get-svn-revision">
            <delete file="${svn.revision.propertyfile}"/>
            <propertyfile file="${svn.revision.propertyfile}" comment="record svn revision">
                <entry  key="revision" value="${wc-entries.entry.revision}"/>
            </propertyfile>
        </target>

    結果write-svn-revision-to-file這個在我這倒是可以獲取本地的svn revision,但是遠方的同事可急了,build老失敗,只好把這部分build注釋了,還好,到周末了,可以在家好好研究一下,很快找了一個新的工具:
    It's my fault. In my version of svn, the entries file is xml formatted. So i parse it using ant task - 'xmlproperty'. Now i have fix this problem by using 'svnkit' tools, a pure java svn toolkit. Now there are two ways to retrieve svn revision. One is from remote repository server. For this one, before building, you should set your own username and password for the remote repository server('remote.repository.username' and 'remote.repository.password' properties in build.xml,respectively). Another one is retrieving revision from local working copy. If using this one, you should set 'local.repository' property in build.xml to your own directory.
    利用svnkit,從服務器上獲取revision大概是:
                repository = SVNRepositoryFactory.create(SVNURL.parseURIDecoded(urlStr));
                ISVNAuthenticationManager authManager = SVNWCUtil.createDefaultAuthenticationManager(username, password);
                repository.setAuthenticationManager(authManager);
                headRevision = repository.getLatestRevision();
    從本地working copy獲取revision:
                SVNClientManager clientManager = SVNClientManager.newInstance();
                SVNWCClient wcClient = clientManager.getWCClient();   
                SVNInfo info = wcClient.doInfo(new File(fileUrl), SVNRevision.WORKING);
                headRevision = info.getRevision().getNumber(); 

    利用ant task將獲取的revision寫入到一個配置文件中(如revision.properties),在tomcat啟動的時候加載進來,就可以了。   

    posted on 2008-04-28 15:43 honzeland 閱讀(2180) 評論(2)  編輯  收藏 所屬分類: Java

    評論

    # re: Svn revision retrieve and logging to database 2008-04-28 23:23 lformat

    log4j.appender.DATABASE.url=jdbc:postgresql://localhost:5432/test
    log4j.appender.DATABASE.username=pguser
    log4j.appender.DATABASE.password=post

    地址和用戶名密碼都暴露了,有沒有其他辦法?  回復  更多評論   

    # re: Svn revision retrieve and logging to database 2008-04-29 11:45 honzeland

    可以設置在build時讓用戶輸入用戶名和密碼,或者把它們放在一個單獨的屬性文件里面(該文件只對個人可見),另外就比較復雜了,加密后存入文件  回復  更多評論   

    主站蜘蛛池模板: 老司机午夜在线视频免费观| 亚洲冬月枫中文字幕在线看| 成人久久久观看免费毛片| 免费无码看av的网站| 亚洲国产精品18久久久久久 | 亚洲精品无播放器在线播放| 91在线视频免费91| 亚洲欧美综合精品成人导航| 妞干网在线免费观看| 亚洲国产av玩弄放荡人妇| 在线观看永久免费视频网站| 男男gvh肉在线观看免费| 亚洲人成国产精品无码| 成人无码WWW免费视频| 午夜亚洲AV日韩AV无码大全| 30岁的女人韩剧免费观看| 亚洲区精品久久一区二区三区| 日韩精品无码区免费专区| 亚洲av永久无码精品网址| 亚洲另类激情专区小说图片| baoyu122.永久免费视频| 自怕偷自怕亚洲精品| 成年女性特黄午夜视频免费看| 美国毛片亚洲社区在线观看| 久久久久亚洲精品无码网址| 久久久久久AV无码免费网站下载 | 美女巨胸喷奶水视频www免费| 亚洲va久久久噜噜噜久久狠狠| 亚洲成人在线免费观看| 亚洲av无码成人精品国产| 亚洲色无码专区在线观看| 曰批视频免费40分钟试看天天| 在线观看亚洲专区| 亚洲A∨无码无在线观看| 成人免费网站在线观看| 久久国产美女免费观看精品| 亚洲蜜芽在线精品一区| 免费人成视频在线观看不卡| 免费看男人j放进女人j免费看| 亚洲视频无码高清在线| 亚洲中文字幕不卡无码|