log_manager.cxx 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //
  2. // log_manager.cxx
  3. // logging
  4. //
  5. // Created by Sam Jaffe on 4/1/19.
  6. //
  7. #include "logger/log_manager.h"
  8. #include <memory>
  9. #include <unordered_map>
  10. #include "../../../paradigm/declarative/expect/include/expect/expect.hpp"
  11. #include "../../../types/resource_factory/include/resource_factory/prototype_factory.hpp"
  12. #include "logger/c_logger.h"
  13. #include "logger/detail/logger_impl.h"
  14. #include "logger/exception.h"
  15. #include "logger/logger.h"
  16. #include "logger/properties.h"
  17. INSTANTIATE_PROTOTYPE_FACTORY_2(logging::impl_factory);
  18. using namespace logging;
  19. struct logging::manager_impl {
  20. std::shared_ptr<logger_impl> get_logger(properties const & props);
  21. std::shared_ptr<logger_impl> default_logger;
  22. std::unordered_map<std::string, std::shared_ptr<logger_impl>> appenders;
  23. std::unordered_map<std::string, std::shared_ptr<logger_impl>> loggers;
  24. };
  25. manager::manager() : pimpl_(new manager_impl) {}
  26. manager::~manager() {}
  27. logger manager::get() {
  28. return logger("", pimpl_->default_logger);
  29. }
  30. logger manager::get(std::string const & name) {
  31. return logger(name, pimpl_->loggers.at(name));
  32. }
  33. c_logger manager::c_get() {
  34. return c_logger("", pimpl_->default_logger);
  35. }
  36. c_logger manager::c_get(std::string const & name) {
  37. return c_logger(name, pimpl_->loggers.at(name));
  38. }
  39. struct compound_logger : public logger_impl {
  40. void write(logpacket const & pkt) override {
  41. for (auto & log : values) { log->write(pkt); }
  42. }
  43. void flush() override {
  44. for (auto & log : values) { log->flush(); }
  45. }
  46. std::vector<std::shared_ptr<logger_impl>> values;
  47. };
  48. std::shared_ptr<logger_impl>
  49. manager_impl::get_logger(properties const & props) {
  50. if (props.type == properties::OBJECT) {
  51. // TODO include settings on the parent
  52. return appenders.at(props["ref"].value);
  53. } else if (props.type == properties::ARRAY) {
  54. auto out = std::make_shared<compound_logger>();
  55. for (auto & part : props.array) {
  56. out->values.push_back(get_logger(part));
  57. }
  58. return out;
  59. } else {
  60. throw invalid_property_type{"appenders cannot be a STRING"};
  61. }
  62. }
  63. void manager::configure(properties const & props) {
  64. auto & factory = impl_factory::instance();
  65. // TODO: Load logger_impl here
  66. auto & impls = props["configuration"]["appenders"];
  67. // TODO: Support multiple File loggers, etc.
  68. expects(impls.type == properties::OBJECT);
  69. for (auto & app : impls.obj) {
  70. pimpl_->appenders.emplace(app.first, factory.get(app.first, app.second));
  71. }
  72. auto & configs = props["configuration"]["loggers"];
  73. expects(configs.type == properties::OBJECT);
  74. for (auto & log : configs.obj) {
  75. auto logimpl = pimpl_->get_logger(log.second["appenders"]);
  76. pimpl_->loggers.emplace(log.first, logimpl);
  77. }
  78. pimpl_->default_logger = pimpl_->get_logger(configs["root"]["appenders"]);
  79. }