logging.hpp 1.66 KB
Newer Older
lyz's avatar
lyz committed
1 2 3
#ifndef LOGGING_HPP
#define LOGGING_HPP

lxq's avatar
lxq committed
4
#include <cstdlib>
lyz's avatar
lyz committed
5 6 7
#include <iostream>
#include <sstream>

lxq's avatar
lxq committed
8 9 10 11
enum LogLevel { DEBUG = 0, INFO, WARNING, ERROR };
struct LocationInfo {
    LocationInfo(std::string file, int line, const char *func)
        : file_(file), line_(line), func_(func) {}
lyz's avatar
lyz committed
12 13 14 15 16 17 18 19 20
    ~LocationInfo() = default;

    std::string file_;
    int line_;
    const char *func_;
};
class LogStream;
class LogWriter;

lxq's avatar
lxq committed
21 22
class LogWriter {
  public:
lyz's avatar
lyz committed
23
    LogWriter(LocationInfo location, LogLevel loglevel)
lxq's avatar
lxq committed
24
        : location_(location), log_level_(loglevel) {
lyz's avatar
lyz committed
25
        char *logv = std::getenv("LOGV");
lxq's avatar
lxq committed
26
        if (logv) {
lyz's avatar
lyz committed
27 28
            std::string string_logv = logv;
            env_log_level = std::stoi(logv);
lxq's avatar
lxq committed
29
        } else {
lyz's avatar
lyz committed
30 31 32 33 34 35
            env_log_level = 4;
        }
    };

    void operator<(const LogStream &stream);

lxq's avatar
lxq committed
36
  private:
lyz's avatar
lyz committed
37 38 39 40 41 42
    void output_log(const std::ostringstream &g);
    LocationInfo location_;
    LogLevel log_level_;
    int env_log_level;
};

lxq's avatar
lxq committed
43 44 45
class LogStream {
  public:
    template <typename T> LogStream &operator<<(const T &val) noexcept {
lyz's avatar
lyz committed
46 47 48 49 50 51
        sstream_ << val;
        return *this;
    }

    friend class LogWriter;

lxq's avatar
lxq committed
52
  private:
lyz's avatar
lyz committed
53 54 55 56 57 58 59
    std::stringstream sstream_{};
};

std::string level2string(LogLevel level);
std::string get_short_name(const char *file_path);

#define __FILESHORTNAME__ get_short_name(__FILE__)
lxq's avatar
lxq committed
60 61 62
#define LOG_IF(level)                                                          \
    LogWriter(LocationInfo(__FILESHORTNAME__, __LINE__, __FUNCTION__),         \
              level) < LogStream()
lyz's avatar
lyz committed
63 64 65 66 67 68 69
#define LOG(level) LOG_##level
#define LOG_DEBUG LOG_IF(DEBUG)
#define LOG_INFO LOG_IF(INFO)
#define LOG_WARNING LOG_IF(WARNING)
#define LOG_ERROR LOG_IF(ERROR)

#endif