diff --git a/src/libs/logging/ascent_logging.cpp b/src/libs/logging/ascent_logging.cpp index d16cf1613..ac4f2d82c 100644 --- a/src/libs/logging/ascent_logging.cpp +++ b/src/libs/logging/ascent_logging.cpp @@ -31,41 +31,32 @@ using namespace conduit; namespace ascent { +//----------------------------------------------------------------------------- +// main logger instance +//----------------------------------------------------------------------------- Logger Logger::m_instance; -Logger *Logger::m_active_instance = nullptr; -std::vector Logger::m_level_strings = {"unset", - "debug", - "info", - "warn", - "error", - "legendary"}; //----------------------------------------------------------------------------- -Logger::Scope::Scope(Logger *lgr, const std::string &name) +Logger::Scope::Scope(Logger &lgr, const std::string &name) : m_lgr(lgr), m_name(name) { - if(m_lgr != nullptr) - { - m_lgr->log_block_begin(m_name); - } + m_lgr.log_block_begin(m_name); } //----------------------------------------------------------------------------- Logger::Scope::~Scope() { - if(m_lgr != nullptr) - { - m_lgr->log_block_end(m_name); - } + m_lgr.log_block_end(m_name); } //----------------------------------------------------------------------------- Logger::Logger() - : m_indent_level(0), + : m_log_open(false), + m_indent_level(0), m_rank(-1), - m_level_threshold(INFO), - m_echo_level_threshold(LEGENDARY) + m_log_threshold(Logger::INFO), + m_echo_threshold(Logger::NONE) { m_key_counters.push(std::map()); } @@ -76,72 +67,111 @@ Logger::~Logger() close(); } +//----------------------------------------------------------------------------- +void +Logger::reset() +{ + m_indent_level = 0; + m_log_threshold = Logger::INFO; + m_echo_threshold = Logger::NONE; + // reset our stacks + m_timers = std::stack(); + m_key_counters = std::stack>(); + m_key_counters.push(std::map()); +} + //----------------------------------------------------------------------------- void Logger::open(const std::string &ofpattern) { + if(is_log_open()) + { + std::string emsg = conduit_fmt::format("[FATAL_ERROR] failed to open log with pattern: {}, logger already has {} open.", + ofpattern, m_log_fname); + throw conduit::Error(emsg, + __FILE__, + __LINE__); + } + // multi node case, assumes file pattern includes "rank" - std::string ofname; if(rank() > -1) { - ofname = conduit_fmt::format(ofpattern, - conduit_fmt::arg("rank",rank())); + m_log_fname = conduit_fmt::format(ofpattern, + conduit_fmt::arg("rank",rank())); } else { - ofname = ofpattern; + m_log_fname = ofpattern; } - m_ofstream.open(ofname.c_str()); + // open append (consequtive ascent open use cases) + m_log_stream.open(m_log_fname.c_str(),std::ios_base::app); - if(!m_ofstream.is_open()) + if(!m_log_stream.is_open()) { - std::cerr << "[ERROR] Failed to open log file: " << ofname << std::endl; + throw conduit::Error(conduit_fmt::format("[FATAL_ERROR] Failed to open log file: {} ", m_log_fname), + __FILE__, + __LINE__); } + m_log_open = true; + log_message(Logger::DEBUG,conduit_fmt::format("opened log file: {}", m_log_fname)); } //----------------------------------------------------------------------------- bool -Logger::is_open() +Logger::is_log_open() { - return m_ofstream.is_open(); + return m_log_open; } //----------------------------------------------------------------------------- void Logger::close() { - if(m_ofstream.is_open()) + if(is_log_open()) { - m_ofstream.close(); + log_message(Logger::DEBUG,conduit_fmt::format("closing log file: {}", m_log_fname)); + m_log_stream.close(); + m_log_open = false; + m_log_fname = ""; } + + reset(); } //----------------------------------------------------------------------------- void Logger::flush() { - m_ofstream << std::flush; + if(is_log_open()) + { + log_stream() << std::flush; + } } //----------------------------------------------------------------------------- void Logger::log_block_begin(const std::string &name) { + // skip if log is not open + if(!is_log_open()) + { + return; + } + // make sure we have a unique key name - int key_count = m_key_counters.top()[name]++; - stream() << m_indent_string <<"-\n"; + log_stream() << m_indent_string <<"-\n"; set_indent_level(indent_level()+1); if(key_count == 0) { - stream() << m_indent_string << name << ":\n"; + log_stream() << m_indent_string << name << ":\n"; } else { - stream() << m_indent_string << name << "_" << key_count <<":\n"; + log_stream() << m_indent_string << name << "_" << key_count <<":\n"; } set_indent_level(indent_level()+1); // add timer for new level @@ -154,8 +184,14 @@ Logger::log_block_begin(const std::string &name) void Logger::log_block_end(const std::string &name) { - stream() << m_indent_string <<"-\n"; - stream() << m_indent_string << " time_elapsed: " << m_timers.top().elapsed() << "\n"; + // skip if log is not open + if(!is_log_open()) + { + return; + } + + log_stream() << m_indent_string <<"-\n"; + log_stream() << m_indent_string << " time_elapsed: " << m_timers.top().elapsed() << "\n"; set_indent_level(indent_level()-2); m_key_counters.pop(); m_timers.pop(); @@ -168,17 +204,17 @@ Logger::log_message(int level, const std::string &file, int line) { - // log if equal or above logging threshold - if(level >= log_threshold()) - { - log_message(level, msg, file, line, stream(), true); - } - // echo if equal or above echo threshold if(level >= echo_threshold()) { log_message(level, msg, file, line, std::cout, false); } + + // log if equal or above logging threshold + if(level >= log_threshold()) + { + log_message(level, msg, file, line, log_stream(), true); + } } @@ -214,17 +250,17 @@ void Logger::log_message(int level, const std::string &msg) { - // log if equal or above logging threshold - if(level >= log_threshold()) - { - log_message(level, msg, stream(), true); - } - // echo if equal or above echo threshold if(level >= echo_threshold()) { log_message(level, msg, std::cout, false); } + + // log if equal or above logging threshold + if(level >= log_threshold()) + { + log_message(level, msg, log_stream(), true); + } } //----------------------------------------------------------------------------- @@ -302,71 +338,69 @@ Logger::set_rank(int rank) void Logger::set_log_threshold(int level) { - m_level_threshold = level; + m_log_threshold = level; } //----------------------------------------------------------------------------- int Logger::log_threshold() const { - return m_level_threshold; + return m_log_threshold; } //----------------------------------------------------------------------------- void Logger::set_echo_threshold(int level) { - m_echo_level_threshold = level; + m_echo_threshold = level; } //----------------------------------------------------------------------------- int Logger::echo_threshold() const { - return m_echo_level_threshold; + return m_echo_threshold; } //----------------------------------------------------------------------------- std::ostream & -Logger::stream() +Logger::log_stream() { - return m_ofstream; + return m_log_stream; } //----------------------------------------------------------------------------- -Logger * +Logger & Logger::instance() { - return m_active_instance; -} - -//----------------------------------------------------------------------------- -void -Logger::activate() -{ - m_active_instance = &m_instance; -} - -//----------------------------------------------------------------------------- -void -Logger::deactivate() -{ - m_active_instance = nullptr; + return m_instance; } //----------------------------------------------------------------------------- -const std::string & +std::string Logger::level_string(int level) { - if(level < Logger::UNKNOWN ) + if(level < Logger::ALL ) + { + level = Logger::ALL; + } + else if(level < Logger::DEBUG) + { + level = Logger::DEBUG; + } + else if(level > Logger::ERROR) { - level = Logger::UNKNOWN; + level = Logger::NONE; } - else if(level > Logger::LEGENDARY) + switch(level) { - level = Logger::LEGENDARY; + case Logger::ALL: return "all"; break; + case Logger::DEBUG: return "debug"; break; + case Logger::INFO: return "info"; break; + case Logger::WARN: return "warn"; break; + case Logger::ERROR: return "error"; break; + case Logger::NONE: return "none"; break; } - return m_level_strings[level]; } //----------------------------------------------------------------------------- diff --git a/src/libs/logging/ascent_logging.hpp b/src/libs/logging/ascent_logging.hpp index f4a4c1de8..4ae985427 100644 --- a/src/libs/logging/ascent_logging.hpp +++ b/src/libs/logging/ascent_logging.hpp @@ -21,14 +21,20 @@ #include #include +//----------------------------------------------------------------------------- /* + +Unified Logging Macros used by all libraries.alignas + +macros: + ASCENT_LOG_OPEN( output_file_name_pattern ) // serial ASCENT_LOG_OPEN( output_file_name_pattern, rank ) // mpi par -ASCENT_LOG_DEBUG( msg ) (w/ line, file, etc) -ASCENT_LOG_INFO( msg ) (w/ line, file, etc) -ASCENT_LOG_WARN( msg ) (w/ line, file, etc) -ASCENT_LOG_ERROR( msg ) (w/ line, file, etc) +ASCENT_LOG_DEBUG( msg ) (w/ line, file) +ASCENT_LOG_INFO( msg ) (w/ line, file) +ASCENT_LOG_WARN( msg ) (w/ line, file) +ASCENT_LOG_ERROR( msg ) (w/ line, file) ASCENT_LOG_SCOPE( name ) --> increase indent ASCENT_LOG_MARK_BEGIN( name ) --> increase indent @@ -36,104 +42,82 @@ ASCENT_LOG_MARK_END( name ) --> decrease indent ASCENT_LOG_MARK_FUNCTION () ASCENT_LOG_FLUSH() +ASCENT_LOG_CLOSE() */ +//----------------------------------------------------------------------------- //----------------------------------------------------------------------------- -#define ASCENT_LOG_OPEN( ofname_pattern ) \ -{ \ - ascent::Logger::activate(); \ - ascent::Logger *lgr = ascent::Logger::instance(); \ - lgr->open(ofname_pattern); \ +#define ASCENT_LOG_OPEN( ofname_pattern ) \ +{ \ + ascent::Logger::instance().open(ofname_pattern); \ } //----------------------------------------------------------------------------- -#define ASCENT_LOG_OPEN_RANK( ofname_pattern , rank ) \ -{ \ - ascent::Logger::activate(); \ - ascent::Logger *lgr = ascent::Logger::instance(); \ - lgr->set_rank(rank); \ - lgr->open(ofname_pattern); \ +#define ASCENT_LOG_OPEN_RANK( ofname_pattern , rank ) \ +{ \ + ascent::Logger &lgr = ascent::Logger::instance(); \ + lgr.set_rank(rank); \ + lgr.open(ofname_pattern); \ } //----------------------------------------------------------------------------- -#define ASCENT_LOG_DEBUG( msg ) \ -{ \ - ascent::Logger *_ascent_lgr = ascent::Logger::instance(); \ - if(_ascent_lgr != nullptr) \ - { \ - std::ostringstream _ascent_oss_info; \ - _ascent_oss_info << msg; \ - _ascent_lgr->log_message(ascent::Logger::DEBUG, \ - _ascent_oss_info.str(), \ - std::string(__FILE__), \ - __LINE__); \ - } \ +#define ASCENT_LOG_DEBUG( msg ) \ +{ \ + std::ostringstream _ascent_oss_info; \ + _ascent_oss_info << msg; \ + ascent::Logger::instance().log_message(ascent::Logger::DEBUG, \ + _ascent_oss_info.str(), \ + std::string(__FILE__), \ + __LINE__); \ } //----------------------------------------------------------------------------- -#define ASCENT_LOG_INFO( msg ) \ -{ \ - ascent::Logger *_ascent_lgr = ascent::Logger::instance(); \ - if(_ascent_lgr != nullptr) \ - { \ - std::ostringstream _ascent_oss_info; \ - _ascent_oss_info << msg; \ - _ascent_lgr->log_message(ascent::Logger::INFO, \ - _ascent_oss_info.str(), \ - std::string(__FILE__), \ - __LINE__); \ - } \ +#define ASCENT_LOG_INFO( msg ) \ +{ \ + std::ostringstream _ascent_oss_info; \ + _ascent_oss_info << msg; \ + ascent::Logger::instance().log_message(ascent::Logger::INFO, \ + _ascent_oss_info.str(), \ + std::string(__FILE__), \ + __LINE__); \ } //----------------------------------------------------------------------------- -#define ASCENT_LOG_WARN( msg ) \ -{ \ - ascent::Logger *_ascent_lgr = ascent::Logger::instance(); \ - if(_ascent_lgr != nullptr) \ - { \ - std::ostringstream _ascent_oss_info; \ - _ascent_oss_info << msg; \ - _ascent_lgr->log_message(ascent::Logger::WARN, \ - _ascent_oss_info.str(), \ - std::string(__FILE__), \ - __LINE__); \ - } \ +#define ASCENT_LOG_WARN( msg ) \ +{ \ + std::ostringstream _ascent_oss_info; \ + _ascent_oss_info << msg; \ + ascent::Logger::instance().log_message(ascent::Logger::WARN, \ + _ascent_oss_info.str(), \ + std::string(__FILE__), \ + __LINE__); \ } //----------------------------------------------------------------------------- -#define ASCENT_LOG_ERROR( msg ) \ -{ \ - ascent::Logger *_ascent_lgr = ascent::Logger::instance(); \ - if(_ascent_lgr != nullptr) \ - { \ - std::ostringstream _ascent_oss_info; \ - _ascent_oss_info << msg; \ - _ascent_lgr->log_message(ascent::Logger::ERROR, \ - _ascent_oss_info.str(), \ - std::string(__FILE__), \ - __LINE__); \ - } \ -}// TODO EXCEPTION! +#define ASCENT_LOG_ERROR( msg ) \ +{ \ + std::ostringstream _ascent_oss_info; \ + _ascent_oss_info << msg; \ + ascent::Logger::instance().log_message(ascent::Logger::ERROR, \ + _ascent_oss_info.str(), \ + std::string(__FILE__), \ + __LINE__); \ + ascent::Logger::instance().flush(); \ + throw conduit::Error(_ascent_oss_info.str(), \ + std::string(__FILE__), \ + __LINE__); \ +} //----------------------------------------------------------------------------- -#define ASCENT_LOG_FLUSH() \ -{ \ - ascent::Logger *_ascent_lgr = ascent::Logger::instance(); \ - if(_ascent_lgr != nullptr) \ - { \ - _ascent_lgr->flush(); \ - } \ +#define ASCENT_LOG_FLUSH() \ +{ \ + ascent::Logger::instance().flush(); \ } //----------------------------------------------------------------------------- -#define ASCENT_LOG_CLOSE() \ -{ \ - ascent::Logger *_ascent_lgr = ascent::Logger::instance(); \ - if(_ascent_lgr != nullptr) \ - { \ - _ascent_lgr->close(); \ - ascent::Logger::deactivate(); \ - } \ +#define ASCENT_LOG_CLOSE() \ +{ \ + ascent::Logger::instance().close(); \ } //----------------------------------------------------------------------------- @@ -143,26 +127,17 @@ ASCENT_LOG_FLUSH() #define ASCENT_MARK_FUNCTION( name ) ASCENT_ANNOTATE_MARK_FUNCTION; ascent::Logger::Scope _ascent_lgr_func(ascent::Logger::instance(), std::string(__func__)); //----------------------------------------------------------------------------- -#define ASCENT_MARK_BEGIN( name ) ASCENT_ANNOTATE_MARK_BEGIN( name ); \ -{ \ - ascent::Logger *_ascent_lgr = ascent::Logger::instance(); \ - if(_ascent_lgr != nullptr) \ - { \ - _ascent_lgr->log_block_begin(name); \ - } \ +#define ASCENT_MARK_BEGIN( name ) ASCENT_ANNOTATE_MARK_BEGIN( name ); \ +{ \ + ascent::Logger::instance().log_block_begin(name); \ } //----------------------------------------------------------------------------- -#define ASCENT_MARK_END( name ) ASCENT_ANNOTATE_MARK_END( name ); \ -{ \ - ascent::Logger *_ascent_lgr = ascent::Logger::instance(); \ - if(_ascent_lgr != nullptr) \ - { \ - _ascent_lgr->log_block_end(name); \ - } \ +#define ASCENT_MARK_END( name ) ASCENT_ANNOTATE_MARK_END( name ); \ +{ \ + ascent::Logger::instance().log_block_end(name); \ } - //----------------------------------------------------------------------------- // -- begin ascent:: -- //----------------------------------------------------------------------------- @@ -177,33 +152,34 @@ class ASCENT_API Logger //------------------------------------------------------------------------- typedef enum { - UNKNOWN = -1, - DEBUG = 1, - INFO = 2, - WARN = 3, - ERROR = 4, - LEGENDARY = 5, + ALL = -1, // lowest + DEBUG = 1, + INFO = 2, + WARN = 3, + ERROR = 4, + NONE = 127, // highest } MessageLevel; //------------------------------------------------------------------------- class ASCENT_API Scope { public: - Scope(Logger *lgr, const std::string &name); + Scope(Logger &lgr, const std::string &name); ~Scope(); private: - Logger *m_lgr; + Logger &m_lgr; std::string m_name; }; // - // "ascent_log_out.yaml" - // "ascent_log_out_{rank}.yaml" - // "ascent_log_out_{rank:05d}.yaml" + // file pattern examples: + // "ascent_log_out.yaml" + // "ascent_log_out_{rank}.yaml" + // "ascent_log_out_{rank:05d}.yaml" // - void open(const std::string &ofile_pattern); - bool is_open(); + bool is_log_open(); + void reset(); // reset to defaults void close(); void flush(); @@ -232,19 +208,21 @@ class ASCENT_API Logger void set_echo_threshold(int level); int echo_threshold() const; - std::ostream &stream(); - - static Logger *instance(); - static void activate(); - static void deactivate(); + std::ostream &log_stream(); + static Logger &instance(); private: //------------------------------------------------------------------------- + // constructor + destructor + // ------------------------------------------------------------------------ Logger(); ~Logger(); - static const std::string &level_string(int level); - std::string timestamp(); + // ------------------------------------------------------------------------ + // helpers + // ------------------------------------------------------------------------ + static std::string level_string(int level); + static std::string timestamp(); void log_message(int level, const std::string &msg, @@ -267,25 +245,31 @@ class ASCENT_API Logger void log_block_end(const std::string &name, std::ostream &os); - std::ofstream m_ofstream; - - int m_indent_level; // default = 0 - int m_indent_spaces; // default = 4 - int m_rank; // default = -1 - int m_level_threshold; // default = INFO - int m_echo_level_threshold; // default = LEGENDARY - - std::string m_indent_string; // current indent string + // ------------------------------------------------------------------------ + // instance vars + // ------------------------------------------------------------------------ + std::ofstream m_log_stream; + bool m_log_open; + std::string m_log_fname; + int m_indent_level; // default = 0 + int m_rank; // default = -1 + int m_log_threshold; // default = INFO + int m_echo_threshold; // default = NONE + std::string m_indent_string; // current indent string + // ------------------------------------------------------------------------ + // logging state stacks + // ------------------------------------------------------------------------ // stack of timers std::stack m_timers; // stack of block name counters // used to make sure we have unique keys in our yaml output std::stack> m_key_counters; + // ------------------------------------------------------------------------ + // static members + // ------------------------------------------------------------------------ static Logger m_instance; - static Logger *m_active_instance; // default = nullptr - static std::vector m_level_strings; }; //----------------------------------------------------------------------------- diff --git a/src/tests/logging/t_ascent_logger_basic.cpp b/src/tests/logging/t_ascent_logger_basic.cpp index c4207ce4a..352f9e0f7 100644 --- a/src/tests/logging/t_ascent_logger_basic.cpp +++ b/src/tests/logging/t_ascent_logger_basic.cpp @@ -57,15 +57,16 @@ void myfunc() //----------------------------------------------------------------------------- TEST(ascent_logging, basic_logging) { - - ASCENT_LOG_OPEN("tout_logging_log_1.yaml"); + // remove file if it exists + std::string lfname = "tout_logging_log_1.yaml"; + conduit::utils::remove_path_if_exists(lfname); + ASCENT_LOG_OPEN(lfname); + ASCENT_LOG_DEBUG("my debug!"); ASCENT_LOG_INFO("my info!"); ASCENT_LOG_WARN("my warning!"); - ASCENT_LOG_ERROR("my error!"); ASCENT_MARK_BEGIN("blocky"); ASCENT_LOG_INFO("my info!"); ASCENT_LOG_WARN("my warning!"); - ASCENT_LOG_ERROR("my error!"); ASCENT_MARK_END("blocky"); myfunc(); @@ -79,7 +80,7 @@ TEST(ascent_logging, basic_logging) ASCENT_LOG_CLOSE(); conduit::Node n; - n.load("tout_logging_log_1.yaml"); + n.load(lfname); n.print(); } @@ -87,39 +88,145 @@ TEST(ascent_logging, basic_logging) //----------------------------------------------------------------------------- TEST(ascent_logging, basic_logging_echo) { - + // remove file if it exists + std::string lfname = "tout_logging_log_2.yaml"; + conduit::utils::remove_path_if_exists(lfname); + ascent::Logger::instance().set_echo_threshold(ascent::Logger::ALL); std::cout << "[echoed]" << std::endl; - ASCENT_LOG_OPEN("tout_logging_log_2.yaml"); - ascent::Logger::instance()->set_echo_threshold(0); + ASCENT_LOG_OPEN(lfname); + ASCENT_LOG_DEBUG("my debug!"); ASCENT_LOG_INFO("my info!"); ASCENT_LOG_WARN("my warning!"); - ASCENT_LOG_ERROR("my error!"); ASCENT_LOG_CLOSE(); std::cout << "[loaded]" << std::endl; conduit::Node n; - n.load("tout_logging_log_2.yaml"); + n.load(lfname); n.print(); - EXPECT_EQ(n.number_of_children(),3); + // we should have 2 msgs above debug + EXPECT_EQ(n.number_of_children(),2); } //----------------------------------------------------------------------------- TEST(ascent_logging, basic_logging_threshold) { - - ASCENT_LOG_OPEN("tout_logging_log_3.yaml"); + // remove file if it exists + std::string lfname = "tout_logging_log_3.yaml"; + conduit::utils::remove_path_if_exists(lfname); + ASCENT_LOG_OPEN(lfname); ASCENT_LOG_INFO("my info!"); - ascent::Logger::instance()->set_log_threshold(ascent::Logger::LEGENDARY); + ascent::Logger::instance().set_log_threshold(ascent::Logger::NONE); ASCENT_LOG_WARN("my warning!"); - ASCENT_LOG_ERROR("my error!"); ASCENT_LOG_CLOSE(); std::cout << "[loaded]" << std::endl; conduit::Node n; - n.load("tout_logging_log_3.yaml"); + n.load(lfname); + n.print(); + // we should have 1 msg above debug + EXPECT_EQ(n.number_of_children(),1); +} + +//----------------------------------------------------------------------------- +TEST(ascent_logging, basic_logging_error) +{ + bool error_occured = false; + try + { + ASCENT_LOG_ERROR("my error!"); + } + catch (conduit::Error &error) + { + std::cout << error.what() << std::endl; + error_occured = true; + } + EXPECT_TRUE(error_occured); + + // now check error inside log file + // remove file if it exists + std::string lfname = "tout_logging_log_4.yaml"; + conduit::utils::remove_path_if_exists(lfname); + ASCENT_LOG_OPEN(lfname); + + error_occured = false; + try + { + ASCENT_LOG_ERROR("my error!"); + } + catch (conduit::Error &error) + { + std::cout << error.what() << std::endl; + error_occured = true; + } + EXPECT_TRUE(error_occured); + + ASCENT_LOG_CLOSE(); + std::cout << "[loaded]" << std::endl; + conduit::Node n; + n.load(lfname); n.print(); + // we should have 1 msg above debug EXPECT_EQ(n.number_of_children(),1); } +//----------------------------------------------------------------------------- +TEST(ascent_logging, basic_logging_append) +{ + // remove file if it exists + std::string lfname = "tout_logging_log_5.yaml"; + conduit::utils::remove_path_if_exists(lfname); + ascent::Logger::instance().set_log_threshold(ascent::Logger::ALL); + ASCENT_LOG_OPEN(lfname); + ASCENT_LOG_INFO("my debug 1!"); + ASCENT_LOG_INFO("my info 1!"); + ASCENT_LOG_WARN("my warning 1!"); + ASCENT_LOG_CLOSE(); + ascent::Logger::instance().set_log_threshold(ascent::Logger::ALL); + ASCENT_LOG_OPEN(lfname); + ASCENT_LOG_INFO("my debug 2!"); + ASCENT_LOG_INFO("my info 2!"); + ASCENT_LOG_WARN("my warning 2!"); + ASCENT_LOG_CLOSE(); + std::cout << "[loaded]" << std::endl; + conduit::Node n; + n.load(lfname); + n.print(); + // we should have 5 * 2 (open, close, + 1 debug, + 1 info, + 1 warn) + EXPECT_EQ(n.number_of_children(),10); +} + + +//----------------------------------------------------------------------------- +TEST(ascent_logging, basic_logging_error_bad_log_file) +{ + bool error_occured = false; + try + { + ASCENT_LOG_OPEN("/blargh/totally/bogus/des/path/to/log/file.yaml"); + } + catch (conduit::Error &error) + { + std::cout << error.what() << std::endl; + error_occured = true; + } + EXPECT_TRUE(error_occured); + + // remove file if it exists + std::string lfname = "tout_logging_log_6.yaml"; + conduit::utils::remove_path_if_exists(lfname); + error_occured =false; + try + { + // double open should throw an exception + ASCENT_LOG_OPEN(lfname); + ASCENT_LOG_OPEN(lfname); + } + catch (conduit::Error &error) + { + std::cout << error.what() << std::endl; + error_occured = true; + } + EXPECT_TRUE(error_occured); +}