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

            開源日志系統log4cplus(七)

             

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

            ### NDC ###
            首先我們先了解一下log4cplus中嵌入診斷上下文(Nested Diagnostic Context),即NDC。對log系統而言,
            當輸入源可能不止一個,而只有一個輸出時,往往需要分辯所要輸出消息的來源,比如服務器處理來自不同
            客戶端的消息時就需要作此判斷,NDC可以為交錯顯示的信息打上一個標記(stamp), 使得辨認工作看起來
            比較容易些,呵呵。這個標記是線程特有的,利用了線程局部存儲機制,稱為線程私有數據(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了,而且當出現異常時,能夠確保push與pop的調用是匹配的。
                
            ### 線程 ###
            線程是log4cplus中的副產品, 而且僅作了最基本的實現,使用起來也異常簡單,只要且必須要
            在派生類中重載run函數即可:
            class TestThread : public AbstractThread
            {
            public:
                
            virtual void run();
            }
            ;
                            
            void TestThread::run()

               
            /* do sth. */ 
                
            }

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

            【注】 這里對宏的調用其實是調用了SocketAppender::append,里面有一個數據傳輸約定,即先發送
            一個后續數據的總長度,然后再發送實際的數據:
                 
                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函數創建一個新的socket與客戶端連接 */Socket sock = serverSocket.accept();
            				
            此后即可用該sock進行數據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;
            }

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

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

            評論

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

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

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

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

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

            perfect  回復  更多評論   

            国产成人久久久精品二区三区 | 久久精品麻豆日日躁夜夜躁| 77777亚洲午夜久久多喷| 超级97碰碰碰碰久久久久最新| 性欧美大战久久久久久久久| 精品精品国产自在久久高清| 久久有码中文字幕| 久久精品国产亚洲av高清漫画| 久久AAAA片一区二区| 色婷婷久久综合中文久久蜜桃av | 狠狠色丁香久久综合五月| 热re99久久精品国产99热| 国产69精品久久久久APP下载| 国产日产久久高清欧美一区| 中文字幕无码av激情不卡久久| 青青草原综合久久| 久久天堂AV综合合色蜜桃网| 久久精品中文字幕大胸| 国产精品成人无码久久久久久| 日本强好片久久久久久AAA| 国产精品欧美久久久久无广告 | 狠狠色噜噜狠狠狠狠狠色综合久久| 久久综合九色欧美综合狠狠| 久久亚洲国产欧洲精品一| 麻豆成人久久精品二区三区免费 | 国产亚洲精久久久久久无码AV| 久久久久亚洲精品无码蜜桃 | 久久电影网| 99久久精品九九亚洲精品| 97久久精品无码一区二区| 亚洲成色WWW久久网站| 国产精品乱码久久久久久软件| 久久精品国产亚洲7777| 青青青国产精品国产精品久久久久| 无码日韩人妻精品久久蜜桃| 99久久国产精品免费一区二区| 亚洲午夜无码AV毛片久久| 亚洲国产精品无码久久九九| 久久天天躁狠狠躁夜夜躁2014| 久久久午夜精品| 久久精品一本到99热免费|