// // log_manager.cxx // logging // // Created by Sam Jaffe on 4/1/19. // #include "logger/log_manager.h" #include #include #include "../../../paradigm/declarative/expect/include/expect/expect.hpp" #include "../../../types/resource_factory/include/resource_factory/prototype_factory.hpp" #include "logger/c_logger.h" #include "logger/detail/logger_impl.h" #include "logger/exception.h" #include "logger/logger.h" #include "logger/properties.h" INSTANTIATE_PROTOTYPE_FACTORY_2(logging::impl_factory); using namespace logging; struct logging::manager_impl { std::shared_ptr get_logger(properties const & props); std::shared_ptr default_logger; std::unordered_map> appenders; std::unordered_map> loggers; }; manager::manager() : pimpl_(new manager_impl) {} manager::~manager() {} logger manager::get() { return logger("", pimpl_->default_logger); } logger manager::get(std::string const & name) { return logger(name, pimpl_->loggers.at(name)); } c_logger manager::c_get() { return c_logger("", pimpl_->default_logger); } c_logger manager::c_get(std::string const & name) { return c_logger(name, pimpl_->loggers.at(name)); } struct compound_logger : public logger_impl { void write(logpacket const & pkt) override { for (auto & log : values) { log->write(pkt); } } void flush() override { for (auto & log : values) { log->flush(); } } std::vector> values; }; std::shared_ptr manager_impl::get_logger(properties const & props) { if (props.type == properties::OBJECT) { // TODO include settings on the parent return appenders.at(props["ref"].value); } else if (props.type == properties::ARRAY) { auto out = std::make_shared(); for (auto & part : props.array) { out->values.push_back(get_logger(part)); } return out; } else { throw invalid_property_type{"appenders cannot be a STRING"}; } } void manager::configure(properties const & props) { auto & factory = impl_factory::instance(); // TODO: Load logger_impl here auto & impls = props["configuration"]["appenders"]; // TODO: Support multiple File loggers, etc. expects(impls.type == properties::OBJECT); for (auto & app : impls.obj) { pimpl_->appenders.emplace(app.first, factory.get(app.first, app.second)); } auto & configs = props["configuration"]["loggers"]; expects(configs.type == properties::OBJECT); for (auto & log : configs.obj) { auto logimpl = pimpl_->get_logger(log.second["appenders"]); pimpl_->loggers.emplace(log.first, logimpl); } pimpl_->default_logger = pimpl_->get_logger(configs["root"]["appenders"]); }