-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLoggerModule.hpp
134 lines (115 loc) · 4.01 KB
/
LoggerModule.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
#pragma once
#include <fmt/core.h>
#include <spdlog/sinks/stdout_color_sinks.h>
#include <spdlog/spdlog.h>
#include <cstdarg>
#include <iomanip> // needed for setw and setfill
#include <iostream>
#include <iterator>
#include <ostream>
#include <sstream>
#include <string>
#include <type_traits> // needed for std::is_same
#include <vector>
class LoggerModule {
public:
struct HexBuffer {
const std::vector<unsigned char> &buffer;
HexBuffer(const std::vector<unsigned char> &buf) : buffer(buf) {}
};
static inline std::shared_ptr<spdlog::logger> logger_ = nullptr;
static void init() {
if (!logger_) {
auto console_sink =
std::make_shared<spdlog::sinks::stdout_color_sink_mt>();
console_sink->set_pattern("[%^%l%$] %v");
logger_ = std::make_shared<spdlog::logger>("logger", console_sink);
console_sink->set_level(spdlog::level::debug);
logger_->set_level(spdlog::level::debug);
spdlog::register_logger(logger_);
}
}
static void setLogLevel(spdlog::level::level_enum level) {
if (logger_) {
logger_->set_level(level);
}
}
private:
template <typename T>
static constexpr bool is_byte_vector =
std::is_same<T, std::vector<unsigned char>>::value;
template <typename T> static auto format_arg(const T &arg) {
if constexpr (is_byte_vector<T>)
return HexBuffer(arg);
else
return arg;
}
public:
template <typename... Args>
static void log(const char *file, int line, spdlog::level::level_enum level,
const std::string &fmt, Args... args) {
const int maxFileWidth = sizeof("FileHandler.cpp") - 1;
const int maxLineNumWidth = 3;
const int maxTotalWidth = maxFileWidth + maxLineNumWidth + 5;
std::ostringstream oss;
oss << "[" << file << ":" << line << "]";
int actualLength = oss.str().length();
int spacesRequired = maxTotalWidth - actualLength;
oss << std::string(spacesRequired, ' ');
oss << "[%^%l%$] %v";
spdlog::set_pattern(oss.str());
switch (level) {
case spdlog::level::info:
logger_->info(fmt, format_arg(args)...);
break;
case spdlog::level::warn:
logger_->warn(fmt, format_arg(args)...);
break;
case spdlog::level::err:
logger_->error(fmt, format_arg(args)...);
break;
case spdlog::level::critical:
logger_->critical(fmt, format_arg(args)...);
break;
case spdlog::level::debug:
logger_->debug(fmt, format_arg(args)...);
break;
default:
logger_->info(fmt, format_arg(args)...);
break;
}
}
};
namespace fmt {
template <> struct formatter<LoggerModule::HexBuffer> {
template <typename ParseContext> constexpr auto parse(ParseContext &ctx) {
return ctx.begin();
}
template <typename FormatContext>
auto format(const LoggerModule::HexBuffer &buf, FormatContext &ctx) {
std::string formatted;
for (size_t i = 0; i < buf.buffer.size(); ++i) {
formatted += fmt::format("{:02x} ", buf.buffer[i]);
if ((i + 1) % 8 == 0)
formatted += "\n";
}
return format_to(ctx.out(), "{}", formatted);
}
};
} // namespace fmt
#define LOG(fmt, ...) \
LoggerModule::log(__FILE__, __LINE__, spdlog::level::info, fmt, ##__VA_ARGS__)
#define ERROR_LOG(fmt, ...) \
LoggerModule::log(__FILE__, __LINE__, spdlog::level::err, fmt, ##__VA_ARGS__)
#define CRITICAL_LOG(fmt, ...) \
LoggerModule::log(__FILE__, __LINE__, spdlog::level::critical, fmt, \
##__VA_ARGS__)
#define WARN_LOG(fmt, ...) \
LoggerModule::log(__FILE__, __LINE__, spdlog::level::warn, fmt, ##__VA_ARGS__)
#ifdef ENABLE_DEBUG_LOGGING
#define DEBUG_LOG(fmt, ...) \
LoggerModule::log(__FILE__, __LINE__, spdlog::level::debug, fmt, \
##__VA_ARGS__)
#else
#define DEBUG_LOG(fmt, ...)
#endif