2016-04-30 2 views
1

Мое приложение имеет несколько компонентов, и я хочу, чтобы каждый компонент записывал журналы в отдельный файл.Boost Log несколько файлов с вращением

Я хотел использовать «текстовый файл с несколькими файлами», но в соответствии с документацией он не поддерживает поворот файла.

Итак, моя идея состояла в том, чтобы внедрить класс журнала и мгновенно получить для каждого из компонентов и сохранить их на карте, таким образом, я могу использовать карту для получения правильного экземпляра журнала (в соответствии с именем) и журнала в правильный файл.

Я сделал это, но это не работает для меня, я вижу одни и те же сообщения во всех файлах (кажется, что это глобальный регистратор).

Это проект моего кода:

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

Это именно то, что мне нужно, спасибо. –

Смежные вопросы