27#include <fmt/format.h>
28#include <fmt/compile.h>
37#include <condition_variable>
52#include <sys/syscall.h>
57#define APP_NAME "libjami"
61#define END_COLOR "\033[0m"
64#define RED "\033[22;31m"
65#define YELLOW "\033[01;33m"
66#define CYAN "\033[22;36m"
68#define FOREGROUND_WHITE 0x000f
69#define RED FOREGROUND_RED + 0x0008
70#define YELLOW FOREGROUND_RED + FOREGROUND_GREEN + 0x0008
71#define CYAN FOREGROUND_BLUE + FOREGROUND_GREEN + 0x0008
72#define LIGHT_GREEN FOREGROUND_GREEN + 0x0008
79static constexpr auto ENDL =
'\n';
90 return "unknown (too big to display)";
93 return "unknown (invalid error number)";
122 }
else return nullptr;
131 auto tid = std::this_thread::get_id();
145 return fmt::format(
FMT_COMPILE(
"[{: >3d}.{:0<3d}|{: >4}|{: <24s}:{: <4d}] "),
172 if ((
size_t) size >=
ret.size()) {
173 ret.resize(size + 1);
188 Msg(
int level,
const char* file,
int line,
bool linefeed, std::string&& message)
196 Msg(
int level,
const char* file,
int line,
bool linefeed,
const char* fmt, va_list ap)
208 payload_ = std::move(other.payload_);
231 void enable(
bool en) { enabled_.store(en, std::memory_order_relaxed); }
232 bool isEnable() {
return enabled_.load(std::memory_order_relaxed); }
235 std::atomic_bool enabled_ {
false};
269 auto header =
msg.header();
275 switch (
msg.level_) {
310 auto header =
msg.header();
315 switch (
msg.level_) {
354Logger::setConsoleLog(
bool en)
413Logger::setSysLog(
bool en)
431 auto message =
msg.header() +
msg.payload_;
437Logger::setMonitorLog(
bool en)
455 if (thread_.joinable()) {
456 notify([
this] {
enable(
false); });
461 if (
not path.empty()) {
462 file.open(path, std::ofstream::out | std::ofstream::app);
469 thread_ = std::thread([
this,
file = std::move(
file)]()
mutable {
473 std::unique_lock
lk(mtx_);
490 notify([=] {
enable(
false); });
491 if (thread_.joinable())
497 notify([&,
this] { currentQ_.emplace_back(std::move(
msg)); });
504 std::lock_guard
lk(mtx_);
509 void do_consume(std::ofstream&
file,
const std::vector<Logger::Msg>&
messages)
519 std::vector<Logger::Msg> currentQ_;
521 std::condition_variable cv_;
526Logger::setFileLog(
const std::string& path)
555Logger::setDebugMode(
bool enable)
561Logger::debugEnabled()
606 Logger::setConsoleLog(
false);
void consume(Logger::Msg &msg) override
static ConsoleLog & instance()
void printLogImpl(const Logger::Msg &msg, bool with_color)
static FileLog & instance()
void consume(Logger::Msg &msg) override
void setFile(const std::string &path)
virtual void consume(Msg &msg)=0
virtual ~Handler()=default
static LIBJAMI_PUBLIC void static LIBJAMI_PUBLIC void vlog(int level, const char *file, int line, bool linefeed, const char *fmt, va_list)
Printf fashion logging (using va_list parameters)
static MonitorLog & instance()
void consume(Logger::Msg &msg) override
static SysLog & instance()
void consume(Logger::Msg &msg) override
static std::atomic_bool debugEnabled_
void emitSignal(Args... args)
std::string formatPrintfArgs(const char *format, va_list ap)
static const char * stripDirName(const char *path)
void strErr()
Thread-safe function to print the stringified contents of errno.
static const char * check_error(int result, char *buffer)
static constexpr auto ENDL
void log_to_if_enabled(T &handler, Logger::Msg &msg)
std::string formatHeader(const char *const file, int line)
Msg(int level, const char *file, int line, bool linefeed, std::string &&message)
std::string header() const
Msg(int level, const char *file, int line, bool linefeed, const char *fmt, va_list ap)
#define strerror_r(errno, buf, len)
void syslog(int, const char *,...)
void openlog(const char *, int, int)