• <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 楊粼波 閱讀(5399) 評論(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  回復  更多評論   

            99久久综合国产精品免费| 国产L精品国产亚洲区久久| 欧美黑人激情性久久| 久久精品99无色码中文字幕| 国产精品乱码久久久久久软件| 亚洲中文字幕久久精品无码喷水| 久久99国内精品自在现线| 国产香蕉97碰碰久久人人| 国内精品久久久久影院老司| 97久久精品无码一区二区天美| 伊人久久大香线焦综合四虎 | 18岁日韩内射颜射午夜久久成人| 一本色道久久HEZYO无码| 国产成人99久久亚洲综合精品| 亚洲国产成人久久笫一页| 色欲久久久天天天综合网| 97超级碰碰碰碰久久久久| 囯产精品久久久久久久久蜜桃| 亚洲伊人久久大香线蕉苏妲己| 精品国产乱码久久久久软件| 久久99国产一区二区三区| 欧美一区二区三区久久综| 欧美亚洲国产精品久久久久| 日本久久久精品中文字幕| 2022年国产精品久久久久| 久久精品国产2020| 亚洲AV伊人久久青青草原| 九九久久精品国产| 四虎国产永久免费久久| 国产精品女同久久久久电影院| 国产aⅴ激情无码久久| 精品国产乱码久久久久久人妻 | 91久久精品电影| 色婷婷综合久久久久中文| 久久午夜夜伦鲁鲁片免费无码影视| 国内精品久久久久久久亚洲 | 精品人妻伦九区久久AAA片69| 国内精品久久国产大陆| jizzjizz国产精品久久| 996久久国产精品线观看| 久久99国产精品久久99果冻传媒|