Logger.h 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. // Copyright (C) 2009-2016, Panagiotis Christopoulos Charitos.
  2. // All rights reserved.
  3. // Code licensed under the BSD License.
  4. // http://www.anki3d.org/LICENSE
  5. #pragma once
  6. #include <anki/Config.h>
  7. #include <anki/util/Singleton.h>
  8. #include <anki/util/Thread.h>
  9. namespace anki
  10. {
  11. // Forward
  12. class File;
  13. /// @addtogroup util_private
  14. /// @{
  15. /// The logger singleton class. The logger cannot print errors or throw
  16. /// exceptions, it has to recover somehow. Its thread safe
  17. /// To add a new signal:
  18. /// @code logger.addMessageHandler((void*)obj, &function) @endcode
  19. class Logger
  20. {
  21. public:
  22. /// Logger message type
  23. enum class MessageType : U8
  24. {
  25. NORMAL,
  26. ERROR,
  27. WARNING,
  28. FATAL,
  29. COUNT
  30. };
  31. /// Used as parammeter when emitting the signal
  32. class Info
  33. {
  34. public:
  35. const char* m_file;
  36. I32 m_line;
  37. const char* m_func;
  38. MessageType m_type;
  39. const char* m_msg;
  40. };
  41. /// The message handler callback
  42. using MessageHandlerCallback = void (*)(void*, const Info& info);
  43. /// Initialize the logger and add the default message handler
  44. Logger();
  45. ~Logger();
  46. /// Add a new message handler
  47. void addMessageHandler(void* data, MessageHandlerCallback callback);
  48. /// Add file message handler.
  49. void addFileMessageHandler(File* file);
  50. /// Send a message
  51. void write(const char* file,
  52. int line,
  53. const char* func,
  54. MessageType type,
  55. const char* msg);
  56. /// Send a formated message
  57. void writeFormated(const char* file,
  58. int line,
  59. const char* func,
  60. MessageType type,
  61. const char* fmt,
  62. ...);
  63. private:
  64. class Handler
  65. {
  66. public:
  67. void* m_data = nullptr;
  68. MessageHandlerCallback m_callback = nullptr;
  69. Handler() = default;
  70. Handler(const Handler&) = default;
  71. Handler(void* data, MessageHandlerCallback callback)
  72. : m_data(data)
  73. , m_callback(callback)
  74. {
  75. }
  76. };
  77. Mutex m_mutex; ///< For thread safety
  78. Array<Handler, 4> m_handlers;
  79. U32 m_handlersCount = 0;
  80. static void defaultSystemMessageHandler(void*, const Info& info);
  81. static void fileMessageHandler(void* file, const Info& info);
  82. };
  83. typedef Singleton<Logger> LoggerSingleton;
  84. #define ANKI_LOGGER_MESSAGE(t, ...) \
  85. do \
  86. { \
  87. LoggerSingleton::get().writeFormated( \
  88. ANKI_FILE, __LINE__, ANKI_FUNC, t, __VA_ARGS__); \
  89. } while(false);
  90. /// @}
  91. /// @addtogroup util_logging
  92. /// @{
  93. /// Log information message.
  94. #define ANKI_LOGI(...) \
  95. ANKI_LOGGER_MESSAGE(Logger::MessageType::NORMAL, __VA_ARGS__)
  96. /// Log warning message.
  97. #define ANKI_LOGW(...) \
  98. ANKI_LOGGER_MESSAGE(Logger::MessageType::WARNING, __VA_ARGS__)
  99. /// Log error message.
  100. #define ANKI_LOGE(...) \
  101. ANKI_LOGGER_MESSAGE(Logger::MessageType::ERROR, __VA_ARGS__)
  102. /// Log fatal message. It will will abort.
  103. #define ANKI_LOGF(...) \
  104. ANKI_LOGGER_MESSAGE(Logger::MessageType::FATAL, __VA_ARGS__)
  105. /// @}
  106. } // end namespace anki