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

               C++ 技術中心

               :: 首頁 :: 聯(lián)系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

            鄭重聲明:本BLOG所發(fā)表的原創(chuàng)文章,作者保留一切權利。必須經(jīng)過作者本人同意后方可轉載,并注名作者(天空)和出處(CppBlog.com)。作者Email:coder@luckcoder.com

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評論

            評論排行榜

            一. 優(yōu)先級控制
            在研究LogLevelManager之前,首先介紹一下log4cplus中l(wèi)ogger的存儲機制,在log4cplus中,
            所有l(wèi)ogger都通過一個層次化的結構(其實內部是hash表)來組織的,有一個Root級別的logger,
            可以通過以下方法獲取:
            Logger root = Logger::getRoot();

            用戶定義的logger都有一個名字與之對應,比如:
            Logger test = Logger::getInstance("test");

            可以定義該logger的子logger:
            Logger subTest = Logger::getInstance("test.subtest");   

            注意:Root級別的logger只有通過getRoot方法獲取,Logger::getInstance("root")獲得的是它的子對象而已。

            有了這些具有父子關系的logger之后可分別設置其LogLevel比如:
            root.setLogLevel( ... );
            test.setLogLevel( ... );
            subTest.setLogLevel( ... );


            logger的這種父子關聯(lián)性會體現(xiàn)在優(yōu)先級控制方面,log4cplus將輸出的log信息按照LogLevel(從低到高)分為:
            NOT_SET_LOG_LEVEL (   -1)   :接受缺省的LogLevel,如果有父logger則繼承它的LogLevel
            ALL_LOG_LEVEL           (    0)    :開放所有l(wèi)og信息輸出
            TRACE_LOG_LEVEL     (    0)    :開放trace信息輸出(即ALL_LOG_LEVEL)
            DEBUG_LOG_LEVEL    (10000) :開放debug信息輸出
            INFO_LOG_LEVEL        (20000) :開放info信息輸出
            WARN_LOG_LEVEL     (30000) :開放warning信息輸出
            ERROR_LOG_LEVEL    (40000) :開放error信息輸出
            FATAL_LOG_LEVEL    (50000)  :開放fatal信息輸出
            OFF_LOG_LEVEL        (60000)  :關閉所有l(wèi)og信息輸出

            LogLevelManager負責設置logger的優(yōu)先級,各個logger可以通過setLogLevel設置自己的優(yōu)先級,
            當某個logger的LogLevel設置成NOT_SET_LOG_LEVEL時,該logger會繼承父logger的優(yōu)先級,另外,
            如果定義了重名的多個logger, 對其中任何一個的修改都會同時改變其它logger,我們舉例說明:

            /*    
            設置日志等級
            */

            #include 
            "stdafx.h"
            #pragma comment(lib,
            "../bin/log4cplusD.lib")



            #include 
            <log4cplus/logger.h>
            #include 
            <log4cplus/fileappender.h>
            #include 
            <log4cplus/consoleappender.h>
            #include 
            <conio.h>
            #include 
            <iostream>

            using namespace std;
            using namespace log4cplus;
            int _tmain(int argc, _TCHAR* argv[]){   

            SharedAppenderPtr _append(
            new ConsoleAppender());   
            _append
            ->setName(LOG4CPLUS_TEXT("test"));   

            //新建test logger以及test的子subtest logger
            Logger::getRoot().addAppender(_append);
            Logger root 
            = Logger::getRoot();
            Logger test 
            = Logger::getInstance(LOG4CPLUS_TEXT("test"));    
            Logger subTest 
            = Logger::getInstance(LOG4CPLUS_TEXT("test.subtest"));    
            LogLevelManager
            & llm = getLogLevelManager();

            //設置優(yōu)先級之前
            //默認都是debug級別
            cout << endl << "Before Setting, Default LogLevel" << endl;    
            LOG4CPLUS_FATAL(root, 
            "root: " << llm.toString(root.getChainedLogLevel()));   
            LOG4CPLUS_FATAL(root, 
            "test: " << llm.toString(test.getChainedLogLevel()));    
            LOG4CPLUS_FATAL(root, 
            "test.subtest: " << llm.toString(subTest.getChainedLogLevel()));    


            //subTest被設置警告優(yōu)先級
            cout << endl << "Setting test.subtest to WARN" << endl;   
            subTest.setLogLevel(WARN_LOG_LEVEL);    
            LOG4CPLUS_FATAL(root, 
            "root: " << llm.toString(root.getChainedLogLevel()));   
            LOG4CPLUS_FATAL(root, 
            "test: " << llm.toString(test.getChainedLogLevel()));    
            LOG4CPLUS_FATAL(root, 
            "test.subtest: " << llm.toString(subTest.getChainedLogLevel()));    

            //設置TRACE
            cout << endl << "Setting test.subtest to TRACE" << endl;    
            test.setLogLevel(TRACE_LOG_LEVEL);    
            LOG4CPLUS_FATAL(root, 
            "root: " << llm.toString(root.getChainedLogLevel()));    
            LOG4CPLUS_FATAL(root, 
            "test: " << llm.toString(test.getChainedLogLevel()));    
            LOG4CPLUS_FATAL(root, 
            "test.subtest: " << llm.toString(subTest.getChainedLogLevel()));    
            cout 
            << endl << "Setting test.subtest to NO_LEVEL" << endl;    

            //NOT_SET_LOG_LEVEL
            subTest.setLogLevel(NOT_SET_LOG_LEVEL);    
            LOG4CPLUS_FATAL(root, 
            "root: " << llm.toString(root.getChainedLogLevel()));    
            LOG4CPLUS_FATAL(root, 
            "test: " << llm.toString(test.getChainedLogLevel()));    
            LOG4CPLUS_FATAL(root, 
            "test.subtest: " << llm.toString(subTest.getChainedLogLevel()) << '\n') ;   

            //重新獲取test實例
            cout << "create a logger test_bak, named \"test_\", too. " << endl;    
            Logger test_bak 
            = Logger::getInstance(LOG4CPLUS_TEXT("test"));    


            //設置等級INFO_LOG_LEVEL
            cout << "Setting test to INFO, so test_bak also be set to INFO" << endl;    
            test.setLogLevel(INFO_LOG_LEVEL);    
            LOG4CPLUS_FATAL(root, 
            "test: " << llm.toString(test.getChainedLogLevel()));    
            LOG4CPLUS_FATAL(root, 
            "test_bak: " << llm.toString(test_bak.getChainedLogLevel()));   

            _getch();

            return 0;
            }



            /*    
            設置日志等級,輸出對應等級的日志
            */

            #include 
            "stdafx.h"
            #pragma comment(lib,
            "../bin/log4cplusD.lib")

            #include 
            <log4cplus/logger.h>
            #include 
            <log4cplus/fileappender.h>
            #include 
            <log4cplus/consoleappender.h>
            #include 
            <conio.h>
            #include 
            <iostream>

            using namespace std;
            using namespace log4cplus;

            void ShowMsg(void)
            {   
                LOG4CPLUS_TRACE(Logger::getRoot(),
            "info");
                LOG4CPLUS_DEBUG(Logger::getRoot(),
            "info");
                LOG4CPLUS_INFO(Logger::getRoot(),
            "info");
                LOG4CPLUS_WARN(Logger::getRoot(),
            "info");
                LOG4CPLUS_ERROR(Logger::getRoot(),
            "info");
                LOG4CPLUS_FATAL(Logger::getRoot(),
            "info");
            }



            int _tmain(int argc, _TCHAR* argv[]){   

               SharedAppenderPtr _append(
            new ConsoleAppender());
               _append
            ->setName(LOG4CPLUS_TEXT("test"));   
               
            //std::auto_ptr<Layout> _layout(new TTCCLayout());
               
            //_append->setLayout(_layout);
               _append->setLayout(std::auto_ptr<TTCCLayout>(new TTCCLayout()));
               Logger root 
            = Logger::getRoot();
               root.addAppender(_append);    
               
               
            //無等級,顯示所有的日志
               cout << endl << "all-log allowed" << endl;    
               root.setLogLevel(ALL_LOG_LEVEL);    
               ShowMsg();    
               
               
            //顯示>=TRACE等級日志
               cout << endl << "trace-log and above allowed" << endl;    
               root.setLogLevel(TRACE_LOG_LEVEL);    
               ShowMsg();    
               
               
            //顯示>=DEBUG等級日志
               cout << endl << "debug-log and above allowed" << endl;    
               root.setLogLevel(DEBUG_LOG_LEVEL);    
               ShowMsg();    
               
               
            //顯示>=INFO等級日志
               cout << endl << "info-log and above allowed" << endl;    
               root.setLogLevel(INFO_LOG_LEVEL);    
               ShowMsg();    
               
               
            //顯示>=WARN等級日志
               cout << endl << "warn-log and above allowed" << endl;    
               root.setLogLevel(WARN_LOG_LEVEL);    
               ShowMsg();    

               
            //顯示>=ERROR等級日志
               cout << endl << "error-log and above allowed" << endl;    
               root.setLogLevel(ERROR_LOG_LEVEL);    
               ShowMsg();    

               
            //顯示>=FATAL等級日志
               cout << endl << "fatal-log and above allowed" << endl;    
               root.setLogLevel(FATAL_LOG_LEVEL);    
               ShowMsg();    
               
               
            //關閉所有日志輸出
               cout << endl << "log disabled" << endl;    
               root.setLogLevel(OFF_LOG_LEVEL);    
               ShowMsg();    
             
                _getch();

                
            return 0;
            }


            用戶也可以自行定義LogLevel,操作比較簡單,首先要定義LEVEL值,比如HELLO_LOG_LEVEL定義如下:
            //DEBUG_LOG_LEVEL  < HELLO_LOG_LEVEL < INFO_LOG_LEVEL

            const LogLevel HELLO_LOG_LEVEL = 15000;
            然后定義以下宏即可:

            // define MACRO LOG4CPLUS_HELLO
            #define LOG4CPLUS_HELLO(logger, logEvent) \    
            if(logger.isEnabledFor(HELLO_LOG_LEVEL)) { \        
            log4cplus::tostringstream _log4cplus_buf; \        
            _log4cplus_buf 
            << logEvent; \ 
            logger.forcedLog(HELLO_LOG_LEVEL, _log4cplus_buf.str(), __FILE__, __LINE__); \    
            }


            不過log4cplus沒有提供給用戶一個接口來實現(xiàn)LEVEL值與字符串的轉換,所以當帶格式
            輸出LogLevel字符串時候會顯示"UNKNOWN", 不夠理想。比如用TTCCLayout控制輸出的結果可能會如下所示:
            10-17-04 11:17:51,124 [1075298944] UNKNOWN root <> - info
            而不是期望的以下結果:
            10-17-04 11:17:51,124 [1075298944] HELLO root <> - info

            要想實現(xiàn)第二種結果,按照log4cplus現(xiàn)有的接口機制,只能改其源代碼后重新編譯,方法是在loglevel.cxx中加入:
            #define _HELLO_STRING LOG4CPLUS_TEXT("HELLO")
            然后修改log4cplus::tstring  defaultLogLevelToStringMethod(LogLevel ll)函數(shù),增加一個判斷:
            case HELLO_LOG_LEVEL:   
              return _HELLO_STRING;

            重新編譯log4cplus源代碼后生成庫文件,再使用時即可實現(xiàn)滿意效果。

            二. 基于腳本配置來過濾log信息
            除了通過程序實現(xiàn)對log環(huán)境的配置之外,log4cplus通過PropertyConfigurator類實現(xiàn)了基于腳本配置的功能。
            通過腳本可以完成對logger、appender和layout的配置,因此可以解決怎樣輸出,輸出到哪里的問題,我將在
            全文的最后一部分中提到多線程環(huán)境中如何利用腳本配置來配合實現(xiàn)性能測試,本節(jié)將重點介紹基腳本實現(xiàn)過
            濾log信息的功能。

            首先簡單介紹一下腳本的語法規(guī)則:
            包括Appender的配置語法和logger的配置語法,其中:
            1.Appender的配置語法:
              (1)設置名稱:
                 //設置方法
                 log4cplus.appender.appenderName=fully.qualified.name.of.appender.class
             
                例如(列舉了所有可能的Appender,其中SocketAppender后面會講到):
                log4cplus.appender.append_1=log4cplus::ConsoleAppender
                log4cplus.appender.append_2=log4cplus::FileAppender
                log4cplus.appender.append_3=log4cplus::RollingFileAppender
                log4cplus.appender.append_4=log4cplus::DailyRollingFileAppender
                log4cplus.appender.append_4=log4cplus::SocketAppender
             
              (2)設置Filter:
                包括選擇過濾器和設置過濾條件,可選擇的過濾器包括:LogLevelMatchFilter、LogLevelRangeFilter、和StringMatchFilter:
               
                對LogLevelMatchFilter來說,過濾條件包括LogLevelToMatch和AcceptOnMatch(true|false),
                只有當log信息的LogLevel值與LogLevelToMatch相同,且AcceptOnMatch為true時才會匹配。
               
                LogLevelRangeFilter來說,過濾條件包括LogLevelMin、LogLevelMax和AcceptOnMatch,
                只有當log信息的LogLevel在LogLevelMin、LogLevelMax之間同時AcceptOnMatch為true時才會匹配。
               
                對StringMatchFilter來說,過濾條件包括StringToMatch和AcceptOnMatch,只有當log信息的LogLevel值
                與StringToMatch對應的LogLevel值與相同, 且AcceptOnMatch為true時會匹配。
               
                過濾條件處理機制類似于IPTABLE的Responsibility chain,(即先deny、再allow)不過執(zhí)行順序剛好相反,
                后寫的條件會被先執(zhí)行,比如:
                log4cplus.appender.append_1.filters.1=log4cplus::spi::LogLevelMatchFilter
                log4cplus.appender.append_1.filters.1.LogLevelToMatch=TRACE
                log4cplus.appender.append_1.filters.1.AcceptOnMatch=true
                #log4cplus.appender.append_1.filters.2=log4cplus::spi::DenyAllFilter
               
               
                會首先執(zhí)行filters.2的過濾條件,關閉所有過濾器,然后執(zhí)行filters.1,僅匹配TRACE信息。
                
                (3) 設置Layout可以選擇不設置、TTCCLayout、或PatternLayout如果不設置,
                會輸出簡單格式的log信息。設置TTCCLayout如下所示:
                log4cplus.appender.ALL_MSGS.layout=log4cplus::TTCCLayout
               
                設置PatternLayout如下所示:
                log4cplus.appender.append_1.layout=log4cplus::PatternLayout
                log4cplus.appender.append_1.layout.ConversionPattern=%d{%m/%d/%y %H:%M:%S,%Q} [%t] %-5p - %m%n
               
            2.logger的配置語法
                包括rootLogger和non-root logger。
                對于rootLogger來說:log4cplus.rootLogger=[LogLevel], appenderName, appenderName, ...
                對于non-root logger來說:log4cplus.logger.logger_name=[LogLevel|INHERITED], appenderName, appenderName, ...

                腳本方式使用起來非常簡單,只要首先加載配置即可(urconfig.properties是自行定義的配置文件):
                PropertyConfigurator::doConfigure("urconfig.properties");


                補充說明:log4cplus.additivity.logger_name表示表示是否繼承父類的配置

            3. 示例:
            配置文件如下:

            log4cplus.rootLogger=TRACE, ALL_MSGS, TRACE_MSGS, DEBUG_INFO_MSGS, FATAL_MSGS

            #trace_msgs將可以通過Logger::getInstance(LOG4CPLUS_TEXT("trace_msgs"))獲取
            log4cplus.logger.trace_msgs      = TRACE,TRACE_MSGS
            log4cplus.logger.debug_info_msgs = TRACE,DEBUG_INFO_MSGS
            log4cplus.logger.fatal_msgs      = TRACE,FATAL_MSGS

            log4cplus.appender.ALL_MSGS=log4cplus::RollingFileAppender
            log4cplus.appender.ALL_MSGS.File=all_msgs.log
            log4cplus.appender.ALL_MSGS.layout=log4cplus::TTCCLayout

            log4cplus.appender.TRACE_MSGS=log4cplus::RollingFileAppender
            log4cplus.appender.TRACE_MSGS.File=trace_msgs.log
            log4cplus.appender.TRACE_MSGS.layout=log4cplus::TTCCLayout
            log4cplus.appender.TRACE_MSGS.filters.1=log4cplus::spi::LogLevelMatchFilter
            log4cplus.appender.TRACE_MSGS.filters.1.LogLevelToMatch=TRACE
            log4cplus.appender.TRACE_MSGS.filters.1.AcceptOnMatch=true
            log4cplus.appender.TRACE_MSGS.filters.2=log4cplus::spi::DenyAllFilter

            log4cplus.appender.DEBUG_INFO_MSGS=log4cplus::RollingFileAppender
            log4cplus.appender.DEBUG_INFO_MSGS.File=debug_info_msgs.log
            log4cplus.appender.DEBUG_INFO_MSGS.layout=log4cplus::TTCCLayout
            log4cplus.appender.DEBUG_INFO_MSGS.filters.1=log4cplus::spi::LogLevelRangeFilter
            log4cplus.appender.DEBUG_INFO_MSGS.filters.1.LogLevelMin=DEBUG
            log4cplus.appender.DEBUG_INFO_MSGS.filters.1.LogLevelMax=INFO
            log4cplus.appender.DEBUG_INFO_MSGS.filters.1.AcceptOnMatch=true
            log4cplus.appender.DEBUG_INFO_MSGS.filters.2=log4cplus::spi::DenyAllFilter

            log4cplus.appender.FATAL_MSGS=log4cplus::RollingFileAppender
            log4cplus.appender.FATAL_MSGS.File=fatal_msgs.log
            log4cplus.appender.FATAL_MSGS.layout=log4cplus::TTCCLayout
            log4cplus.appender.FATAL_MSGS.filters.1=log4cplus::spi::StringMatchFilter
            log4cplus.appender.FATAL_MSGS.filters.1.StringToMatch=FATAL
            log4cplus.appender.FATAL_MSGS.filters.1.AcceptOnMatch=true
            log4cplus.appender.FATAL_MSGS.filters.2=log4cplus::spi::DenyAllFilter

            代碼示例如下:

            /*    
            設置日志等級,輸出對應等級的日志
            */

            #include 
            "stdafx.h"
            #pragma comment(lib,
            "../bin/log4cplusD.lib")

            #include 
            <log4cplus/logger.h>
            #include 
            <log4cplus/fileappender.h>
            #include 
            <log4cplus/consoleappender.h>
            #include 
            <conio.h>
            #include 
            <iostream>
            #include 
            <log4cplus/configurator.h>

            using namespace std;
            using namespace log4cplus;

            static Logger logger1 = Logger::getInstance(LOG4CPLUS_TEXT("TRACE_MSGS"));
            static Logger logger2 = Logger::getInstance(LOG4CPLUS_TEXT("log"));

            void printDebug(){    
            /*    LOG4CPLUS_TRACE(logger, "::printDebug()");    
                LOG4CPLUS_DEBUG(logger, "This is a DEBUG message");    
                LOG4CPLUS_INFO(logger, "This is a INFO message");    
                LOG4CPLUS_WARN(logger, "This is a WARN message");   
                LOG4CPLUS_ERROR(logger, "This is a ERROR message");    
                LOG4CPLUS_FATAL(logger, "This is a FATAL message");
                
            */


                LOG4CPLUS_TRACE(logger1, 
            "::printDebug()"); 

            }


            int _tmain(int argc, _TCHAR* argv[]){   


                
            //    
                PropertyConfigurator::doConfigure(LOG4CPLUS_TEXT("urconfig.properties"));    
                

                
            //入root的logger寫入記錄
                Logger root = Logger::getRoot();
                LOG4CPLUS_FATAL(root,
            "向all_msgs.log文件中寫入信息,因為向root,自動往所有的字文件寫入!");
                
                
            //只向log4cplus.logger.trace_msgs      = TRACE,TRACE_MSGS對應的
                
            //log4cplus.appender.TRACE_MSGS文件寫入日志
                Logger logger1 = Logger::getInstance(LOG4CPLUS_TEXT("TRACE_MSGS"));
                LOG4CPLUS_TRACE(logger1,
            "只向all_msgs.log或trace_msgs.log文件寫入日志!");

                
            return 0;
            }

             
            結果如下:
            all_msgs.log:
            10 [5840] FATAL root <> - 向所有的文件中寫入信息,因為向root,自動往所有的字文件寫入!
            10 [5840] TRACE TRACE_MSGS <> - 只向trace_msgs.log文件寫入日志!


            trace_msgs.log:
            10 [5840] TRACE TRACE_MSGS <> - 只向trace_msgs.log文件寫入日志!

            其他文件為空

            posted on 2011-04-02 16:00 C++技術中心 閱讀(9545) 評論(0)  編輯 收藏 引用 所屬分類: 三方庫
            少妇高潮惨叫久久久久久| 日韩电影久久久被窝网| 7777精品伊人久久久大香线蕉| avtt天堂网久久精品| 亚洲国产精品无码久久| 久久精品一区二区三区AV| 免费久久人人爽人人爽av| 久久精品无码一区二区WWW| 精品久久久久久久国产潘金莲| 亚洲七七久久精品中文国产| 99久久国产亚洲综合精品| 久久国产欧美日韩精品免费| 97视频久久久| 久久久久女人精品毛片| 狠狠色婷婷综合天天久久丁香| 亚洲欧美精品伊人久久| 国产精品欧美久久久久天天影视| 办公室久久精品| 久久久精品国产| 97r久久精品国产99国产精| 成人精品一区二区久久| 久久综合久久鬼色| 亚洲国产精品18久久久久久| 91久久精一区二区三区大全| 久久精品国产精品亚洲人人| 亚洲一区精品伊人久久伊人| 91精品国产乱码久久久久久| 久久毛片免费看一区二区三区| 久久久无码精品亚洲日韩蜜臀浪潮| 日韩乱码人妻无码中文字幕久久| 国产精品一区二区久久精品| 久久乐国产精品亚洲综合| 精品国产乱码久久久久软件| 91精品婷婷国产综合久久 | 久久狠狠一本精品综合网| 伊人久久五月天| 久久91精品国产91久久户| 久久精品国产亚洲Aⅴ蜜臀色欲| 欧美伊人久久大香线蕉综合| 51久久夜色精品国产| 久久国产色AV免费看|