2016-06-14 23:32:35 -04:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include <cstdio>
|
2016-12-05 14:41:00 -05:00
|
|
|
#include <map>
|
|
|
|
#include <string>
|
2016-12-22 23:18:58 -05:00
|
|
|
#include <thread>
|
2016-06-14 23:32:35 -04:00
|
|
|
|
|
|
|
#include "common.hpp"
|
2017-01-19 20:25:54 -05:00
|
|
|
#include "settings.hpp"
|
2016-06-14 23:32:35 -04:00
|
|
|
|
2017-01-10 23:10:51 -05:00
|
|
|
#ifndef STDOUT_FILENO
|
|
|
|
#define STDOUT_FILENO 1
|
|
|
|
#endif
|
|
|
|
#ifndef STDERR_FILENO
|
|
|
|
#define STDERR_FILENO 2
|
|
|
|
#endif
|
|
|
|
|
2016-11-19 00:22:44 -05:00
|
|
|
POLYBAR_NS
|
2016-06-14 23:32:35 -04:00
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
enum class loglevel : uint8_t {
|
2016-06-14 23:32:35 -04:00
|
|
|
NONE = 0,
|
|
|
|
ERROR,
|
|
|
|
WARNING,
|
|
|
|
INFO,
|
|
|
|
TRACE,
|
|
|
|
};
|
|
|
|
|
|
|
|
class logger {
|
|
|
|
public:
|
2016-12-09 03:40:46 -05:00
|
|
|
using make_type = const logger&;
|
|
|
|
static make_type make(loglevel level = loglevel::NONE);
|
2016-12-09 03:02:47 -05:00
|
|
|
|
2016-11-02 15:22:45 -04:00
|
|
|
explicit logger(loglevel level);
|
2016-06-14 23:32:35 -04:00
|
|
|
|
2016-12-09 06:22:58 -05:00
|
|
|
static loglevel parse_verbosity(const string& name, loglevel fallback = loglevel::NONE);
|
|
|
|
|
|
|
|
void verbosity(loglevel&& level);
|
2016-06-14 23:32:35 -04:00
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
#ifdef DEBUG_LOGGER // {{{
|
2016-06-14 23:32:35 -04:00
|
|
|
template <typename... Args>
|
2016-10-24 19:51:55 -04:00
|
|
|
void trace(string message, Args... args) const {
|
2016-06-14 23:32:35 -04:00
|
|
|
output(loglevel::TRACE, message, args...);
|
|
|
|
}
|
2017-01-13 05:04:43 -05:00
|
|
|
#ifdef DEBUG_LOGGER_TRACE
|
2016-10-25 07:10:34 -04:00
|
|
|
template <typename... Args>
|
|
|
|
void trace_x(string message, Args... args) const {
|
|
|
|
output(loglevel::TRACE, message, args...);
|
|
|
|
}
|
|
|
|
#else
|
2016-12-05 14:41:00 -05:00
|
|
|
template <typename... Args>
|
|
|
|
void trace_x(Args...) const {}
|
2016-10-25 07:10:34 -04:00
|
|
|
#endif
|
2016-12-05 14:41:00 -05:00
|
|
|
#else
|
|
|
|
template <typename... Args>
|
|
|
|
void trace(Args...) const {}
|
|
|
|
template <typename... Args>
|
|
|
|
void trace_x(Args...) const {}
|
|
|
|
#endif // }}}
|
2016-10-25 07:10:34 -04:00
|
|
|
|
2016-06-14 23:32:35 -04:00
|
|
|
/**
|
|
|
|
* Output an info message
|
|
|
|
*/
|
|
|
|
template <typename... Args>
|
|
|
|
void info(string message, Args... args) const {
|
|
|
|
output(loglevel::INFO, message, args...);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Output a warning message
|
|
|
|
*/
|
|
|
|
template <typename... Args>
|
|
|
|
void warn(string message, Args... args) const {
|
|
|
|
output(loglevel::WARNING, message, args...);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Output an error message
|
|
|
|
*/
|
|
|
|
template <typename... Args>
|
|
|
|
void err(string message, Args... args) const {
|
|
|
|
output(loglevel::ERROR, message, args...);
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
template <typename T>
|
|
|
|
decltype(auto) convert(T&& arg) const {
|
|
|
|
return forward<T>(arg);
|
2016-10-25 14:14:44 -04:00
|
|
|
}
|
2016-06-14 23:32:35 -04:00
|
|
|
|
|
|
|
/**
|
2016-12-22 23:18:58 -05:00
|
|
|
* Convert string
|
2016-06-14 23:32:35 -04:00
|
|
|
*/
|
2016-12-23 09:54:06 -05:00
|
|
|
const char* convert(string arg) const; // NOLINT
|
2016-12-22 23:18:58 -05:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Convert thread id
|
|
|
|
*/
|
|
|
|
size_t convert(const std::thread::id arg) const;
|
2016-06-14 23:32:35 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Write the log message to the output channel
|
|
|
|
* if the defined verbosity level allows it
|
|
|
|
*/
|
|
|
|
template <typename... Args>
|
|
|
|
void output(loglevel level, string format, Args... values) const {
|
2016-12-05 14:41:00 -05:00
|
|
|
if (level > m_level) {
|
2016-06-14 23:32:35 -04:00
|
|
|
return;
|
2016-12-05 14:41:00 -05:00
|
|
|
}
|
2016-06-14 23:32:35 -04:00
|
|
|
|
2016-12-05 14:41:00 -05:00
|
|
|
#if defined(__clang__) // {{{
|
2016-06-14 23:32:35 -04:00
|
|
|
#pragma clang diagnostic push
|
|
|
|
#pragma clang diagnostic ignored "-Wformat-security"
|
2016-10-25 16:47:21 -04:00
|
|
|
#elif defined(__GNUC__)
|
|
|
|
#pragma GCC diagnostic push
|
|
|
|
#pragma GCC diagnostic ignored "-Wformat-security"
|
2016-12-05 14:41:00 -05:00
|
|
|
#endif // }}}
|
|
|
|
|
|
|
|
dprintf(m_fd, (m_prefixes.at(level) + format + m_suffixes.at(level) + "\n").c_str(), convert(values)...);
|
|
|
|
|
|
|
|
#if defined(__clang__) // {{{
|
2016-06-14 23:32:35 -04:00
|
|
|
#pragma clang diagnostic pop
|
2016-10-25 16:47:21 -04:00
|
|
|
#elif defined(__GNUC__)
|
|
|
|
#pragma GCC diagnostic pop
|
2016-12-05 14:41:00 -05:00
|
|
|
#endif // }}}
|
2016-06-14 23:32:35 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
private:
|
|
|
|
/**
|
|
|
|
* Logger verbosity level
|
|
|
|
*/
|
2016-12-05 14:41:00 -05:00
|
|
|
loglevel m_level{loglevel::TRACE};
|
2016-06-14 23:32:35 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* File descriptor used when writing the log messages
|
|
|
|
*/
|
2016-12-05 14:41:00 -05:00
|
|
|
int m_fd{STDERR_FILENO};
|
2016-06-14 23:32:35 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Loglevel specific prefixes
|
|
|
|
*/
|
2016-12-05 14:41:00 -05:00
|
|
|
std::map<loglevel, string> m_prefixes;
|
2016-06-14 23:32:35 -04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Loglevel specific suffixes
|
|
|
|
*/
|
2016-12-05 14:41:00 -05:00
|
|
|
std::map<loglevel, string> m_suffixes;
|
2016-06-14 23:32:35 -04:00
|
|
|
};
|
|
|
|
|
2016-11-19 00:22:44 -05:00
|
|
|
POLYBAR_NS_END
|