<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 閱讀(2192) 評論(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无码去区首| 久久久久亚洲av无码专区喷水| 亚洲综合国产成人丁香五月激情| 东北美女野外bbwbbw免费| 国产成人免费福利网站| 亚洲a∨无码一区二区| 国产免费人成在线视频| 国产精品亚洲精品日韩电影| 高清国语自产拍免费视频国产| 亚洲精品天堂成人片AV在线播放 | 免费大片黄在线观看yw| 亚洲男女一区二区三区| 九九精品免费视频| 亚洲狠狠婷婷综合久久| 又粗又硬又黄又爽的免费视频| 免费又黄又爽又猛大片午夜| 亚洲情综合五月天| 亚洲暴爽av人人爽日日碰| 永久免费无码网站在线观看 | 亚洲色最新高清av网站| 暖暖免费高清日本一区二区三区| 亚洲夜夜欢A∨一区二区三区| 免费无码黄网站在线看| 亚洲欧洲日产国码二区首页| 久久精品免费大片国产大片| 女人18毛片水真多免费播放| 国产精品亚洲片在线花蝴蝶| 亚洲色图综合在线| 亚洲AV色欲色欲WWW| 国产福利电影一区二区三区,亚洲国模精品一区 | 免费观看激色视频网站(性色)| 亚洲日本国产综合高清| 亚洲av午夜精品一区二区三区 | 亚洲日本中文字幕天天更新| 免费jlzzjlzz在线播放视频| a级毛片免费全部播放| 亚洲妇女熟BBW| 亚洲精品无码av人在线观看| 在线观看免费人成视频色9| 九九免费精品视频在这里| 亚洲v高清理论电影|