FeatherMC/src/logging/Logger.h

162 lines
4.6 KiB
C
Raw Normal View History

2020-07-29 02:43:59 +01:00
#pragma once
2020-08-07 06:23:12 +01:00
#include <event2/event.h>
#define FMT_HEADER_ONLY
#include <fmt/core.h>
#include <fmt/color.h>
#include <ostream>
#include <vector>
#include <array>
2020-07-29 05:32:35 +01:00
2020-08-07 06:23:12 +01:00
//#define FEATHER_Log::COLUMNS
2020-07-29 05:32:35 +01:00
2020-08-07 06:23:12 +01:00
namespace Feather::Log
{
2020-07-29 02:43:59 +01:00
enum class Level
{
// Serious problems
Error = -2,
2020-07-29 02:43:59 +01:00
// Potential problems of note
Warning = -1,
2020-07-29 02:43:59 +01:00
// General messages for end-users
Info = 0,
2020-07-29 02:43:59 +01:00
// More advanced information for problem-solving
Debug = 1,
2020-07-29 02:43:59 +01:00
// Fine grained spew
Trace = 2,
2020-07-29 02:43:59 +01:00
};
2020-08-07 06:23:12 +01:00
constexpr std::string_view GetLevelStringView(Level level)
{
switch (level)
{
case Level::Error: return "Error";
case Level::Warning: return "Warning";
case Level::Info: return "Info";
case Level::Debug: return "Debug";
case Level::Trace: return "Trace";
default: return "Unknown";
}
}
constexpr size_t MaxLevelLength = 7;
constexpr size_t MaxChannelLength = 15;
inline std::ostream& operator << (std::ostream& os, Level level)
{
os << GetLevelStringView(level);
return os;
}
2020-07-29 05:32:35 +01:00
2020-08-07 06:23:12 +01:00
constexpr fmt::text_style GetLevelTextStyle(Level level)
{
switch (level)
{
default:
case Level::Info: return fmt::fg(fmt::color::white);
case Level::Error: return fmt::fg(fmt::color::crimson);
case Level::Warning: return fmt::fg(fmt::color::yellow);
case Level::Debug: return fmt::fg(fmt::color::rebecca_purple);
case Level::Trace: return fmt::fg(fmt::color::aquamarine);
}
}
using ChannelID = size_t;
2020-07-29 05:32:35 +01:00
2020-07-29 02:43:59 +01:00
class Channel
2020-07-29 05:32:35 +01:00
{
public:
2020-08-07 06:23:12 +01:00
Channel(std::string_view name) : m_name(name) {}
2020-07-29 02:43:59 +01:00
2020-08-07 06:23:12 +01:00
inline std::string_view GetName() { return m_name; }
2020-07-29 02:43:59 +01:00
2020-08-07 06:23:12 +01:00
private:
std::string_view m_name;
};
2020-07-29 05:32:35 +01:00
2020-08-07 06:23:12 +01:00
namespace Channels
{
extern ChannelID General;
}
2020-07-29 02:43:59 +01:00
class Logger
{
public:
2020-08-07 06:23:12 +01:00
template <class S, typename... Args>
void LogRaw(const fmt::text_style& style, const S& fmt, Args... args)
{
fmt::print(style, fmt, args...);
}
template <class S, typename... Args>
void LogRaw(const S& fmt, Args... args)
{
constexpr fmt::text_style white = fmt::fg(fmt::color::white);
LogRaw(white, fmt, args...);
}
template <class S, typename... Args>
void Log(ChannelID channel, Level level, const S& fmt, Args... args)
{
std::string_view levelString = GetLevelStringView(level);
std::string_view channelString = m_channels[channel].GetName();
#ifdef FEATHER_Log::COLUMNS
std::array<char, MaxLevelLength + 1> levelSpaces = {};
std::fill_n(levelSpaces.data(), MaxLevelLength - levelString.size(), ' ');
std::array<char, MaxChannelLength> channelSpaces = {};
std::fill_n(channelSpaces.data(), MaxChannelLength - channelString.size(), ' ');
LogRaw(GetLevelTextStyle(level), levelString);
LogRaw("{}|", levelSpaces.data());
LogRaw(channelString);
LogRaw("{}|", channelSpaces.data());
LogRaw(fmt, args...);
LogRaw("\n");
#else
if (channel != Channels::General)
LogRaw("[{}] ", channelString);
LogRaw("[");
LogRaw(GetLevelTextStyle(level), levelString);
LogRaw("] ");
LogRaw(fmt, args...);
LogRaw("\n");
#endif
}
2020-07-29 05:32:35 +01:00
ChannelID RegisterChannel(const char* name);
2020-08-07 06:23:12 +01:00
static Logger& Instance();
2020-07-29 05:32:35 +01:00
private:
2020-08-07 06:23:12 +01:00
std::vector<Channel> m_channels;
2020-07-29 02:43:59 +01:00
};
2020-08-07 06:23:12 +01:00
template <class S, typename... Args>
void Msg(ChannelID channel, Level level, const S& fmt, Args... args)
{
Logger::Instance().Log(channel, level, fmt, args...);
}
2020-07-29 02:43:59 +01:00
2020-08-07 06:23:12 +01:00
template <class S, typename... Args>
void Info(const S& fmt, Args... args) { Msg(Channels::General, Level::Info, fmt, args...); }
2020-07-29 05:37:22 +01:00
2020-08-07 06:23:12 +01:00
template <class S, typename... Args>
void Warn(const S& fmt, Args... args) { Msg(Channels::General, Level::Warning, fmt, args...); }
2020-07-29 05:37:22 +01:00
2020-08-07 06:23:12 +01:00
template <class S, typename... Args>
void Error(const S& fmt, Args... args) { Msg(Channels::General, Level::Error, fmt, args...); }
2020-07-29 05:37:22 +01:00
2020-08-07 06:23:12 +01:00
template <class S, typename... Args>
void Debug(const S& fmt, Args... args) { Msg(Channels::General, Level::Debug, fmt, args...); }
2020-07-29 05:37:22 +01:00
2020-08-07 06:23:12 +01:00
template <class S, typename... Args>
void Trace(const S& fmt, Args... args) { Msg(Channels::General, Level::Trace, fmt, args...); }
}