2016-04-30 71 views
1

我的應用程序有幾個組件,我希望每個組件都將日誌寫入單獨的文件。Boost記錄多個旋轉的文件

我想使用「文本多文件後端」,但根據文檔,它不支持文件旋轉。

所以我的想法是實現一個日誌類,並立即爲每個組件和存儲他們在地圖中,這樣我可以使用地圖來獲取正確的記錄器實例(根據名稱)和日誌到正確的文件。

我已經做到了這一點,但這不適合我,我可以在所有文件中看到相同的消息(看起來這是一個全局記錄器)。

這是我的代碼草案:

logger.h

struct LogInfo{ 
    std::string log_path; 
    LogLevel log_level; 
    long log_file_size; 
    int log_file_amount; 
}; 

LogLevel stringToLogLevel(const std::string &fileType); 

class Logger { 
public: 
    Logger(const LogInfo &log_info, const std::string &component_name); 
    void writeToLog(LogLevel log_level, const std::string &scope, const std::string &message); 
private: 
    void scanForFiles(const std::string &path, const std::string &component_name); 

    std::string pid; 
    std::string log_file_name; 
    boost::log::sources::severity_logger<boost::log::trivial::severity_level> boost_severity_logger; 
}; 

logger.cpp

using namespace boost::log; 
using namespace std; 
namespace fs = boost::filesystem; 

LogLevel stringToLogLevel(const string &fileType) { 
    if (fileType == "TRACE") 
     return LOGLEVEL_TRACE; 
    if (fileType == "DEBUG") 
     return LOGLEVEL_DEBUG; 
    if (fileType == "INFO") 
     return LOGLEVEL_INFO; 
    if (fileType == "WARNING") 
     return LOGLEVEL_WARNING; 
    if (fileType == "ERROR") 
     return LOGLEVEL_ERROR; 
    throw invalid_argument("Unknown file type"); 
} 

trivial::severity_level logLevelToBoostLogLevel(const LogLevel log_level) { 
    if (log_level == LOGLEVEL_TRACE) 
     return trivial::trace; 
    if (log_level == LOGLEVEL_DEBUG) 
     return trivial::debug; 
    if (log_level == LOGLEVEL_INFO) 
     return trivial::info; 
    if (log_level == LOGLEVEL_WARNING) 
     return trivial::warning; 
    if (log_level == LOGLEVEL_ERROR) 
     return trivial::error; 
    throw invalid_argument("Unknown log type"); 
} 

Logger::Logger(const LogInfo &log_info, const string &component_name) { 
    scanForFiles(log_info.log_path, component_name); 
    stringstream s; 
    s << log_info.log_path << component_name << "_%N.log"; 
    add_file_log(
     keywords::file_name = s.str(), 
     keywords::rotation_size = log_info.log_file_size, 
     keywords::max_size = log_info.log_file_amount * log_info.log_file_size, 
     keywords::target = log_info.log_path, 
     keywords::open_mode = std::ios::out | std::ios::app, 
     keywords::auto_flush = true, 
     keywords::format = 
     expressions::format("[%1%] [%2%] [%3%] [%4%] %5%") 
     % expressions::format_date_time<boost::posix_time::ptime>("TimeStamp", "%Y-%m-%d %H:%M:%S.%f") 
     % expressions::attr<unsigned int>("ThreadID") 
     % expressions::attr<string>("Scope") 
     % trivial::severity 
     % expressions::smessage 
    ); 

    trivial::severity_level requested_level = logLevelToBoostLogLevel(log_info.log_level); 
    core::get()->set_filter(
     trivial::severity >= requested_level 
    ); 
    add_common_attributes(); 
} 

void Logger::writeToLog(LogLevel log_level, const std::string &scope, const std::string &message) { 
    BOOST_LOG_SCOPED_THREAD_ATTR("ThreadID", attributes::constant<unsigned int>(OS::getTid())); 
    BOOST_LOG_SCOPED_THREAD_ATTR("Scope", attributes::constant<string>(scope)); 
    BOOST_LOG_SEV(this->boost_severity_logger, logLevelToBoostLogLevel(log_level))<< message.c_str(); 
} 

是否有可能實現我想要什麼?

回答

1

請參閱this的回覆。除此之外,它還介紹瞭如何使用通道和過濾器來實現您想要的功能。

+0

這正是我所需要的,謝謝。 –