// // file_logger.cxx // logging // // Created by Sam Jaffe on 4/1/19. // #include #include "expect/expect.hpp" #include "resource_factory/prototype_factory.hpp" #include "logger/detail/appender.h" #include "logger/log_manager.h" #include "logger/properties.h" using namespace logging; namespace logging { level level_from_string(std::string const & value); } class file_appender : public appender { public: static std::shared_ptr create(properties const&); explicit file_appender(const std::string& fname, bool append); void write(std::string const & msg) override; void flush() override; private: bool flush_immediately_{false}; std::ofstream out_; }; using namespace logging::property; properties const DEFAULT_FILE_APPENDER{_obj({ {"immediateFlush", _v(true)}, {"threshold", _v("ERROR")}, {"filename", {}}, // Will throw if accessed {"fileAppend", _v(true)}/*, {"bufferedIO", _v(false)}, {"bufferSize", _v(8192)}*/ })}; std::shared_ptr file_appender::create(properties const & props) { properties const actual = DEFAULT_FILE_APPENDER.mergedWith(props); file_appender app(actual["filename"], actual["fileAppend"]); app.flush_immediately_ = actual["immediateFlush"]; app.min_log_level = level_from_string(actual["threshold"]); return std::make_shared(std::move(app)); } static std::ios_base::openmode mode(bool append) { return (append ? std::ios_base::app : 0) | std::ios_base::out; } file_appender::file_appender(const std::string& fname, bool append) : out_(fname, mode(append)) {} void file_appender::write(std::string const & msg) { out_ << msg; if (flush_immediately_) { flush(); } } void file_appender::flush() { out_.flush(); } namespace { bool _ = appenders::instance().bind("File", file_appender::create); }