• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            CppExplore

            一切像霧像雨又像風(fēng)

              C++博客 :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
              29 隨筆 :: 0 文章 :: 280 評論 :: 0 Trackbacks

            作者:CppExplore 網(wǎng)址:http://www.shnenglu.com/CppExplore/
            log模塊是一個小模塊,卻是每個系統(tǒng)必備的模塊。優(yōu)秀的系統(tǒng)一定會有優(yōu)秀的log信息,也可以說全面到位的log信息在一定程度上決定了一個系統(tǒng)的健壯性。在linux上,log模塊是跟蹤程序運行,驗證業(yè)務(wù)邏輯正確的唯一方法。
            一、功能
            一個優(yōu)秀的log系統(tǒng)應(yīng)該包含以下功能:
            (1)支持打印到屏幕、文件、socket、syslog
            (2)支持分級別打印
            (3)支持分模塊打印
            (4)支持多線程
            (5)支持文件轉(zhuǎn)儲:按時間、按大小。
            二、使用原則
            方便說明,這里定義8個log級別:

            typedef enum{
                XLOG_CRITICAL
            =0x1,
                XLOG_ERROR
            =0x2,
                XLOG_WARNING
            =0x4,
                XLOG_NOTICE
            =0x8,
                XLOG_INFO
            =0x10,
                XLOG_DEBUG
            =0x20,
                XLOG_TRACE
            =0x40,
                XLOG_ALL
            =0x80
            }
            XLogLevel;
            使用方式舉例如下:
            X_LOG(XLOG_NOTICE,"message[%s:%d]\n",char_value,int_value);

            打印log的原則:
            (1)重要的函數(shù)(業(yè)務(wù)處理)入口處打印XLOG_DEBUG級別log,打印出函數(shù)名稱、入口參數(shù)。
            (2)函數(shù)有多個執(zhí)行支路,在異常退出函數(shù)的支路上,打印XLOG_WARNING級別log,表明退出原因。
            (3)系統(tǒng)調(diào)用發(fā)生異常,甚至造成程序退出的地方,打印XLOG_ERROR級別log,表明發(fā)生該錯誤的文件、行數(shù)、錯誤號
            (4)為所有的類對象實現(xiàn)dump方法,該方法打印該類中的所有私有屬性信息,以XLOG_NOTICE級別打印,當類對象中含有自定義的類屬性時,該類的dump中打印屬性類信息可以直接調(diào)用屬性類的dump。運行期間,可以給用戶提供輸入接口:telnet、交互式shell命令行、或者簡單的getchar,根據(jù)用戶要求,執(zhí)行頂級類對象的dump,以運行期間查看系統(tǒng)內(nèi)所有數(shù)據(jù)的內(nèi)部信息。
            (5)該系統(tǒng)與外在系統(tǒng)的交互信息,往來數(shù)據(jù)包使用XLOG_INFO級別打印。
            (6)為了調(diào)試系統(tǒng),更為細微的查看系統(tǒng)的運行狀況而加入的log,使用XLOG_TRACE級別。
            三、log模塊框架
            可選的開源log很多:ace_log/Log4c/log4c**/log4c++/Pantheios/Log4cplus。依據(jù)開源項目活躍程度、庫本身的獨立性以及參考文檔的數(shù)量,個人選擇的開源庫是Log4cplus。個人測試,未發(fā)現(xiàn)該庫(v1.02)有bug或者內(nèi)存泄漏現(xiàn)象,大力推薦。網(wǎng)上有關(guān)該庫的文檔的也相當多,我就不再羅唆了。
            下面是我的log框架,不依賴于具體的log模塊,相信你會喜歡:

            #ifndef _X_LOG_H_
            #define _X_LOG_H_
            #include 
            <stdio.h>
            #include 
            <errno.h>

            #ifdef USE_LOG4CPLUS
                #include 
            <log4cplus/configurator.h>
                #include 
            <string>
                
            static log4cplus::Logger logger= log4cplus::Logger::getInstance("Log");
                
            static void init_log(const std::string & path)
                
            {
                    log4cplus::PropertyConfigurator::doConfigure(path);   
                }

                #define XLOG_ALL        log4cplus::TRACE_LOG_LEVEL
                #define XLOG_TRACE        log4cplus::TRACE_LOG_LEVEL
                #define XLOG_DEBUG        log4cplus::DEBUG_LOG_LEVEL
                #define XLOG_INFO            log4cplus::INFO_LOG_LEVEL
                #define XLOG_NOTICE        log4cplus::INFO_LOG_LEVEL
                #define XLOG_WARNING    log4cplus::WARN_LOG_LEVEL
                #define XLOG_ERROR        log4cplus::ERROR_LOG_LEVEL
                #define XLOG_CRITICAL    log4cplus::FATAL_LOG_LEVEL

                #define X_LOG(l, ) \
                
            do { \
                    
            if(logger.isEnabledFor(l)) { \
                        
            char __buf__internal__[2046]={0}; \
                        snprintf(__buf__internal__,
            2045,__VA_ARGS__); \
                        logger.forcedLog(l, __buf__internal__, __FILE__, 

            __LINE__); \
                    }
             \
                }
             while(0);
            #elif define USE_ACE_LOG
                #include 
            "ace/Log_Msg.h"
                #include 
            "ace/Trace.h"
                #define XLOG_ALL        LM_TRACE
                #define XLOG_TRACE        LM_TRACE
                #define XLOG_DEBUG        LM_DEBUG
                #define XLOG_INFO             LM_INFO
                #define XLOG_NOTICE        LM_NOTICE
                #define XLOG_WARNING    LM_WARNING
                #define XLOG_ERROR        LM_ERROR
                #define XLOG_CRITICAL        LM_CRITICAL
                #define X_LOG(l,
            do{ \
                    ACE_DEBUG((l,
            "[%T|%t] %s-%s:%

            d
            ",__FILE__,__FUNCTION__,__LINE__)); \
                    ACE_DEBUG((l,__VA_ARGS__)); \
                    }
            while(0)
            #
            else
                #include 
            <pthread.h>
                #include 
            <time.h>
                #include 
            <sys/time.h>
                #define XLOG_LEVEL 
            0xFF
                typedef 
            enum{
                    XLOG_CRITICAL
            =0x1,
                    XLOG_ERROR
            =0x2,
                    XLOG_WARNING
            =0x4,
                    XLOG_NOTICE
            =0x8,
                    XLOG_INFO
            =0x10,
                    XLOG_DEBUG
            =0x20,
                    XLOG_TRACE
            =0x40,
                    XLOG_ALL
            =0x80
                }
            XLogLevel;
                #define X_LOG(l,
            do{ \
                    
            if(XLOG_LEVEL&l){ \
                            struct timeval now;\
                            gettimeofday(
            &now,0); \
                            struct tm 
            *ptm=localtime(&(now.tv_sec)); \
                            printf(
            "[%d|%d:%d:%d.%d] [%s/%s/%d] 

            ",pthread_self(),ptm->tm_hour,ptm->tm_min,ptm-

            >tm_sec,now.tv_usec,__FILE__,__FUNCTION__,__LINE__); \
                            printf( __VA_ARGS__); \
                        }
             \
                    }
            while(0)
            #endif

            #define die(str) 
            {X_LOG(XLOG_WARNING,str); return;}

            #define die_0(str) 
            {X_LOG(XLOG_WARNING,str); return 0; }

            #define die_1(str) 
            {X_LOG(XLOG_WARNING,str); return -1; }

            #define die_ns(str) 
            {X_LOG(XLOG_WARNING,str); return ""; }

            /*safe func return empty,0,-1*/
            #define SAFE_FUNC(func) 
            if((func)<0) \
                
            { \
                    X_LOG(XLOG_ERROR,
            "[%s:%d]error!error[%d:%s]

            \n
            ",__FILE__,__LINE__,errno,strerror(errno)); \
                    exit(-1); \
                }


            /*safe func but 1 err return empty,0,-1*/
            #define SAFE_FUNC_BUT_ERR1(func,ERR1) 
            do \
                
            { \
                    
            if((func)<0){ \
                        X_LOG(XLOG_ERROR,
            "[%s:%d]error!error[%d:%s]

            \n
            ",__FILE__,__LINE__,errno,strerror(errno)); \
                        if(errno!=ERR1) exit(-1); \
                    }
             \
                    
            else break; \
                }
            while(1)

            /*safe func but 2 err return empty,0,-1*/
            #define SAFE_FUNC_BUT_ERR2(func,ERR1,ERR2) 
            do \
                
            { \
                    
            if((func)<0){ \
                        X_LOG(XLOG_ERROR,
            "[%s:%d]error!error[%d:%s]

            \n
            ",__FILE__,__LINE__,errno,strerror(errno)); \
                        if(errno!=ERR1&&errno!=ERR2)  exit(-1); \
                    }
             \
                    
            else break; \
                }
            while(1)
            #endif

            當前的XLog.h文件實現(xiàn)了使用log4cplus、ace、printf三種方式,當然可以隨意擴展。die則是XLOG_WARNING的打印方式,SAFE_FUNC是XLOG_ERROR的打印方式。
            如果要使用log4cplus,請定義USE_LOG4CPLUS宏,使用的時候在進程開始處,

            #ifdef  USE_LOG4CPLUS
              init_log(
            "log.properties");
            #endif

            以X_LOG的方式使用log4cplus,你可以對log4cplus一無所知。執(zhí)行你編譯好的程序前,在可執(zhí)行程序的目錄下建立log.properties文件,內(nèi)容你可以這樣寫:

            # Define the root logger
            log4cplus.rootLogger
            =TRACE, consoleAppender, fileAppender

            # Define a file appender named 
            "consoleAppender"
            log4cplus.appender.consoleAppender
            =log4cplus::ConsoleAppender
            log4cplus.appender.consoleAppender.layout
            =log4cplus::PatternLayout
            log4cplus.appender.consoleAppender.layout.ConversionPattern
            =%-5p-[%t][%D{%H:%M:%%Q}]%m

            # Define a file appender named 
            "fileAppender"
            log4cplus.appender.fileAppender
            =log4cplus::RollingFileAppender
            log4cplus.appender.fileAppender.MaxFileSize
            =200KB
            log4cplus.appender.fileAppender.File
            =./log.log
            log4cplus.appender.fileAppender.MaxBackupIndex
            =3
            log4cplus.appender.fileAppender.layout
            =log4cplus::PatternLayout
            log4cplus.appender.fileAppender.layout.ConversionPattern
            =%-5p-[%t][%D{%H:%M:%%Q}]%m

            有關(guān)log.properties文件的配置,可以自行去查找有關(guān)log4cplus的文章。如果你沒使用過log4cplus,ok,那么下載一個log4cplus,編譯,依據(jù)本文的XLog.h文件構(gòu)建一個系統(tǒng),嘗試以下,你一定會驚嘆log4cplus的強大與美妙。

            posted on 2008-06-05 09:54 cppexplore 閱讀(7141) 評論(23)  編輯 收藏 引用

            評論

            # re: 【原創(chuàng)】系統(tǒng)設(shè)計之 必備外圍功能-log 2008-06-05 11:38 true
            知識面很廣啊,不知工作中開發(fā)什么呢  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】系統(tǒng)設(shè)計之 必備外圍功能-log[未登錄] 2008-06-05 12:08 cppexplore
            @true
            呵呵 linux上的應(yīng)用服務(wù)器 軟交換服務(wù)器 流媒體服務(wù)器等。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】系統(tǒng)設(shè)計之 必備外圍功能-log 2008-06-05 12:28 true
            汗。。。,我和你可能有些緣分,我也在linux開發(fā)應(yīng)用服務(wù)器,語音板卡,信令。哈哈。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】系統(tǒng)設(shè)計之 必備外圍功能-log[未登錄] 2008-06-05 12:48 cppexplore
            還沒接觸過語音板卡 我們的應(yīng)用沒有媒體編解碼或者dtmf檢測的。有時間向你討教討教,留個聯(lián)系方式吧,我的gtalk/gmail是gamil.com的,msn是live.com的,名稱都是zongjinliang。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】系統(tǒng)設(shè)計之 必備外圍功能-log 2008-06-05 17:50 Kevin Lynx
            日志對于一個系統(tǒng)來說確實是必不可少的基礎(chǔ)模塊。
            我用模板寫了個不依賴于具體‘寫’的日志類,簡單的日志等級過濾。
            ///
            /// @file kl_logger.h
            /// @author Kevin Lynx
            /// @date 4.21.2008
            ///
            #ifndef ___KL_LOGGER_H_
            #define ___KL_LOGGER_H_

            #include <assert.h>
            #include <stdarg.h>
            #include <time.h>
            #include <fstream>
            #include "kl_compiler_cfg.h"

            KL_COMMON_NAMESPACE_BEGIN

            /// log level
            enum log_level
            {
            LL_MIN = -1,
            LL_ERROR,
            LL_WARNING,
            LL_INFO,
            LL_DEBUG,
            LL_MAX
            };

            ///
            /// default log pre-string, add system time and log level.
            ///
            struct default_log_prestr
            {
            /// output pre-string in the buffer
            /// @return the offset of the buf.
            std::size_t operator() ( char *buf, int level )
            {
            char time[9];
            char date[9];
            _strtime( time );
            _strdate( date );

            const char *ll_desc = 0;
            switch( level )
            {
            case LL_ERROR:
            ll_desc = "ERROR";
            break;
            case LL_WARNING:
            ll_desc = "WARNING";
            break;
            case LL_INFO:
            ll_desc = "INFO";
            break;
            case LL_DEBUG:
            ll_desc = "DEBUG";
            break;

            default:
            ll_desc = "UNKNOWN";
            }

            // combine
            sprintf( buf, "%s %s %s : ", date, time, ll_desc );
            return strlen( buf ) ;
            }
            };

            ///
            ///
            /// A simple logger class to write log information.
            ///
            /// @param _Output where the log information to put, it must implement 'log( const char*)' function.
            /// @param _PreStr used to write the pre-string of the log text like : 4.21.2008 : something.
            /// @param string_size used when format string.(static buffer is more fast than dynamic buffer)
            template <typename _Output, typename _PreStr = default_log_prestr, std::size_t _string_size = 1024>
            class logger
            {
            public:
            /// output object type
            typedef _Output output_type;

            /// pre-string type
            typedef _PreStr prestr_type;

            /// string size used when formatting strings.
            enum
            {
            string_size = _string_size
            };

            public:
            /// constructor
            logger() :
            _output( 0 ), _level( LL_DEBUG )
            {
            }

            /// destructor
            ~logger()
            {
            }

            /// set the output manager, you must call this function before you
            /// log anything.
            void set_output( output_type *ot )
            {
            assert( ot != 0 && "logger::set_output : invalid arguments." );
            _output = ot;
            }

            /// write log text
            void write_only( int level, const char *format, ... )
            {
            assert( _output != 0 && "logger::write_only : You must set up the output manager before you log anything." );
            static char buf[string_size];

            // checck the level
            if( level > _level ) return ;

            // format the string
            va_list list;
            va_start( list, format );
            vsprintf( buf, format, list );
            va_end( list );

            // output the log text
            _output->log( buf );
            }

            /// write log text and append prestring
            void write( int level, const char *format, ... )
            {
            assert( _output != 0 && "logger::write : You must set up the output manager before you log anything." );
            static char buf[string_size];

            // checck the level
            if( level > _level ) return ;

            // append pre-string
            std::size_t pos = _prestr( buf, level );

            // format the string
            va_list list;
            va_start( list, format );
            vsprintf( &buf[pos], format, list );
            va_end( list );

            // output the log text
            _output->log( buf );
            }

            /// set log level
            void set_level( int level )
            {
            assert( level > LL_MIN && level < LL_MAX && "logger::set_level : invalid arguments." );
            _level = level;
            }

            /// get the log level
            int get_level()
            {
            return _level;
            }

            private:
            /// output manager to collect log text.
            output_type *_output;
            /// pre-str to append some text before the log text
            prestr_type _prestr;
            /// log level
            int _level;
            };

            ///
            /// The file log output manager, write log text to the file.
            ///
            class file_output
            {
            public:
            /// constructor
            file_output()
            {
            }

            /// this constructor will open the file
            file_output( const std::string filename, std::ios_base::openmode _Mode = std::ios_base::out ) :
            _file_handle( filename.c_str(), _Mode )
            {
            }

            /// destructor
            ~file_output()
            {
            }

            /// open the file if it's not open
            bool open( const std::string filename, std::ios_base::openmode _Mode = std::ios_base::out )
            {
            if( _file_handle.is_open() )
            {
            return false;
            }

            _file_handle.open( filename.c_str(), _Mode );
            return _file_handle.is_open();
            }

            /// log
            void log( const char *str )
            {
            assert( _file_handle.is_open() && "file_output::log : you cannot write anything before you open the file!" );
            _file_handle << str ;
            _file_handle.flush();
            }

            private:
            /// output file
            std::ofstream _file_handle;
            };

            KL_COMMON_NAMESPACE_END

            #endif // end ___KL_LOGGER_H_  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】系統(tǒng)設(shè)計之 必備外圍功能-log 2008-06-05 19:44 cppexplore
            呵呵 以為我的log框架你會喜歡,看來我錯了。不過還有一句話“如果你沒使用過log4cplus,ok,那么下載一個log4cplus,編譯,......,嘗試以下,你一定會驚嘆log4cplus的強大與美妙。”  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log 2008-12-02 13:18 mono
            logger如果建立多個,日志文件會狂長,因為每次調(diào)用LOG4CPLUS_LEVEL,每個logger都記錄一次

            我奇怪,logger.shutdown 好像沒有作用

            看起來static 好像可以,但是如果你在多個地方都指定properties,logger還是會運行多次,而
            log4cplus::PropertyConfigurator::doConfigure(LOG4CPLUS("log4cplus.properties"));
            又不能static

            當然導(dǎo)入一次properties會記錄正確,我又不明白,如果你在某一個函數(shù)里聲明,它什么時候會消亡呢。我覺得在某一個函數(shù)里聲明properties,它就是全局的嗎,那我希望某個地方換一個properties,比如某個函數(shù)是在不同的路徑甚至機器下運行,還能不能保證還是這個properties,或者根據(jù)當前位置的相對路徑無法找到需要的properties



            另外,lz的宏編譯錯誤,我自己寫了一個宏

            static log4cplus:tostringstream _str_buf;
            static log4cplus::Logger logger= log4cplus::Logger::getInstance("filelogger");

            X_LOG( logInfo, logLevel) \
            _str_buf.clear();
            _str_buf << logInfo;
            logger.forceLog( logLevel, _str_buf.str(), __FILE__, __LINE__ )

            在vs 2005下編譯成功,并且也確實記錄了,問題就是,即使你指定properties,它也不按照格式配置記錄,而是自己把日志內(nèi)容按行紀錄,根本無視 時間、線程等等格式

            這個宏與log4cplus本身的宏并沒有什么區(qū)別,為什么看起來并沒有讀properties呢

              回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log[未登錄] 2008-12-02 19:05 cppexplore
            @mono
            #define USE_LOG4CPLUS
            之后就編譯正確了吧,或者你把define USE_ACE_LOG那段去掉,可以用printf調(diào)式。
            你的需求是什么樣子的?我用于server端程序,在main函數(shù)開始,來句:
            #ifdef USE_LOG4CPLUS
            init_log("./log.properties");
            #endif
            之后就再就是正常的程序啟動了,起各個協(xié)議棧、線程。當然log也都是打印在一個log文件里。
            server端程序是一直運行的,不會退出,也就不存在消亡的問題。
              回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log 2008-12-10 11:34 guosha
            very good,
            博主用過log4c嗎?感覺如何?  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log[未登錄] 2008-12-10 11:56 cppexplore
            @guosha
            沒有用過。
            log是個小功能,封裝下能做到透明使用基本就可以了。log4c依賴apr庫,如果你的主體程序不是在apr上構(gòu)建的話,引入log4c不太舒服,呵呵。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log[未登錄] 2008-12-10 12:01 cppexplore
            @mono,給你個可以編譯通過的宏,不知道你是win下還linux下,下面的宏都可以,另外流式的log不容易和printf、ace等對應(yīng),也看個人喜好,我是認為printf的方式更容易格式化輸出。
            #define USE_LOG4CPLUS
            #ifdef USE_LOG4CPLUS
            #include <log4cplus/configurator.h>
            #include <string>
            static log4cplus::Logger logger= log4cplus::Logger::getInstance("Log");
            static void init_log(const std::string & path)
            {
            log4cplus::PropertyConfigurator::doConfigure(path);
            }
            #define XLOG_ALL log4cplus::TRACE_LOG_LEVEL
            #define XLOG_TRACE log4cplus::TRACE_LOG_LEVEL
            #define XLOG_DEBUG log4cplus::DEBUG_LOG_LEVEL
            #define XLOG_INFO log4cplus::INFO_LOG_LEVEL
            #define XLOG_NOTICE log4cplus::INFO_LOG_LEVEL
            #define XLOG_WARNING log4cplus::WARN_LOG_LEVEL
            #define XLOG_ERROR log4cplus::ERROR_LOG_LEVEL
            #define XLOG_CRITICAL log4cplus::FATAL_LOG_LEVEL

            #ifdef WIN32
            #if (_MSC_VER < 1500)
            #define vsnprintf _vsnprintf
            #endif
            void inline win_log( int l, const char *format, ... )
            {
            if(logger.isEnabledFor(l)) {
            schar buf[2046]={0};
            va_list list;
            va_start( list, format );
            vsnprintf( buf, (size_t)2045,format, list );
            va_end( list );
            logger.forcedLog(l, buf, __FILE__, __LINE__);
            }
            }
            #define X_LOG win_log
            #else
            #define X_LOG(l, ...) \
            do { \
            if(logger.isEnabledFor(l)) { \
            char __buf__internal__[2046]={0}; \
            snprintf(__buf__internal__,2045,__VA_ARGS__); \
            logger.forcedLog(l, __buf__internal__, __FILE__, __LINE__); \
            } \
            } while(0)
            #endif  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log 2008-12-17 21:55 田伯光
            樓主,多進程可以用嗎?  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log 2008-12-17 22:16 田伯光
            樓主, 是把log4cplus編譯成一個靜態(tài)庫或是動態(tài)庫后就直接使用你這個套上去就可以用嗎?  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log 2008-12-17 22:35 田伯光
            看上去我好像已經(jīng)弄明白怎么用了, 不知道博主可有比較完備一點的有關(guān)LOG配置的文檔? 另外多進程程序使用這個log系統(tǒng)會不會有什么問題?  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log[未登錄] 2008-12-18 18:54 cppexplore
            @田伯光
            多個進程指向同一個文件的話,的確都可以寫進去。至于是不是穩(wěn)定就不清楚了,呵呵,我一直是單進程多線程下使用,偶爾忘記程序已經(jīng)啟動,第二次啟動,同樣會把log寫進文件。
            你多測試下吧。
            log4cplus的配置文件的配置方式網(wǎng)上不少,或者你留個郵箱,我發(fā)給你。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log 2008-12-23 15:30 田伯光
            @cppexplore
            guosha167@yahoo.com.cn

            謝謝  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log 2008-12-23 16:54 田伯光
            多進程的話,不知道它是不是可以做到在一個進程內(nèi)改了配置,自動的其它進程也可以使用更改過后的配置,并且不需要重新啟動程序。最好能做到交互式的,在程序運行期間能動態(tài)控制Loger的打印行為。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log[未登錄] 2008-12-23 21:18 cppexplore
            @田伯光
            呵呵,多進程一定不能共享對象,除非這個對象在共享內(nèi)存中,共享內(nèi)存中的對象又要注意互斥問題。最好的辦法還是各進程用自己的進程的log對象。運行期間動態(tài)改變log的級別,可以去代碼中找答案,或者你等我有了這個需求,我改好告訴你,呵呵。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log 2008-12-23 23:24 田伯光
            @cppexplore
            是這樣的, 我以前寫的簡單的Log模塊就是用共享內(nèi)存把log的管理結(jié)構(gòu)共享出來, 這樣動態(tài)控制只需要更改這個結(jié)構(gòu)的內(nèi)容就可以了,但我以前寫的只是控制一下級別跟打印的目的地,沒有這個功能那么多,呵呵. C++我不熟悉, 所以不想去研究這個的代碼,故問你一下以得到現(xiàn)成結(jié)果.
              回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log[未登錄] 2008-12-24 09:20 cppexplore
            @田伯光
            log4cplus是線程安全的。多進程共享內(nèi)存的方式使用對象,和多線程的方式是一樣的。你可以壓力下測試下,呵呵。
            另外,打印到syslogd和打印到socket也是多進程打印log的備選方案。
            log系統(tǒng)用開源也不是因為它們功能強大,主要的好處是它們充分考慮了IO輸出的效率(開辟內(nèi)存池,延遲批量輸出),第二個是系統(tǒng)宕掉時候,log打印的準確性。另外用宏隔離,也方便以后發(fā)現(xiàn)更好log系統(tǒng)時候替換。  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log 2009-02-08 18:07 sashion
            能否介紹一下log4cplus如何支持文件轉(zhuǎn)儲?能在core dump 之前把所有的對象都dump到日志中嗎?是如何實現(xiàn)的?  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log[未登錄] 2009-02-19 10:36 cppexplore
            @sashion
            不曉的啊,可以去看源代碼 :)  回復(fù)  更多評論
              

            # re: 【原創(chuàng)】技術(shù)系列之 必備外圍功能-log[未登錄] 2011-06-04 13:31 cppexplore
            2年前對日志完善了不少,以前的錯誤引導(dǎo)更正下
            @田伯光
            多進程打印問題:
            不可以多進程打印, 除了寫不能保證原子性,還有文件更換時的問題.
            共享內(nèi)存共享log對象可以, 這樣還不如各自打印獨立文件, 同時使用遠程syslog方式統(tǒng)一打印到遠程(需要自己實現(xiàn)appender)

            動態(tài)生效問題:
            可使用ConfigureAndWatchThread類達到目的, 同時log4cplus中有不少bug,使用這個功能時 要修改不少地方.

            @sashion
            上上個我的留言里說錯了很多地方.
            log4cplus沒有提供延遲輸出的策略, 新的維護者有計劃增加異步,還沒增加.實現(xiàn)異步延遲打印,需要自己進一步封裝實現(xiàn).

            "能在core dump 之前把所有的對象都dump到日志中嗎?"
            不能. 因log4cplus沒有提供延遲輸出的策略, 日志同步打印,也不存在這個問題. 若自己實現(xiàn)異步延遲輸出的話, 延遲輸出的部分可以使用共享內(nèi)存,另可捕獲信號做一定補償.  回復(fù)  更多評論
              


            只有注冊用戶登錄后才能發(fā)表評論。
            網(wǎng)站導(dǎo)航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


            九九99精品久久久久久| 中文字幕无码免费久久| 亚洲综合熟女久久久30p| 精品久久久无码中文字幕天天| 婷婷综合久久狠狠色99h| 天堂无码久久综合东京热| 97久久精品人人做人人爽| 久久久久99精品成人片欧美| 亚洲精品国精品久久99热一| 中文字幕热久久久久久久| 亚洲中文字幕无码久久2017 | 久久99精品久久久久久水蜜桃 | 精品久久久久久无码人妻蜜桃| 麻豆AV一区二区三区久久| 久久久久99这里有精品10| 伊人久久成人成综合网222| 深夜久久AAAAA级毛片免费看 | 一本一道久久a久久精品综合| 久久久久99精品成人片牛牛影视| 精品久久人人妻人人做精品| 99久久无码一区人妻| 国产免费久久久久久无码| 人人狠狠综合88综合久久| 色婷婷狠狠久久综合五月| 无码人妻久久一区二区三区蜜桃| 77777亚洲午夜久久多人| 免费无码国产欧美久久18| 性做久久久久久久| 欧美日韩中文字幕久久伊人| 国内精品久久久久久久影视麻豆| 色妞色综合久久夜夜| 久久精品国产亚洲AV无码偷窥| Xx性欧美肥妇精品久久久久久 | 久久精品卫校国产小美女| 久久久噜噜噜久久中文字幕色伊伊| 久久被窝电影亚洲爽爽爽| 久久精品国产99久久久香蕉| 亚洲av伊人久久综合密臀性色| 国产成人香蕉久久久久 | 亚洲国产精品成人久久蜜臀| 久久精品人妻中文系列|