3 #include <kafka/Project.h>
5 #include <kafka/Utility.h>
31 static const std::string& levelString(std::size_t level)
33 static const std::vector<std::string> levelNames = {
"EMERG",
"ALERT",
"CRIT",
"ERR",
"WARNING",
"NOTICE",
"INFO",
"DEBUG",
"INVALID"};
34 static const std::size_t maxIndex = levelNames.size() - 1;
36 return levelNames[(std::min)(level, maxIndex)];
42 template <std::
size_t MAX_CAPACITY>
46 LogBuffer() { clear(); }
55 template<
class ...Args>
56 LogBuffer& print(
const char* format, Args... args)
58 assert(!(_buf[0] != 0 && _wptr == _buf.data()));
60 auto cnt = std::snprintf(_wptr, capacity(), format, args...);
63 _wptr = (std::min)(_wptr + cnt, _buf.data() + MAX_CAPACITY - 1);
67 LogBuffer& print(
const char* format) {
return print(
"%s", format); }
69 std::size_t capacity()
const {
return static_cast<size_t>(_buf.data() + MAX_CAPACITY - _wptr); }
70 char* str() {
return _buf.data(); }
71 const char* c_str()
const {
return _buf.data(); }
74 std::array<char, MAX_CAPACITY> _buf;
75 char* _wptr =
nullptr;
80 inline void DefaultLogger(
int level,
const char* ,
int ,
const char* msg)
82 std::cout <<
"[" << utility::getCurrentTime() <<
"]" << Log::levelString(
static_cast<std::size_t
>(level)) <<
" " << msg;
83 std::cout << std::endl;
87 inline void NullLogger(
int ,
const char* ,
int ,
const char* )
93 template <
typename T =
void>
96 static clients::LogCallback logCb;
97 static std::once_flag initOnce;
99 static const constexpr
int LOG_BUFFER_SIZE = 1024;
101 template<
class ...Args>
102 static void doLog(
int level,
const char* filename,
int lineno,
const char* format, Args... args)
104 if (!GlobalLogger<>::logCb)
return;
106 LogBuffer<LOG_BUFFER_SIZE> logBuffer;
107 logBuffer.print(format, args...);
108 GlobalLogger<>::logCb(level, filename, lineno, logBuffer.c_str());
112 template <
typename T>
113 clients::LogCallback GlobalLogger<T>::logCb;
115 template <
typename T>
116 std::once_flag GlobalLogger<T>::initOnce;
121 inline void setGlobalLogger(clients::LogCallback cb)
123 std::call_once(GlobalLogger<>::initOnce, [](){});
124 GlobalLogger<>::logCb = std::move(cb);
133 #define KAFKA_API_LOG(level, ...) do { \
134 std::call_once(GlobalLogger<>::initOnce, [](){ GlobalLogger<>::logCb = DefaultLogger; }); \
135 GlobalLogger<>::doLog(level, __FILE__, __LINE__, ##__VA_ARGS__); \