• <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>

            牽著老婆滿街逛

            嚴以律己,寬以待人. 三思而后行.
            GMail/GTalk: yanglinbo#google.com;
            MSN/Email: tx7do#yahoo.com.cn;
            QQ: 3 0 3 3 9 6 9 2 0 .

            開源日志系統(tǒng)log4cplus(七)

             

            經(jīng)過短暫的熟悉過程,log4cplus已經(jīng)被成功應用到了我的項目中去了,效果還不錯,:)除了上文提及的
            功能之外,下面將介紹log4cplus提供的線程和套接字的使用情況。

            ### NDC ###
            首先我們先了解一下log4cplus中嵌入診斷上下文(Nested Diagnostic Context),即NDC。對log系統(tǒng)而言,
            當輸入源可能不止一個,而只有一個輸出時,往往需要分辯所要輸出消息的來源,比如服務器處理來自不同
            客戶端的消息時就需要作此判斷,NDC可以為交錯顯示的信息打上一個標記(stamp), 使得辨認工作看起來
            比較容易些,呵呵。這個標記是線程特有的,利用了線程局部存儲機制,稱為線程私有數(shù)據(jù)(Thread-specific
             Data,或TSD)。 看了一下源代碼,相關定義如下,包括定義、初始化、獲取、設置和清除操作:
            linux pthread
            #   define LOG4CPLUS_THREAD_LOCAL_TYPE pthread_key_t*
            #   define LOG4CPLUS_THREAD_LOCAL_INIT ::log4cplus::thread::createPthreadKey()
            #   define LOG4CPLUS_GET_THREAD_LOCAL_VALUE( key ) pthread_getspecific(
            *key)
            #   define LOG4CPLUS_SET_THREAD_LOCAL_VALUE( key, value ) pthread_setspecific(
            *key, value)
            #   define LOG4CPLUS_THREAD_LOCAL_CLEANUP( key ) pthread_key_delete(
            *key)

            win32
            #   define LOG4CPLUS_THREAD_LOCAL_TYPE DWORD
            #   define LOG4CPLUS_THREAD_LOCAL_INIT TlsAlloc()
            #   define LOG4CPLUS_GET_THREAD_LOCAL_VALUE( key ) TlsGetValue(key)
            #   define LOG4CPLUS_SET_THREAD_LOCAL_VALUE( key, value ) \       TlsSetValue(key, static_cast(value))
            #   define LOG4CPLUS_THREAD_LOCAL_CLEANUP( key ) TlsFree(key)
            				
            使用起來比較簡單,在某個線程中:
                NDC& ndc = log4cplus::getNDC();
                ndc.push(
            "ur ndc string");
                LOG4CPLUS_DEBUG(logger, 
            "this is a NDC test");
                 
                ndc.pop();
                    
                LOG4CPLUS_DEBUG(logger, 
            "There should be no NDC");
                ndc.remove();


               
            當設定輸出格式(Layout)為TTCCLayout時,輸出如下:
            10-21-04 21:32:58, [3392] DEBUG test  - this is a NDC test
            10-21-04 21:32:58, [3392] DEBUG test <> - There should be no NDC...
            也可以在自定義的輸出格式中使用NDC(用%x) ,比如:
                 
              std::
            string pattern = "NDC:[%x]  - %m %n";
              std::auto_ptr _layout(
            new PatternLayout(pattern));
                 
             LOG4CPLUS_DEBUG(_logger, 
            "This is the FIRST log message")
              NDC
            & ndc = log4cplus::getNDC();
              ndc.push(
            "ur ndc string"); 
              LOG4CPLUS_WARN(_logger, 
            "This is the SECOND log message")
              ndc.pop();
             ndc.remove(); 
                

               
            輸出如下:
            NDC:[]  - This is the FIRST log message...
            NDC:[ur ndc string]  - This is the SECOND log message...
            				
            另外一種更簡單的使用方法是在線程中直接用NDCContextCreator:
                NDCContextCreator _first_ndc("ur ndc string");
                LOG4CPLUS_DEBUG(logger, 
            "this is a NDC test")

               
            不必顯式地調用push/pop了,而且當出現(xiàn)異常時,能夠確保push與pop的調用是匹配的。
                
            ### 線程 ###
            線程是log4cplus中的副產(chǎn)品, 而且僅作了最基本的實現(xiàn),使用起來也異常簡單,只要且必須要
            在派生類中重載run函數(shù)即可:
            class TestThread : public AbstractThread
            {
            public:
                
            virtual void run();
            }
            ;
                            
            void TestThread::run()

               
            /* do sth. */ 
                
            }

            log4cplus的線程沒有考慮同步、死鎖,有互斥,實現(xiàn)線程切換的小函數(shù)挺別致的:
            void log4cplus::thread::yield()
            {
            #if defined(LOG4CPLUS_USE_PTHREADS)
                ::sched_yield();
            #elif defined(LOG4CPLUS_USE_WIN32_THREADS)
                ::Sleep(
            0);
            #endif
            }
            				
            ### 套接字 ###
            套接字也是log4cplus中的副產(chǎn)品,在namespace log4cplus::helpers中,實現(xiàn)了C/S方式的日志記錄。
            1. 客戶端程序需要做的工作:
            /* 定義一個SocketAppender類型的掛接器 */SharedAppenderPtr _append(new SocketAppender(host, 8888"ServerName"));
            /* 把_append加入到logger中 */Logger::getRoot().addAppender(_append);
            /*  SocketAppender類型不需要Layout, 直接調用宏就可以將信息發(fā)往loggerServer了 */LOG4CPLUS_INFO(Logger::getRoot(), "This is a test: ")

            【注】 這里對宏的調用其實是調用了SocketAppender::append,里面有一個數(shù)據(jù)傳輸約定,即先發(fā)送
            一個后續(xù)數(shù)據(jù)的總長度,然后再發(fā)送實際的數(shù)據(jù):
                 
                SocketBuffer buffer 
            = convertToBuffer(event, serverName);
                SocketBuffer msgBuffer(LOG4CPLUS_MAX_MESSAGE_SIZE);
                msgBuffer.appendSize_t(buffer.getSize());
                msgBuffer.appendBuffer(buffer);        
            				
            2. 服務器端程序需要做的工作:
            /* 定義一個ServerSocket */ServerSocket serverSocket(port);
             
            /* 調用accept函數(shù)創(chuàng)建一個新的socket與客戶端連接 */Socket sock = serverSocket.accept();
            				
            此后即可用該sock進行數(shù)據(jù)read/write了,形如:
            SocketBuffer msgSizeBuffer(sizeof(unsigned int));
            if(!clientsock.read(msgSizeBuffer))
            {
                
            return;
            }

            unsigned 
            int msgSize = msgSizeBuffer.readInt();
            SocketBuffer buffer(msgSize);
            if(!clientsock.read(buffer))
            {
                
            return;
            }

            為了將讀到的數(shù)據(jù)正常顯示出來,需要將SocketBuffer存放的內容轉換成InternalLoggingEvent格式:
            spi::InternalLoggingEvent event = readFromBuffer(buffer);
            然后輸出:
            Logger logger = Logger::getInstance(event.getLoggerName());
            logger.callAppenders(
            event);
            				
            【注】 read/write是按照阻塞方式實現(xiàn)的,意味著對其調用直到滿足了所接收或發(fā)送的個數(shù)才返回。

            posted on 2006-08-26 04:51 楊粼波 閱讀(5407) 評論(3)  編輯 收藏 引用 所屬分類: Windows編程Linux編程

            評論

            # re: 開源日志系統(tǒng)log4cplus(七)[未登錄] 2008-04-18 12:17 cppexplore

            精彩!多多發(fā)點這種造福大眾的文章啊!  回復  更多評論   

            # re: 開源日志系統(tǒng)log4cplus(七) 2008-07-23 14:54 齊全愛

            很好,多謝!!!支持你!!!  回復  更多評論   

            # re: 開源日志系統(tǒng)log4cplus(七) 2010-05-13 17:22 yacper

            perfect  回復  更多評論   

            久久精品国产福利国产琪琪| 久久免费看黄a级毛片| 久久久精品国产免大香伊| 色综合久久久久网| 狠狠色丁香婷综合久久| 人妻精品久久久久中文字幕69| 久久久久久久97| 伊色综合久久之综合久久| 亚洲伊人久久综合中文成人网| 精品久久久无码中文字幕天天| 中文字幕一区二区三区久久网站 | 国产91色综合久久免费分享| 色欲综合久久中文字幕网| 久久久女人与动物群交毛片| 2022年国产精品久久久久| 亚洲国产精品婷婷久久| 久久久久久久亚洲精品| 精品久久久久久无码不卡| 嫩草伊人久久精品少妇AV| 久久精品国产亚洲AV香蕉| 久久亚洲欧美日本精品| 国产精品伦理久久久久久| 欧美伊人久久大香线蕉综合69| 精品久久久久久无码不卡| 精品久久久久久久久午夜福利| www.久久精品| 四虎影视久久久免费观看| 无码超乳爆乳中文字幕久久| 久久免费小视频| 三级韩国一区久久二区综合| 日日噜噜夜夜狠狠久久丁香五月| 国产精品久久久久久福利漫画| 久久精品无码免费不卡| 国产成人精品综合久久久久| 久久精品成人国产午夜| 久久久久久曰本AV免费免费| 秋霞久久国产精品电影院| 97精品伊人久久久大香线蕉| 国产午夜电影久久| 久久亚洲AV成人无码国产| 久久亚洲AV无码西西人体|