Não pode escolher mais do que 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

99 linhas
3.8 KiB

  1. #pragma once
  2. #include <cpputils/misc/exception.h>
  3. #include <cpputils/logging/types.h>
  4. #include <cpputils/logging/message.h>
  5. // () mandatory
  6. // [] optional
  7. // (logger), (LogLevel: debug|info|warn|error), [Sender], [Message, [Arguments]]
  8. #define log_message(logger, level, ...) \
  9. if (logger.is_enabled(::utl::logging::log_level::level)) \
  10. logger.make_log_helper(::utl::logging::log_level::level, __FILE__, __LINE__, ## __VA_ARGS__ ) = ::utl::logging::message()
  11. namespace utl {
  12. namespace logging {
  13. struct logger
  14. {
  15. public:
  16. struct helper
  17. {
  18. private:
  19. logger& _logger;
  20. data_ptr_s _data;
  21. public:
  22. inline void operator=(const message& msg)
  23. { _data->message += msg.str(); }
  24. inline helper(logger& logger, data_ptr_s data) :
  25. _logger (logger),
  26. _data (data)
  27. { }
  28. inline ~helper()
  29. { _logger.log(_data); }
  30. public:
  31. static inline helper create(logger& logger, log_level level, const char* file, int line, void* sender, const std::string& name, std::string message)
  32. {
  33. using namespace ::utl::logging;
  34. data_ptr_s ret(new data());
  35. ret->level = level;
  36. ret->time = std::chrono::steady_clock::now();
  37. ret->thread = std::this_thread::get_id();
  38. ret->file = file;
  39. ret->line = line;
  40. ret->sender = sender;
  41. ret->name = name;
  42. ret->message = message;
  43. return helper(logger, ret);
  44. }
  45. };
  46. private:
  47. logger(logger&&) = delete;
  48. logger(const logger&) = delete;
  49. public:
  50. logger() { }
  51. virtual const std::string& name () const;
  52. virtual bool is_enabled (log_level level) const;
  53. virtual void log (data_ptr_s data) const;
  54. template<class Sender, class... Args>
  55. inline logger::helper make_log_helper(log_level level, const char* file, int line, Sender* sender, std::string message, Args... args)
  56. {
  57. std::unique_ptr<char, decltype(&free)> buff(static_cast<char*>(malloc(0x8000)), &free);
  58. auto len = snprintf(buff.get(), 10240, message.c_str(), args...);
  59. if (len < 0)
  60. throw utl::error_exception(errno);
  61. return helper::create(*this, level, file, line, static_cast<void*>(sender), name(), std::string(buff.get(), len));
  62. }
  63. template<class... Args>
  64. inline logger::helper make_log_helper(log_level level, const char* file, int line, std::string message, Args... args)
  65. { return make_log_helper<void, Args...>(level, file, line, nullptr, message, args...); }
  66. template<class Sender>
  67. inline logger::helper make_log_helper(log_level level, const char* file, int line, Sender* sender, std::string message)
  68. { return helper::create(*this, level, file, line, static_cast<void*>(sender), name(), message); }
  69. template<class Sender>
  70. inline logger::helper make_log_helper(log_level level, const char* file, int line, Sender* sender)
  71. { return make_log_helper<void>(level, file, line, static_cast<void*>(sender), std::string()); }
  72. inline logger::helper make_log_helper(log_level level, const char* file, int line, std::string message)
  73. { return make_log_helper<void>(level, file, line, nullptr, message); }
  74. inline logger::helper make_log_helper(log_level level, const char* file, int line)
  75. { return make_log_helper<void>(level, file, line, nullptr, std::string()); }
  76. };
  77. logger& get_logger(const std::string& name = "");
  78. }
  79. }