// Copyright (C) 2007 Davis E. King (davis@dlib.net) // License: Boost Software License See LICENSE.txt for the full license. #ifndef DLIB_LOGGER_CONFIg_FILE_CPP #define DLIB_LOGGER_CONFIg_FILE_CPP #include "logger_config_file.h" #include <string> #include "../config_reader.h" #include <fstream> #include <sstream> #include "../error.h" #include "../map.h" #include "../string.h" // ---------------------------------------------------------------------------------------- namespace dlib { namespace logger_config_file_helpers { // ---------------------------------------------------------------------------------------- std::ostream& get_file_stream ( const std::string& file_name ) { using namespace std; static dlib::mutex m; auto_mutex M(m); static dlib::map<string,ostream*>::kernel_1a_c file_map; if (file_map.is_in_domain(file_name) == false) { // We won't ever delete this output stream. It should be around for the // entire life of the program so just let the OS take care of it. ostream* fout = new ofstream(file_name.c_str()); if (!(*fout)) { delete fout; throw error("logger_config: unable to open output file " + file_name); } // add this file to our file map string temp(file_name); file_map.add(temp,fout); } return *file_map[file_name]; } // ---------------------------------------------------------------------------------------- log_level string_to_log_level ( const std::string& level ) { using namespace std; if (level == "LALL" || level == "ALL" || level == "all") return LALL; else if (level == "LNONE" || level == "NONE" || level == "none") return LNONE; else if (level == "LTRACE" || level == "TRACE" || level == "trace") return LTRACE; else if (level == "LDEBUG" || level == "DEBUG" || level == "debug") return LDEBUG; else if (level == "LINFO" || level == "INFO" || level == "info") return LINFO; else if (level == "LWARN" || level == "WARN" || level == "warn") return LWARN; else if (level == "LERROR" || level == "ERROR" || level == "error") return LERROR; else if (level == "LFATAL" || level == "FATAL" || level == "fatal") return LFATAL; else { const int priority = string_cast<int>(level); return log_level(priority,"CONFIG_FILE_DEFINED"); } } // ---------------------------------------------------------------------------------------- void configure_sub_blocks ( const config_reader& cr, const std::string& name ) { using namespace std; logger dlog(name.c_str()); if (cr.is_key_defined("logging_level")) { dlog.set_level(string_to_log_level(cr["logging_level"])); } if (cr.is_key_defined("output")) { string output = cr["output"]; if (output == "cout") dlog.set_output_stream(cout); else if (output == "cerr") dlog.set_output_stream(cerr); else if (output == "clog") dlog.set_output_stream(clog); else { istringstream sin(output); string one, two, three; sin >> one; sin >> two; sin >> three; if (one == "file" && three.size() == 0) dlog.set_output_stream(get_file_stream(two)); else throw error("logger_config: invalid argument to output option: " + output); } } // if (cr.is_key_defined("output")) // now configure all the sub-blocks std_vector_c<std::string> blocks; cr.get_blocks(blocks); for (unsigned long i = 0; i < blocks.size(); ++i) { configure_sub_blocks(cr.block(blocks[i]), name + "." + blocks[i]); } } // ---------------------------------------------------------------------------------------- } // namespace // ---------------------------------------------------------------------------------------- void configure_loggers_from_file ( const std::string& file_name ) { std::ifstream fin(file_name.c_str()); if (!fin) throw logger_config_file_error("logger_config: unable to open config file " + file_name); config_reader temp(fin); configure_loggers_from_file(temp); } // ---------------------------------------------------------------------------------------- void configure_loggers_from_file ( const config_reader& main_cr ) { using namespace logger_config_file_helpers; using namespace std; if (main_cr.is_block_defined("logger_config")) { const config_reader& cr = main_cr.block("logger_config"); if (cr.is_key_defined("logging_level")) { set_all_logging_levels(string_to_log_level(cr["logging_level"])); } if (cr.is_key_defined("output")) { string output = cr["output"]; if (output == "cout") set_all_logging_output_streams(cout); else if (output == "cerr") set_all_logging_output_streams(cerr); else if (output == "clog") set_all_logging_output_streams(clog); else { istringstream sin(output); string one, two, three; sin >> one; sin >> two; sin >> three; if (one == "file" && three.size() == 0) set_all_logging_output_streams(get_file_stream(two)); else throw logger_config_file_error("logger_config: invalid argument to output option: " + output); } } // if (cr.is_key_defined("output")) // now configure all the sub-blocks std_vector_c<std::string> blocks; cr.get_blocks(blocks); for (unsigned long i = 0; i < blocks.size(); ++i) { configure_sub_blocks(cr.block(blocks[i]), blocks[i]); } } } // ---------------------------------------------------------------------------------------- } // ---------------------------------------------------------------------------------------- #endif // DLIB_LOGGER_CONFIg_FILE_CPP