You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

129 lines
3.9 KiB

  1. #include <map>
  2. #include <list>
  3. #include <chrono>
  4. #include <thread>
  5. #include <cpputils/logging/rule.h>
  6. #include <cpputils/logging/global.h>
  7. #include <cpputils/logging/logger_impl.h>
  8. #include <cpputils/logging/consumer/consumer.h>
  9. namespace utl {
  10. namespace logging {
  11. struct manager
  12. {
  13. private:
  14. logger_impl _default_logger;
  15. std::map<std::string, logger_impl_ptr_u> _logger;
  16. std::list<rule> _rules;
  17. std::set<consumer*> _consumer;
  18. logger_impl& initLogger(logger_impl& logger)
  19. {
  20. for (auto& rule : _rules)
  21. {
  22. if (rule.logger_matcher->match(logger))
  23. logger.registerRule(rule);
  24. }
  25. return logger;
  26. }
  27. public:
  28. inline logger& get_logger(const std::string& name)
  29. {
  30. if (name.empty())
  31. return _default_logger;
  32. auto it = _logger.find(name);
  33. return (it != _logger.end()
  34. ? *it->second
  35. : initLogger(*_logger.emplace(name, logger_impl_ptr_u(new logger_impl(name))).first->second));
  36. }
  37. void register_consumer(consumer& consumer)
  38. {
  39. _consumer.insert(&consumer);
  40. for (auto& rule : _rules)
  41. {
  42. if (rule.consumer_matcher->match(consumer))
  43. rule.register_consumer(consumer);
  44. }
  45. }
  46. void unregister_consumer(consumer& consumer)
  47. {
  48. for (auto& rule : _rules)
  49. rule.unregister_consumer(consumer);
  50. }
  51. rule_handle define_rule(matcher_ptr_u logger_matcher, matcher_ptr_u consumer_matcher, log_level min_level, log_level max_level)
  52. {
  53. _rules.emplace_back(std::move(logger_matcher), std::move(consumer_matcher), min_level, max_level);
  54. auto& rule = _rules.back();
  55. for (auto& c : _consumer)
  56. {
  57. if (rule.consumer_matcher->match(*c))
  58. rule.register_consumer(*c);
  59. }
  60. if (rule.logger_matcher->match(_default_logger))
  61. _default_logger.registerRule(rule);
  62. for (auto& l : _logger)
  63. {
  64. if (rule.logger_matcher->match(*l.second))
  65. l.second->registerRule(rule);
  66. }
  67. return &rule;
  68. }
  69. void undefine_rule(rule_handle handle)
  70. {
  71. auto r = static_cast<rule*>(handle);
  72. auto it = _rules.begin();
  73. while (&*it != r && it != _rules.end())
  74. ++it;
  75. if (it == _rules.end())
  76. return;
  77. _default_logger.unregisterRule(*it);
  78. for (auto& l : _logger)
  79. l.second->unregisterRule(*it);
  80. _rules.erase(it);
  81. }
  82. inline void reset()
  83. {
  84. _logger.clear();
  85. _rules.clear();
  86. _consumer.clear();
  87. }
  88. manager() :
  89. _default_logger(std::string())
  90. { }
  91. };
  92. manager& get_manager()
  93. {
  94. static manager value;
  95. return value;
  96. }
  97. logger& get_logger(const std::string& name)
  98. { return get_manager().get_logger(name); }
  99. void register_consumer(consumer& consumer)
  100. { return get_manager().register_consumer(consumer); }
  101. void unregister_consumer(consumer& consumer)
  102. { return get_manager().unregister_consumer(consumer); }
  103. rule_handle define_rule(matcher_ptr_u logger_matcher, matcher_ptr_u consumer_matcher, log_level min_level, log_level max_level)
  104. { return get_manager().define_rule(std::move(logger_matcher), std::move(consumer_matcher), min_level, max_level); }
  105. void undefine_rule(rule_handle rule)
  106. { return get_manager().undefine_rule(rule); }
  107. void reset_logging()
  108. { get_manager().reset(); }
  109. }
  110. }