Added (very limited) support for ansi coloring to log formatter.
This commit is contained in:
parent
8a9df15dd0
commit
c9c4eff130
@ -13,6 +13,7 @@
|
|||||||
#include "../memory/memutil.hpp"
|
#include "../memory/memutil.hpp"
|
||||||
#include "../memory/virtual_allocator.hpp"
|
#include "../memory/virtual_allocator.hpp"
|
||||||
#include "../util/annot.hpp"
|
#include "../util/annot.hpp"
|
||||||
|
#include "../util/ansi_colors.hpp"
|
||||||
#include "../util/concepts.hpp"
|
#include "../util/concepts.hpp"
|
||||||
#include "../util/string.hpp"
|
#include "../util/string.hpp"
|
||||||
|
|
||||||
@ -31,7 +32,7 @@ public:
|
|||||||
|
|
||||||
virtual ~BaseLogFormatter() noexcept = default;
|
virtual ~BaseLogFormatter() noexcept = default;
|
||||||
|
|
||||||
virtual void format(const LogMessage& message, string_t& outFormatted) noexcept = 0;
|
virtual void format(const LogMessage& message, string_t& outFormatted) = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename TChar = MIJIN_DEFAULT_CHAR_TYPE, typename TTraits = std::char_traits<TChar>,
|
template<typename TChar = MIJIN_DEFAULT_CHAR_TYPE, typename TTraits = std::char_traits<TChar>,
|
||||||
@ -44,13 +45,16 @@ public:
|
|||||||
using allocator_t = TAllocator;
|
using allocator_t = TAllocator;
|
||||||
using base_t = BaseLogFormatter<char_t, traits_t, allocator_t>;
|
using base_t = BaseLogFormatter<char_t, traits_t, allocator_t>;
|
||||||
using typename base_t::string_t;
|
using typename base_t::string_t;
|
||||||
|
using string_view_t = std::basic_string_view<char_t, traits_t>;
|
||||||
private:
|
private:
|
||||||
string_t mFormat;
|
string_t mFormat;
|
||||||
string_t mFormatBuffer;
|
string_t mFormatBuffer;
|
||||||
public:
|
public:
|
||||||
explicit BaseSimpleLogFormatter(string_t format) MIJIN_NOEXCEPT : mFormat(std::move(format)), mFormatBuffer(mFormat.get_allocator()) {}
|
explicit BaseSimpleLogFormatter(string_t format) MIJIN_NOEXCEPT : mFormat(std::move(format)), mFormatBuffer(mFormat.get_allocator()) {}
|
||||||
|
|
||||||
void format(const LogMessage& message, string_t& outFormatted) noexcept override;
|
void format(const LogMessage& message, string_t& outFormatted) override;
|
||||||
|
private:
|
||||||
|
void formatAnsiSequence(const LogMessage& message, string_view_t ansiName, string_t& outFormatted);
|
||||||
};
|
};
|
||||||
|
|
||||||
#define FORMATTER_SET_ARGS(chr_type) chr_type, std::char_traits<chr_type>, TAllocator
|
#define FORMATTER_SET_ARGS(chr_type) chr_type, std::char_traits<chr_type>, TAllocator
|
||||||
@ -114,10 +118,8 @@ MIJIN_DEFINE_CHAR_VERSIONS_TMPL(FormattingLogSink, MIJIN_FORMATTING_SINK_COMMON_
|
|||||||
#undef SINK_SET_ARGS
|
#undef SINK_SET_ARGS
|
||||||
|
|
||||||
template<typename TChar, typename TTraits, allocator_type_for<TChar> TAllocator>
|
template<typename TChar, typename TTraits, allocator_type_for<TChar> TAllocator>
|
||||||
void BaseSimpleLogFormatter<TChar, TTraits, TAllocator>::format(const LogMessage& message, string_t& outFormatted) noexcept
|
void BaseSimpleLogFormatter<TChar, TTraits, TAllocator>::format(const LogMessage& message, string_t& outFormatted)
|
||||||
{
|
{
|
||||||
using string_view_t = std::basic_string_view<char_t, traits_t>;
|
|
||||||
|
|
||||||
mFormatBuffer.clear();
|
mFormatBuffer.clear();
|
||||||
for (auto pos = mFormat.begin(); pos != mFormat.end(); ++pos)
|
for (auto pos = mFormat.begin(); pos != mFormat.end(); ++pos)
|
||||||
{
|
{
|
||||||
@ -252,6 +254,10 @@ void BaseSimpleLogFormatter<TChar, TTraits, TAllocator>::format(const LogMessage
|
|||||||
{
|
{
|
||||||
formatInline(message.level->name);
|
formatInline(message.level->name);
|
||||||
}
|
}
|
||||||
|
else if (argName == MIJIN_SMART_QUOTE(char_t, "ansi"))
|
||||||
|
{
|
||||||
|
formatAnsiSequence(message, argFormat.substr(1), outFormatted);
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
MIJIN_ERROR("Invalid format argument name.");
|
MIJIN_ERROR("Invalid format argument name.");
|
||||||
@ -263,6 +269,56 @@ void BaseSimpleLogFormatter<TChar, TTraits, TAllocator>::format(const LogMessage
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template<typename TChar, typename TTraits, allocator_type_for<TChar> TAllocator>
|
||||||
|
void BaseSimpleLogFormatter<TChar, TTraits, TAllocator>::formatAnsiSequence(const LogMessage& message, string_view_t ansiName, string_t& outFormatted)
|
||||||
|
{
|
||||||
|
std::size_t numParts = 0;
|
||||||
|
const auto formatParts = splitFixed<4>(ansiName, ",", {}, &numParts);
|
||||||
|
|
||||||
|
outFormatted += MIJIN_SMART_QUOTE(char_t, "\033[");
|
||||||
|
for (std::size_t partIdx = 0; partIdx < numParts; ++partIdx)
|
||||||
|
{
|
||||||
|
const string_view_t& part = formatParts[partIdx];
|
||||||
|
if (partIdx > 0)
|
||||||
|
{
|
||||||
|
outFormatted += MIJIN_SMART_QUOTE(char_t, ',');
|
||||||
|
}
|
||||||
|
if (part == MIJIN_SMART_QUOTE(char_t, "reset"))
|
||||||
|
{
|
||||||
|
outFormatted += BaseAnsiFontEffects<char_t>::RESET;
|
||||||
|
}
|
||||||
|
else if (part == MIJIN_SMART_QUOTE(char_t, "level_color"))
|
||||||
|
{
|
||||||
|
const int levelValue = message.level->value;
|
||||||
|
if (levelValue < MIJIN_LOG_LEVEL_VALUE_VERBOSE)
|
||||||
|
{
|
||||||
|
outFormatted += BaseAnsiFontEffects<char_t>::FG_CYAN;
|
||||||
|
}
|
||||||
|
else if (levelValue < MIJIN_LOG_LEVEL_VALUE_INFO)
|
||||||
|
{
|
||||||
|
outFormatted += BaseAnsiFontEffects<char_t>::FG_WHITE;
|
||||||
|
}
|
||||||
|
else if (levelValue < MIJIN_LOG_LEVEL_VALUE_WARNING)
|
||||||
|
{
|
||||||
|
outFormatted += BaseAnsiFontEffects<char_t>::FG_BRIGHT_WHITE;
|
||||||
|
}
|
||||||
|
else if (levelValue < MIJIN_LOG_LEVEL_VALUE_ERROR)
|
||||||
|
{
|
||||||
|
outFormatted += BaseAnsiFontEffects<char_t>::FG_YELLOW;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
outFormatted += BaseAnsiFontEffects<char_t>::FG_RED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MIJIN_ERROR("Invalid format ansi font effect name.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
outFormatted += MIJIN_SMART_QUOTE(char_t, 'm');
|
||||||
|
}
|
||||||
} // namespace mijin
|
} // namespace mijin
|
||||||
|
|
||||||
#endif // !defined(MIJIN_LOGGING_FORMATTING_HPP_INCLUDED)
|
#endif // !defined(MIJIN_LOGGING_FORMATTING_HPP_INCLUDED)
|
||||||
|
@ -11,7 +11,7 @@ namespace mijin
|
|||||||
{
|
{
|
||||||
template<MIJIN_FORMATTING_SINK_TMPL_ARGS_INIT>
|
template<MIJIN_FORMATTING_SINK_TMPL_ARGS_INIT>
|
||||||
requires(allocator_type<TAllocator<TChar>>)
|
requires(allocator_type<TAllocator<TChar>>)
|
||||||
class StdioSink : public BaseFormattingLogSink<MIJIN_FORMATTING_SINK_TMP_ARG_NAMES>
|
class BaseStdioSink : public BaseFormattingLogSink<MIJIN_FORMATTING_SINK_TMP_ARG_NAMES>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
using base_t = BaseFormattingLogSink<MIJIN_FORMATTING_SINK_TMP_ARG_NAMES>;
|
using base_t = BaseFormattingLogSink<MIJIN_FORMATTING_SINK_TMP_ARG_NAMES>;
|
||||||
@ -20,12 +20,18 @@ public:
|
|||||||
using typename base_t::formatter_ptr_t;
|
using typename base_t::formatter_ptr_t;
|
||||||
using typename base_t::message_t;
|
using typename base_t::message_t;
|
||||||
private:
|
private:
|
||||||
int mMinStderrLevel;
|
int mMinStderrLevel = MIJIN_LOG_LEVEL_VALUE_WARNING;
|
||||||
public:
|
public:
|
||||||
explicit StdioSink(not_null_t<formatter_ptr_t> formatter, allocator_t allocator = {},
|
explicit BaseStdioSink(not_null_t<formatter_ptr_t> formatter, allocator_t allocator = {})
|
||||||
int minStderrLevel = MIJIN_LOG_LEVEL_VALUE_WARNING)
|
|
||||||
MIJIN_NOEXCEPT_IF(std::is_nothrow_move_constructible_v<allocator_t>)
|
MIJIN_NOEXCEPT_IF(std::is_nothrow_move_constructible_v<allocator_t>)
|
||||||
: base_t(std::move(formatter), std::move(allocator)), mMinStderrLevel(minStderrLevel) {}
|
: base_t(std::move(formatter), std::move(allocator)) {}
|
||||||
|
|
||||||
|
[[nodiscard]]
|
||||||
|
int getMinStderrLevel() const MIJIN_NOEXCEPT { return mMinStderrLevel; }
|
||||||
|
|
||||||
|
void setMinStderrLevel(int level) MIJIN_NOEXCEPT { mMinStderrLevel = level; }
|
||||||
|
|
||||||
|
void setMinStderrLevel(const BaseLogLevel<char_t>& level) MIJIN_NOEXCEPT { mMinStderrLevel = level.value; }
|
||||||
|
|
||||||
void handleMessageFormatted(const message_t& message, const char_t* formatted) MIJIN_NOEXCEPT override
|
void handleMessageFormatted(const message_t& message, const char_t* formatted) MIJIN_NOEXCEPT override
|
||||||
{
|
{
|
||||||
@ -52,6 +58,12 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define SINK_SET_ARGS(chr_type) chr_type, std::char_traits<chr_type>, TAllocator, TDeleter
|
||||||
|
|
||||||
|
MIJIN_DEFINE_CHAR_VERSIONS_TMPL(StdioSink, MIJIN_FORMATTING_SINK_COMMON_ARGS, SINK_SET_ARGS)
|
||||||
|
|
||||||
|
#undef SINK_SET_ARGS
|
||||||
} // namespace mijin
|
} // namespace mijin
|
||||||
|
|
||||||
|
|
||||||
|
55
source/mijin/util/ansi_colors.hpp
Normal file
55
source/mijin/util/ansi_colors.hpp
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#if !defined(MIJIN_UTIL_ANSI_COLORS_HPP_INCLUDED)
|
||||||
|
#define MIJIN_UTIL_ANSI_COLORS_HPP_INCLUDED 1
|
||||||
|
|
||||||
|
#include "../internal/common.hpp"
|
||||||
|
|
||||||
|
namespace mijin
|
||||||
|
{
|
||||||
|
template<typename TChar = MIJIN_DEFAULT_CHAR_TYPE>
|
||||||
|
struct BaseAnsiFontEffects
|
||||||
|
{
|
||||||
|
using char_t = TChar;
|
||||||
|
|
||||||
|
static constexpr const char_t* RESET = MIJIN_SMART_QUOTE(char_t, "0");
|
||||||
|
|
||||||
|
static constexpr const char_t* FG_BLACK = MIJIN_SMART_QUOTE(char_t, "30");
|
||||||
|
static constexpr const char_t* FG_RED = MIJIN_SMART_QUOTE(char_t, "31");
|
||||||
|
static constexpr const char_t* FG_GREEN = MIJIN_SMART_QUOTE(char_t, "32");
|
||||||
|
static constexpr const char_t* FG_YELLOW = MIJIN_SMART_QUOTE(char_t, "33");
|
||||||
|
static constexpr const char_t* FG_BLUE = MIJIN_SMART_QUOTE(char_t, "34");
|
||||||
|
static constexpr const char_t* FG_MAGENTA = MIJIN_SMART_QUOTE(char_t, "35");
|
||||||
|
static constexpr const char_t* FG_CYAN = MIJIN_SMART_QUOTE(char_t, "36");
|
||||||
|
static constexpr const char_t* FG_WHITE = MIJIN_SMART_QUOTE(char_t, "37");
|
||||||
|
static constexpr const char_t* FG_BRIGHT_BLACK = MIJIN_SMART_QUOTE(char_t, "90");
|
||||||
|
static constexpr const char_t* FG_BRIGHT_RED = MIJIN_SMART_QUOTE(char_t, "91");
|
||||||
|
static constexpr const char_t* FG_BRIGHT_GREEN = MIJIN_SMART_QUOTE(char_t, "92");
|
||||||
|
static constexpr const char_t* FG_BRIGHT_YELLOW = MIJIN_SMART_QUOTE(char_t, "93");
|
||||||
|
static constexpr const char_t* FG_BRIGHT_BLUE = MIJIN_SMART_QUOTE(char_t, "94");
|
||||||
|
static constexpr const char_t* FG_BRIGHT_MAGENTA = MIJIN_SMART_QUOTE(char_t, "95");
|
||||||
|
static constexpr const char_t* FG_BRIGHT_CYAN = MIJIN_SMART_QUOTE(char_t, "96");
|
||||||
|
static constexpr const char_t* FG_BRIGHT_WHITE = MIJIN_SMART_QUOTE(char_t, "97");
|
||||||
|
|
||||||
|
static constexpr const char_t* BG_BLACK = MIJIN_SMART_QUOTE(char_t, "40");
|
||||||
|
static constexpr const char_t* BG_RED = MIJIN_SMART_QUOTE(char_t, "41");
|
||||||
|
static constexpr const char_t* BG_GREEN = MIJIN_SMART_QUOTE(char_t, "42");
|
||||||
|
static constexpr const char_t* BG_YELLOW = MIJIN_SMART_QUOTE(char_t, "43");
|
||||||
|
static constexpr const char_t* BG_BLUE = MIJIN_SMART_QUOTE(char_t, "44");
|
||||||
|
static constexpr const char_t* BG_MAGENTA = MIJIN_SMART_QUOTE(char_t, "45");
|
||||||
|
static constexpr const char_t* BG_CYAN = MIJIN_SMART_QUOTE(char_t, "46");
|
||||||
|
static constexpr const char_t* BG_WHITE = MIJIN_SMART_QUOTE(char_t, "47");
|
||||||
|
static constexpr const char_t* BG_BRIGHT_BLACK = MIJIN_SMART_QUOTE(char_t, "100");
|
||||||
|
static constexpr const char_t* BG_BRIGHT_RED = MIJIN_SMART_QUOTE(char_t, "101");
|
||||||
|
static constexpr const char_t* BG_BRIGHT_GREEN = MIJIN_SMART_QUOTE(char_t, "102");
|
||||||
|
static constexpr const char_t* BG_BRIGHT_YELLOW = MIJIN_SMART_QUOTE(char_t, "103");
|
||||||
|
static constexpr const char_t* BG_BRIGHT_BLUE = MIJIN_SMART_QUOTE(char_t, "104");
|
||||||
|
static constexpr const char_t* BG_BRIGHT_MAGENTA = MIJIN_SMART_QUOTE(char_t, "105");
|
||||||
|
static constexpr const char_t* BG_BRIGHT_CYAN = MIJIN_SMART_QUOTE(char_t, "106");
|
||||||
|
static constexpr const char_t* BG_BRIGHT_WHITE = MIJIN_SMART_QUOTE(char_t, "107");
|
||||||
|
};
|
||||||
|
MIJIN_DEFINE_CHAR_VERSIONS(AnsiFontEffects)
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // !defined(MIJIN_UTIL_ANSI_COLORS_HPP_INCLUDED)
|
Loading…
x
Reference in New Issue
Block a user