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

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

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

    honzeland

    記錄點(diǎn)滴。。。

    常用鏈接

    統(tǒng)計(jì)

    Famous Websites

    Java

    Linux

    P2P

    最新評(píng)論

    Svn revision retrieve and logging to database

    最近接到兩個(gè)很小的tickets,兩個(gè)都是為了項(xiàng)目開(kāi)發(fā)時(shí)的方便:一是將logs寫(xiě)入到數(shù)據(jù)庫(kù)中,以方便日志的查詢;一是在build時(shí),在war包加入svn revision info。
    1) logging to database
    經(jīng)過(guò)調(diào)查,決定采用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
    很直觀,用起來(lái)還很方便,但是不久就出現(xiàn)了問(wèn)題,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了,找到了一個(gè)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. 長(zhǎng)嘆了一下。

    最后采用:
    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
    問(wèn)題解決,但是中間有點(diǎn)小波折,在我的項(xiàng)目中,log4j.jar(>1.2.9)重復(fù)了,在$CATALINA_HOME/lib下有一份,在web工程下的WEB-INF/lib下也有一份,而plus-jdbc.jar放置在$CATALINA_HOME/lib下,結(jié)果啟動(dòng)Tomcat,出現(xiàn)
    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".
    原來(lái)是兩個(gè)JDBCAppender實(shí)例不在同一個(gè)classlaoder里面,將WEB-INF/lib下的log4j.jar刪除掉,重啟就沒(méi)問(wèn)題了,按理,將$CATALINA_HOME/lib下的plus-jdbc.jar移到WEB-INF/lib下,應(yīng)該也沒(méi)問(wèn)題,沒(méi)有測(cè)試。

    2)Add build revision info in war file and read it on tomcat startup
    這個(gè)經(jīng)歷比較慘痛,兩個(gè)問(wèn)題,如何獲取revision? And how to read it when tomcat startup? 第二個(gè)問(wèn)題倒是沒(méi)什么,采用javax.servlet.ServletContextListener就可以實(shí)現(xiàn),很簡(jiǎn)單,走彎路的是第一個(gè)問(wèn)題,google后發(fā)現(xiàn)有兩種常見(jiàn)的實(shí)現(xiàn):
    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,遠(yuǎn)在烏克蘭的同事,該文件卻不是xml的,也只怪自己調(diào)研不充分,還得折騰了半天,后來(lái)發(fā)現(xiàn),最新版的svn為了performance的考慮,采用meta data來(lái)實(shí)現(xiàn)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(服務(wù)器在國(guó)外,更新很慢), 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.

    下面是第一版實(shí)現(xiàn):
        <!--  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>

    結(jié)果write-svn-revision-to-file這個(gè)在我這倒是可以獲取本地的svn revision,但是遠(yuǎn)方的同事可急了,build老失敗,只好把這部分build注釋了,還好,到周末了,可以在家好好研究一下,很快找了一個(gè)新的工具:
    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,從服務(wù)器上獲取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寫(xiě)入到一個(gè)配置文件中(如revision.properties),在tomcat啟動(dòng)的時(shí)候加載進(jìn)來(lái),就可以了。   

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

    評(píng)論

    # 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

    地址和用戶名密碼都暴露了,有沒(méi)有其他辦法?  回復(fù)  更多評(píng)論   

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

    可以設(shè)置在build時(shí)讓用戶輸入用戶名和密碼,或者把它們放在一個(gè)單獨(dú)的屬性文件里面(該文件只對(duì)個(gè)人可見(jiàn)),另外就比較復(fù)雜了,加密后存入文件  回復(fù)  更多評(píng)論   

    主站蜘蛛池模板: 国产午夜亚洲精品不卡电影| 免费被黄网站在观看| 国产免费毛不卡片| 国产亚洲情侣一区二区无| 亚洲人成网男女大片在线播放| 亚洲免费一区二区| 国产一区二区三区免费看| 亚洲AV成人一区二区三区在线看| 久久久久久久岛国免费播放| 久久久久久久亚洲精品| 国产精品怡红院永久免费| 亚洲成av人影院| 一级毛片免费播放男男| 亚洲精品偷拍视频免费观看| 国产精品国产亚洲区艳妇糸列短篇| 免费无码精品黄AV电影| 亚洲天堂2017无码中文| 亚洲欧洲美洲无码精品VA| 成人精品视频99在线观看免费| 亚洲精品456播放| 久久午夜免费视频| 亚洲jizzjizz少妇| 国产又大又黑又粗免费视频| 无码天堂亚洲国产AV| 亚洲综合小说久久另类区| 免费A级毛片无码无遮挡内射| 深夜福利在线视频免费| 亚洲区小说区图片区QVOD| 大学生高清一级毛片免费| 黄色一级视频免费| 亚洲中文字幕不卡无码| 免费播放一区二区三区| 亚洲码一区二区三区| 国产亚洲精午夜久久久久久| 精品国产精品久久一区免费式| 97av免费视频| 亚洲精品无码久久久久秋霞| 亚洲成a人片在线观看日本麻豆| 思思久久99热免费精品6| 久久精品国产亚洲AV蜜臀色欲 | 亚洲乱码av中文一区二区|