• <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++ 技術中心

               :: 首頁 :: 聯系 ::  :: 管理
              160 Posts :: 0 Stories :: 87 Comments :: 0 Trackbacks

            公告

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

            留言簿(27)

            搜索

            •  

            最新隨筆

            最新評論

            評論排行榜

            一. 優先級控制
            在研究LogLevelManager之前,首先介紹一下log4cplus中logger的存儲機制,在log4cplus中,
            所有logger都通過一個層次化的結構(其實內部是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的這種父子關聯性會體現在優先級控制方面,log4cplus將輸出的log信息按照LogLevel(從低到高)分為:
            NOT_SET_LOG_LEVEL (   -1)   :接受缺省的LogLevel,如果有父logger則繼承它的LogLevel
            ALL_LOG_LEVEL           (    0)    :開放所有log信息輸出
            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)  :關閉所有log信息輸出

            LogLevelManager負責設置logger的優先級,各個logger可以通過setLogLevel設置自己的優先級,
            當某個logger的LogLevel設置成NOT_SET_LOG_LEVEL時,該logger會繼承父logger的優先級,另外,
            如果定義了重名的多個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();

            //設置優先級之前
            //默認都是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被設置警告優先級
            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沒有提供給用戶一個接口來實現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

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

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

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

            首先簡單介紹一下腳本的語法規則:
            包括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)不過執行順序剛好相反,
                后寫的條件會被先執行,比如:
                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
               
               
                會首先執行filters.2的過濾條件,關閉所有過濾器,然后執行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)  編輯 收藏 引用 所屬分類: 三方庫
            国内精品久久久久久久久电影网| 久久精品无码一区二区WWW| A级毛片无码久久精品免费| 午夜肉伦伦影院久久精品免费看国产一区二区三区 | 国产AV影片久久久久久| 久久精品国产清自在天天线| 久久国语露脸国产精品电影| 91麻豆精品国产91久久久久久| 97视频久久久| 久久国产影院| 久久久久久九九99精品| 无码乱码观看精品久久| 精品久久久久久亚洲| 伊人久久精品无码av一区| 久久国产精品偷99| 国产成人精品白浆久久69| 久久天天躁狠狠躁夜夜2020一| 久久国产成人精品麻豆| 亚洲国产精品无码久久一线| 亚洲美日韩Av中文字幕无码久久久妻妇| 国产亚洲美女精品久久久久狼| 久久久久av无码免费网| 久久夜色精品国产www| 亚洲国产精品久久久久久| 国产精品9999久久久久| 亚洲va国产va天堂va久久| 香蕉久久夜色精品国产尤物| 久久久久国产视频电影| 9999国产精品欧美久久久久久| 久久99精品国产麻豆| 午夜欧美精品久久久久久久| 久久国产欧美日韩精品| 人妻无码αv中文字幕久久琪琪布| 久久久久久久国产免费看| 精品视频久久久久| 久久国产精品国语对白| 久久精品亚洲精品国产欧美| 久久99国产一区二区三区| 久久性精品| 精品国产日韩久久亚洲| 久久精品人妻中文系列|