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.

123 lines
2.6 KiB

2 months ago
  1. /**
  2. * @file logger.h
  3. *
  4. * Defines the base Logger class
  5. */
  6. #pragma once
  7. #include <vector>
  8. #include <algorithm>
  9. #include <map>
  10. #include <sstream>
  11. namespace l3pp {
  12. namespace detail {
  13. /**
  14. * Internal function to get all configured loggers. Should not be used
  15. * directly, see Logger::getLogger()
  16. */
  17. static inline std::map<std::string, LogPtr>& GetLoggers() {
  18. static std::map<std::string, LogPtr> loggers;
  19. return loggers;
  20. }
  21. }
  22. inline LogStream::~LogStream() {
  23. if (level != LogLevel::OFF) {
  24. logger.log(level, stream.str(), context);
  25. }
  26. }
  27. inline void Logger::logEntry(EntryContext const& context, std::string const& msg) {
  28. for(auto& sink: sinks) {
  29. sink->log(context, msg);
  30. }
  31. if (additive && parent) {
  32. parent->logEntry(context, msg);
  33. }
  34. }
  35. inline void Logger::removeSink(SinkPtr sink) {
  36. std::vector<SinkPtr>::iterator pos = std::find(sinks.begin(), sinks.end(), sink);
  37. if (pos != sinks.end()) {
  38. sinks.erase(pos);
  39. }
  40. }
  41. inline void Logger::log(LogLevel level, std::string const& msg, EntryContext context) {
  42. if (level < getLevel()) {
  43. return;
  44. }
  45. context.level = level;
  46. context.logger = this;
  47. logEntry(context, msg);
  48. }
  49. inline LogStream Logger::log(LogLevel level, EntryContext context) {
  50. if (level < getLevel()) {
  51. // Effectively disables the stream
  52. return LogStream(*this, LogLevel::OFF, context);
  53. } else {
  54. return LogStream(*this, level, context);
  55. }
  56. }
  57. inline void Logger::initialize() {
  58. // Setup root logger
  59. getRootLogger();
  60. // Set wall time
  61. Formatter::initialize();
  62. }
  63. inline void Logger::deinitialize() {
  64. detail::GetLoggers().clear();
  65. getRootLogger()->sinks.clear();
  66. }
  67. inline LogPtr Logger::getRootLogger() {
  68. static LogPtr rootLogger = LogPtr(new Logger());
  69. return rootLogger;
  70. }
  71. inline LogPtr Logger::getLogger(std::string name) {
  72. if (name.size() == 0) {
  73. // Root logger
  74. return getRootLogger();
  75. }
  76. auto& loggers = detail::GetLoggers();
  77. auto it = loggers.find(name);
  78. if (it != loggers.end()) {
  79. return it->second;
  80. } else {
  81. auto n = name.rfind('.');
  82. LogPtr parent;
  83. if (n == std::string::npos) {
  84. parent = getRootLogger();
  85. } else{
  86. parent = getLogger(name.substr(0, n));
  87. }
  88. LogPtr newLogger = LogPtr(new Logger(name, parent));
  89. loggers.emplace(name, newLogger);
  90. return newLogger;
  91. }
  92. }
  93. template<typename T>
  94. inline LogStream const& operator<<(LogStream const& stream, T const& val) {
  95. if (stream.level != LogLevel::OFF) {
  96. stream.stream << val;
  97. }
  98. return stream;
  99. }
  100. inline LogStream const& operator<<(LogStream const& stream, std::ostream& (*F)(std::ostream&)) {
  101. if (stream.level != LogLevel::OFF) {
  102. stream.stream << F;
  103. }
  104. return stream;
  105. }
  106. }