ansicolor_sink.cpp
This commit is contained in:
		
							
								
								
									
										105
									
								
								include/spdlog/impl/ansicolor_sink.cpp
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										105
									
								
								include/spdlog/impl/ansicolor_sink.cpp
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,105 @@
 | 
			
		||||
#ifdef SPDLOG_STATIC_LIB
 | 
			
		||||
#include "spdlog/sinks/ansicolor_sink.h"
 | 
			
		||||
#endif
 | 
			
		||||
 | 
			
		||||
#include "spdlog/details/os.h"
 | 
			
		||||
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
SPDLOG_INLINE spdlog::sinks::ansicolor_sink<TargetStream, ConsoleMutex>::ansicolor_sink()
 | 
			
		||||
    : target_file_(TargetStream::stream())
 | 
			
		||||
    , mutex_(ConsoleMutex::mutex())
 | 
			
		||||
 | 
			
		||||
{
 | 
			
		||||
    should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal();
 | 
			
		||||
    colors_[level::trace] = white;
 | 
			
		||||
    colors_[level::debug] = cyan;
 | 
			
		||||
    colors_[level::info] = green;
 | 
			
		||||
    colors_[level::warn] = yellow + bold;
 | 
			
		||||
    colors_[level::err] = red + bold;
 | 
			
		||||
    colors_[level::critical] = bold + on_red;
 | 
			
		||||
    colors_[level::off] = reset;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
SPDLOG_INLINE void spdlog::sinks::ansicolor_sink<TargetStream, ConsoleMutex>::set_color(
 | 
			
		||||
    level::level_enum color_level, const std::string &color)
 | 
			
		||||
{
 | 
			
		||||
    std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
    colors_[color_level] = color;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
SPDLOG_INLINE void spdlog::sinks::ansicolor_sink<TargetStream, ConsoleMutex>::log(const details::log_msg &msg)
 | 
			
		||||
{
 | 
			
		||||
    // Wrap the originally formatted message in color codes.
 | 
			
		||||
    // If color is not supported in the terminal, log as is instead.
 | 
			
		||||
    std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
 | 
			
		||||
    fmt::memory_buffer formatted;
 | 
			
		||||
    formatter_->format(msg, formatted);
 | 
			
		||||
    if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
 | 
			
		||||
    {
 | 
			
		||||
        // before color range
 | 
			
		||||
        print_range_(formatted, 0, msg.color_range_start);
 | 
			
		||||
        // in color range
 | 
			
		||||
        print_ccode_(colors_[msg.level]);
 | 
			
		||||
        print_range_(formatted, msg.color_range_start, msg.color_range_end);
 | 
			
		||||
        print_ccode_(reset);
 | 
			
		||||
        // after color range
 | 
			
		||||
        print_range_(formatted, msg.color_range_end, formatted.size());
 | 
			
		||||
    }
 | 
			
		||||
    else // no color
 | 
			
		||||
    {
 | 
			
		||||
        print_range_(formatted, 0, formatted.size());
 | 
			
		||||
    }
 | 
			
		||||
    fflush(target_file_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
SPDLOG_INLINE void spdlog::sinks::ansicolor_sink<TargetStream, ConsoleMutex>::flush()
 | 
			
		||||
{
 | 
			
		||||
    std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
    fflush(target_file_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
SPDLOG_INLINE void spdlog::sinks::ansicolor_sink<TargetStream, ConsoleMutex>::set_pattern(const std::string &pattern)
 | 
			
		||||
{
 | 
			
		||||
    std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
    formatter_ = std::unique_ptr<spdlog::formatter>(new pattern_formatter(pattern));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
SPDLOG_INLINE void spdlog::sinks::ansicolor_sink<TargetStream, ConsoleMutex>::set_formatter(
 | 
			
		||||
    std::unique_ptr<spdlog::formatter> sink_formatter)
 | 
			
		||||
{
 | 
			
		||||
    std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
    formatter_ = std::move(sink_formatter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
SPDLOG_INLINE bool spdlog::sinks::ansicolor_sink<TargetStream, ConsoleMutex>::should_color()
 | 
			
		||||
{
 | 
			
		||||
    return should_do_colors_;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
SPDLOG_INLINE void spdlog::sinks::ansicolor_sink<TargetStream, ConsoleMutex>::print_ccode_(const std::string &color_code)
 | 
			
		||||
{
 | 
			
		||||
    fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
SPDLOG_INLINE void spdlog::sinks::ansicolor_sink<TargetStream, ConsoleMutex>::print_range_(
 | 
			
		||||
    const fmt::memory_buffer &formatted, size_t start, size_t end)
 | 
			
		||||
{
 | 
			
		||||
    fwrite(formatted.data() + start, sizeof(char), end - start, target_file_);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// template instantiate stdout_mt, stdout_st
 | 
			
		||||
template class spdlog::sinks::ansicolor_sink<spdlog::details::console_stdout, spdlog::details::console_mutex>;
 | 
			
		||||
template class spdlog::sinks::ansicolor_sink<spdlog::details::console_stdout, spdlog::details::console_nullmutex>;
 | 
			
		||||
 | 
			
		||||
// template instantiate stderr_mt, stderr_st
 | 
			
		||||
template class spdlog::sinks::ansicolor_sink<spdlog::details::console_stderr, spdlog::details::console_mutex>;
 | 
			
		||||
template class spdlog::sinks::ansicolor_sink<spdlog::details::console_stderr, spdlog::details::console_nullmutex>;
 | 
			
		||||
@@ -10,45 +10,42 @@ template class spdlog::sinks::base_sink<spdlog::details::null_mutex>;
 | 
			
		||||
#include "spdlog/common.h"
 | 
			
		||||
#include "spdlog/details/pattern_formatter.h"
 | 
			
		||||
 | 
			
		||||
template <typename Mutex>
 | 
			
		||||
template<typename Mutex>
 | 
			
		||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::log(const details::log_msg &msg)
 | 
			
		||||
{
 | 
			
		||||
    std::lock_guard<Mutex> lock(mutex_);
 | 
			
		||||
    sink_it_(msg);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Mutex>
 | 
			
		||||
template<typename Mutex>
 | 
			
		||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::flush()
 | 
			
		||||
{
 | 
			
		||||
    std::lock_guard<Mutex> lock(mutex_);
 | 
			
		||||
    flush_();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Mutex>
 | 
			
		||||
template<typename Mutex>
 | 
			
		||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_pattern(const std::string &pattern)
 | 
			
		||||
{
 | 
			
		||||
    std::lock_guard<Mutex> lock(mutex_);
 | 
			
		||||
    set_pattern_(pattern);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Mutex>
 | 
			
		||||
template<typename Mutex>
 | 
			
		||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter)
 | 
			
		||||
{
 | 
			
		||||
    std::lock_guard<Mutex> lock(mutex_);
 | 
			
		||||
    set_formatter_(std::move(sink_formatter));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Mutex>
 | 
			
		||||
template<typename Mutex>
 | 
			
		||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_pattern_(const std::string &pattern)
 | 
			
		||||
{
 | 
			
		||||
    set_formatter_(details::make_unique<spdlog::pattern_formatter>(pattern));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
template <typename Mutex>
 | 
			
		||||
template<typename Mutex>
 | 
			
		||||
void SPDLOG_INLINE spdlog::sinks::base_sink<Mutex>::set_formatter_(std::unique_ptr<spdlog::formatter> sink_formatter)
 | 
			
		||||
{
 | 
			
		||||
    formatter_ = std::move(sink_formatter);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -11,9 +11,7 @@
 | 
			
		||||
 | 
			
		||||
#include "spdlog/details/console_globals.h"
 | 
			
		||||
#include "spdlog/details/null_mutex.h"
 | 
			
		||||
#include "spdlog/details/os.h"
 | 
			
		||||
#include "spdlog/sinks/sink.h"
 | 
			
		||||
 | 
			
		||||
#include <memory>
 | 
			
		||||
#include <mutex>
 | 
			
		||||
#include <string>
 | 
			
		||||
@@ -28,36 +26,22 @@ namespace sinks {
 | 
			
		||||
 * of the message.
 | 
			
		||||
 * If no color terminal detected, omit the escape codes.
 | 
			
		||||
 */
 | 
			
		||||
template<typename TargetStream, class ConsoleMutex>
 | 
			
		||||
template<typename TargetStream, typename ConsoleMutex>
 | 
			
		||||
class ansicolor_sink final : public sink
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
    using mutex_t = typename ConsoleMutex::mutex_t;
 | 
			
		||||
    ansicolor_sink()
 | 
			
		||||
        : target_file_(TargetStream::stream())
 | 
			
		||||
        , mutex_(ConsoleMutex::mutex())
 | 
			
		||||
 | 
			
		||||
    {
 | 
			
		||||
        should_do_colors_ = details::os::in_terminal(target_file_) && details::os::is_color_terminal();
 | 
			
		||||
        colors_[level::trace] = white;
 | 
			
		||||
        colors_[level::debug] = cyan;
 | 
			
		||||
        colors_[level::info] = green;
 | 
			
		||||
        colors_[level::warn] = yellow + bold;
 | 
			
		||||
        colors_[level::err] = red + bold;
 | 
			
		||||
        colors_[level::critical] = bold + on_red;
 | 
			
		||||
        colors_[level::off] = reset;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    ansicolor_sink();
 | 
			
		||||
    ~ansicolor_sink() override = default;
 | 
			
		||||
 | 
			
		||||
    ansicolor_sink(const ansicolor_sink &other) = delete;
 | 
			
		||||
    ansicolor_sink &operator=(const ansicolor_sink &other) = delete;
 | 
			
		||||
 | 
			
		||||
    void set_color(level::level_enum color_level, const std::string &color)
 | 
			
		||||
    {
 | 
			
		||||
        std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
        colors_[color_level] = color;
 | 
			
		||||
    }
 | 
			
		||||
    void set_color(level::level_enum color_level, const std::string &color);
 | 
			
		||||
    void log(const details::log_msg &msg) override;
 | 
			
		||||
    void flush() override;
 | 
			
		||||
    void set_pattern(const std::string &pattern) final;
 | 
			
		||||
    void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) override;
 | 
			
		||||
    bool should_color();
 | 
			
		||||
 | 
			
		||||
    /// Formatting codes
 | 
			
		||||
    const std::string reset = "\033[m";
 | 
			
		||||
@@ -89,70 +73,13 @@ public:
 | 
			
		||||
    const std::string on_cyan = "\033[46m";
 | 
			
		||||
    const std::string on_white = "\033[47m";
 | 
			
		||||
 | 
			
		||||
    void log(const details::log_msg &msg) override
 | 
			
		||||
    {
 | 
			
		||||
        // Wrap the originally formatted message in color codes.
 | 
			
		||||
        // If color is not supported in the terminal, log as is instead.
 | 
			
		||||
        std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
 | 
			
		||||
        fmt::memory_buffer formatted;
 | 
			
		||||
        formatter_->format(msg, formatted);
 | 
			
		||||
        if (should_do_colors_ && msg.color_range_end > msg.color_range_start)
 | 
			
		||||
        {
 | 
			
		||||
            // before color range
 | 
			
		||||
            print_range_(formatted, 0, msg.color_range_start);
 | 
			
		||||
            // in color range
 | 
			
		||||
            print_ccode_(colors_[msg.level]);
 | 
			
		||||
            print_range_(formatted, msg.color_range_start, msg.color_range_end);
 | 
			
		||||
            print_ccode_(reset);
 | 
			
		||||
            // after color range
 | 
			
		||||
            print_range_(formatted, msg.color_range_end, formatted.size());
 | 
			
		||||
        }
 | 
			
		||||
        else // no color
 | 
			
		||||
        {
 | 
			
		||||
            print_range_(formatted, 0, formatted.size());
 | 
			
		||||
        }
 | 
			
		||||
        fflush(target_file_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void flush() override
 | 
			
		||||
    {
 | 
			
		||||
        std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
        fflush(target_file_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_pattern(const std::string &pattern) final
 | 
			
		||||
    {
 | 
			
		||||
        std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
        formatter_ = std::unique_ptr<spdlog::formatter>(new pattern_formatter(pattern));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) override
 | 
			
		||||
    {
 | 
			
		||||
        std::lock_guard<mutex_t> lock(mutex_);
 | 
			
		||||
        formatter_ = std::move(sink_formatter);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool should_color()
 | 
			
		||||
    {
 | 
			
		||||
        return should_do_colors_;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    void print_ccode_(const std::string &color_code)
 | 
			
		||||
    {
 | 
			
		||||
        fwrite(color_code.data(), sizeof(char), color_code.size(), target_file_);
 | 
			
		||||
    }
 | 
			
		||||
    void print_range_(const fmt::memory_buffer &formatted, size_t start, size_t end)
 | 
			
		||||
    {
 | 
			
		||||
        fwrite(formatted.data() + start, sizeof(char), end - start, target_file_);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    FILE *target_file_;
 | 
			
		||||
    mutex_t &mutex_;
 | 
			
		||||
 | 
			
		||||
    bool should_do_colors_;
 | 
			
		||||
    std::unordered_map<level::level_enum, std::string, level::level_hasher> colors_;
 | 
			
		||||
    void print_ccode_(const std::string &color_code);
 | 
			
		||||
    void print_range_(const fmt::memory_buffer &formatted, size_t start, size_t end);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
using ansicolor_stdout_sink_mt = ansicolor_sink<details::console_stdout, details::console_mutex>;
 | 
			
		||||
@@ -162,5 +89,8 @@ using ansicolor_stderr_sink_mt = ansicolor_sink<details::console_stderr, details
 | 
			
		||||
using ansicolor_stderr_sink_st = ansicolor_sink<details::console_stderr, details::console_nullmutex>;
 | 
			
		||||
 | 
			
		||||
} // namespace sinks
 | 
			
		||||
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 | 
			
		||||
#ifndef SPDLOG_STATIC_LIB
 | 
			
		||||
#include "spdlog/impl/ansicolor_sink.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
@@ -25,7 +25,8 @@ public:
 | 
			
		||||
    base_sink(const base_sink &) = delete;
 | 
			
		||||
    base_sink &operator=(const base_sink &) = delete;
 | 
			
		||||
    void log(const details::log_msg &msg) final;
 | 
			
		||||
    void flush() final;void set_pattern(const std::string &pattern) final;
 | 
			
		||||
    void flush() final;
 | 
			
		||||
    void set_pattern(const std::string &pattern) final;
 | 
			
		||||
    void set_formatter(std::unique_ptr<spdlog::formatter> sink_formatter) final;
 | 
			
		||||
 | 
			
		||||
protected:
 | 
			
		||||
@@ -38,7 +39,6 @@ protected:
 | 
			
		||||
} // namespace sinks
 | 
			
		||||
} // namespace spdlog
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
#ifndef SPDLOG_STATIC_LIB
 | 
			
		||||
#include "spdlog/impl/base_sink.cpp"
 | 
			
		||||
#endif
 | 
			
		||||
		Reference in New Issue
	
	Block a user