123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- #ifndef EDK_CXXUTIL_LOG_H_
- #define EDK_CXXUTIL_LOG_H_
- #include <string>
- #include <streambuf>
- #include <ostream>
- #define STRINGIFY(src) #src
- #define _EDK_LOG_IS_ON(cate, sev) edk::log::LogActivated(STRINGIFY(cate), sev)
- #define _EDK_LOG_STREAM(cate, sev) edk::log::LogMessage(STRINGIFY(cate), __FILE__, __LINE__, sev).stream()
- #define _EDK_LOG(cate, sev) \
- !(_EDK_LOG_IS_ON(cate, sev)) ? (void)0 : edk::log::LogMessageVoidify() & _EDK_LOG_STREAM(cate, sev)
- #define _EDK_LOG_IF(cate, sev, condition) \
- !(_EDK_LOG_IS_ON(cate, sev) && (condition)) ? (void)0 : edk::log::LogMessageVoidify() & _EDK_LOG_STREAM(cate, sev)
- #define _EDK_LOG_CONCAT(lhs, rhs) lhs##_##rhs
- #define _EDK_LOG_COUNTER_NAME(name, line) _EDK_LOG_CONCAT(name, line)
- #define _EDK_LOG_COUNTER _EDK_LOG_COUNTER_NAME(_log_counter, __LINE__)
- #define LOG_EVERY_N(category, severity, N) \
- static int _EDK_LOG_COUNTER = 0; \
- ++_EDK_LOG_COUNTER > N ? _EDK_LOG_COUNTER -= N : 0; \
- _EDK_LOG_IF(category, edk::log::severity, (_EDK_LOG_COUNTER == 1))
- #define LOG_FIRST_N(category, severity, N) \
- static int _EDK_LOG_COUNTER = 0; \
- ++_EDK_LOG_COUNTER > N + 1 ? --_EDK_LOG_COUNTER : 0; \
- _EDK_LOG_IF(category, edk::log::severity, (_EDK_LOG_COUNTER <= N))
- #define LOGF(category) _EDK_LOG_STREAM(category, edk::log::LOG_FATAL)
- #define LOGF_IF(category, condition) \
- !(condition) ? (void)0 : edk::log::LogMessageVoidify() & _EDK_LOG_STREAM(category, edk::log::LOG_FATAL)
- #define LOGE(category) _EDK_LOG(category, edk::log::LOG_ERROR)
- #define LOGE_IF(category, condition) _EDK_LOG_IF(category, edk::log::LOG_ERROR, condition)
- #define LOGW(category) _EDK_LOG(category, edk::log::LOG_WARNING)
- #define LOGW_IF(category, condition) _EDK_LOG_IF(category, edk::log::LOG_WARNING, condition)
- #define LOGI(category) _EDK_LOG(category, edk::log::LOG_INFO)
- #define LOGI_IF(category, condition) _EDK_LOG_IF(category, edk::log::LOG_INFO, condition)
- #define LOGD(category) _EDK_LOG(category, edk::log::LOG_DEBUG)
- #define LOGD_IF(category, condition) _EDK_LOG_IF(category, edk::log::LOG_DEBUG, condition)
- #define LOGT(category) _EDK_LOG(category, edk::log::LOG_TRACE)
- #define LOGT_IF(category, condition) _EDK_LOG_IF(category, edk::log::LOG_TRACE, condition)
- #define LOGA(category) _EDK_LOG(category, edk::log::LOG_ALL)
- #define LOGA_IF(category, condition) _EDK_LOG_IF(category, edk::log::LOG_ALL, condition)
- #define CHECK(category, condition) \
- LOGF_IF((category), !(condition)) << "Check condition (" << STRINGIFY(condition) ") failed"
- namespace edk {
- namespace log {
- enum LogSeverity {
- LOG_FATAL = 0,
- LOG_ERROR,
- LOG_WARNING,
- LOG_INFO,
- LOG_DEBUG,
- LOG_TRACE,
- LOG_ALL
- };
- class LogSink {
- public:
- virtual ~LogSink() { }
- virtual void Send(LogSeverity severity, const char* category,
- const char* filename, int line,
- const struct ::tm* tm_time, int32_t usecs,
- const char* message, size_t message_len) = 0;
- virtual void WaitTillSent() { }
- static std::string ToString(LogSeverity severity, const char* category,
- const char* filename, int line,
- const struct ::tm* tm_time, int32_t usecs,
- const char* message, size_t message_len);
- };
- class LogMessageVoidify {
- public:
- LogMessageVoidify() { }
-
-
- void operator&(std::ostream&) { }
- };
- class LogMessage {
- public:
- class LogStreamBuf : public std::streambuf {
- public:
-
- LogStreamBuf(char *buf, int len) {
- setp(buf, buf + len - 2);
- }
-
- virtual int_type overflow(int_type ch) {
- return ch;
- }
-
- size_t pcount() const { return pptr() - pbase(); }
- char* pbase() const { return std::streambuf::pbase(); }
- };
- class LogStream : public std::ostream {
- public:
- LogStream(char *buf, int len)
- : std::ostream(NULL),
- streambuf_(buf, len) {
- rdbuf(&streambuf_);
- }
-
- size_t pcount() const { return streambuf_.pcount(); }
- char* pbase() const { return streambuf_.pbase(); }
- char* str() const { return pbase(); }
- private:
- LogStream(const LogStream&) = delete;
- LogStream& operator=(const LogStream&) = delete;
- LogStreamBuf streambuf_;
- };
- LogMessage(const char* category, const char* file, int line, LogSeverity severity);
- ~LogMessage();
- void Init(const char* category, const char* file, int line, LogSeverity severity);
- std::ostream& stream();
- struct LogMessageData;
- private:
- LogMessage(const LogMessage&) = delete;
- LogMessage& operator=(const LogMessage&) = delete;
- void Flush();
- void SendToLog();
- LogMessageData* data_;
- LogMessageData* allocated_;
- static const size_t MaxLogMsgLen;
- };
- namespace detail {
- bool CategoryActivated(const char* category, LogSeverity severity) noexcept;
- }
- extern const int g_min_log_level;
- extern const bool g_enable_category_filter;
- inline bool LogActivated(const char* category, LogSeverity severity) noexcept {
- if (g_enable_category_filter) {
- return detail::CategoryActivated(category, severity);
- }
- return g_min_log_level >= severity;
- }
- void InitLogging(bool log_to_stderr, bool log_to_file, const std::string& log_dir = "") noexcept;
- void ShutdownLogging() noexcept;
- void SetFileFlushInterval(uint32_t time) noexcept;
- void AddLogSink(LogSink* log_sink) noexcept;
- void RemoveLogSink(LogSink* log_sink) noexcept;
- }
- }
- #endif
|