From 1c9f1749d392e1bb8f312af82f945f4c7a56630d Mon Sep 17 00:00:00 2001 From: "Kevin M. Godby" Date: Tue, 15 Mar 2016 20:18:08 -0500 Subject: [PATCH 1/4] Added ANSI color sink. --- example/example.cpp | 26 +++++- include/spdlog/sinks/ansicolor_sink.h | 117 ++++++++++++++++++++++++++ 2 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 include/spdlog/sinks/ansicolor_sink.h diff --git a/example/example.cpp b/example/example.cpp index ac45bddf..44408f2b 100644 --- a/example/example.cpp +++ b/example/example.cpp @@ -5,9 +5,12 @@ // // spdlog usage example // +#include "spdlog/spdlog.h" +#include "spdlog/sinks/ansicolor_sink.h" + #include // EXIT_FAILURE #include -#include "spdlog/spdlog.h" +#include int main(int, char*[]) { @@ -85,6 +88,27 @@ int main(int, char*[]) syslog_logger->warn("This is warning that will end up in syslog. This is Linux only!"); #endif + // + // ANSI color logging (OS X and Linux. Windows only if ansi.sys is loaded.) + // + + // Create a sink to add colors to. + auto console_out = spdlog::sinks::stderr_sink_st::instance(); + auto color_sink = std::make_shared(console_out); // wraps around another sink + auto color_logger = spd::details::registry::instance().create("Color", color_sink); + color_logger->set_level(spd::level::trace); + color_sink->setColor(spd::level::info, color_sink->bold + color_sink->green); + color_logger->info("Testing color logger..."); + color_logger->trace("Trace"); + color_logger->debug("Debug"); + color_logger->info("Info"); + color_logger->notice("Notice"); + color_logger->warn("Warning"); + color_logger->error("Error"); + color_logger->critical("Critical"); + color_logger->alert("Alert"); + color_logger->emerg("Emergency"); + // //Release and close all loggers // diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h new file mode 100644 index 00000000..1bd30db6 --- /dev/null +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -0,0 +1,117 @@ +// +// Copyright(c) 2016 Kevin M. Godby. +// Distributed under the MIT License (http://opensource.org/licenses/MIT) +// + +#pragma once + +#include +#include + +#include +#include + +namespace spdlog { +namespace sinks { + +/** + * @brief The ansi_color_sink is a decorator around another sink and prefixes + * the output with an ANSI escape sequence color code depending on the severity + * of the message. + */ +class ansicolor_sink : public sink { +public: + ansicolor_sink(sink_ptr sink); + virtual ~ansicolor_sink(); + + virtual void log(const details::log_msg& msg) override; + virtual void flush() override; + + void setColor(level::level_enum level, const std::string& color); + + /// \name Formatting codes + //@{ + const std::string reset = "\033[00m"; + const std::string bold = "\033[1m"; + const std::string dark = "\033[2m"; + const std::string underline = "\033[4m"; + const std::string blink = "\033[5m"; + const std::string reverse = "\033[7m"; + const std::string concealed = "\033[8m"; + //@} + + /// \name Foreground colors + //@{ + const std::string grey = "\033[30m"; + const std::string red = "\033[31m"; + const std::string green = "\033[32m"; + const std::string yellow = "\033[33m"; + const std::string blue = "\033[34m"; + const std::string magenta = "\033[35m"; + const std::string cyan = "\033[36m"; + const std::string white = "\033[37m"; + //@} + + /// \name Background colors + //@{ + const std::string on_grey = "\033[40m"; + const std::string on_red = "\033[41m"; + const std::string on_green = "\033[42m"; + const std::string on_yellow = "\033[43m"; + const std::string on_blue = "\033[44m"; + const std::string on_magenta = "\033[45m"; + const std::string on_cyan = "\033[46m"; + const std::string on_white = "\033[47m"; + //@} + + +protected: + sink_ptr sink_; + std::map colors_ { + { level::trace, grey }, + { level::debug, white }, + { level::info, green }, + { level::notice, yellow }, + { level::warn, bold + yellow }, + { level::err, red }, + { level::critical, bold + red }, + { level::alert, bold + white + on_red }, + { level::emerg, bold + yellow + on_red }, + { level::off, reset } + }; +}; + +inline ansicolor_sink::ansicolor_sink(sink_ptr sink) : sink_(sink) +{ + // do nothing +} + +inline ansicolor_sink::~ansicolor_sink() +{ + // do nothing +} + +inline void ansicolor_sink::log(const details::log_msg& msg) +{ + // Wrap the originally formatted message in color codes + const std::string prefix = colors_[msg.level]; + const std::string s = msg.formatted.str(); + const std::string suffix = reset; + details::log_msg m; + m.formatted.write(prefix + s + suffix); + sink_->log(m); +} + +inline void ansicolor_sink::flush() +{ + sink_->flush(); +} + +inline void ansicolor_sink::setColor(level::level_enum level, const std::string& color) +{ + colors_[level] = color; +} + +} // namespace sinks +} // namespace spdlog + From e8a669fe0e478aebd34225e26fb428b8408a9e75 Mon Sep 17 00:00:00 2001 From: "Kevin M. Godby" Date: Fri, 18 Mar 2016 11:48:02 -0500 Subject: [PATCH 2/4] Remove member initialization because MSVC 2013 doesn't support it. --- include/spdlog/sinks/ansicolor_sink.h | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index 1bd30db6..d3574171 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -67,28 +67,26 @@ public: protected: sink_ptr sink_; - std::map colors_ { - { level::trace, grey }, - { level::debug, white }, - { level::info, green }, - { level::notice, yellow }, - { level::warn, bold + yellow }, - { level::err, red }, - { level::critical, bold + red }, - { level::alert, bold + white + on_red }, - { level::emerg, bold + yellow + on_red }, - { level::off, reset } - }; + std::map colors_; }; inline ansicolor_sink::ansicolor_sink(sink_ptr sink) : sink_(sink) { - // do nothing + colors_[level::trace] = grey; + colors_[level::debug] = grey; + colors_[level::info] = white; + colors_[level::notice] = yellow; + colors_[level::warn] = bold + yellow; + colors_[level::err] = red; + colors_[level::critical] = bold + red; + colors_[level::alert] = bold + white + on_red; + colors_[level::emerg] = bold + yellow + on_red; + colors_[level::off] = reset; } inline ansicolor_sink::~ansicolor_sink() { - // do nothing + flush(); } inline void ansicolor_sink::log(const details::log_msg& msg) From 9afc960d8800eb279edd84f9e4698a9808d9bac4 Mon Sep 17 00:00:00 2001 From: "Kevin M. Godby" Date: Fri, 18 Mar 2016 13:07:44 -0500 Subject: [PATCH 3/4] Enforce C++11 standard. --- CMakeLists.txt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 15553b13..a3767987 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,6 +6,9 @@ cmake_minimum_required(VERSION 3.0) project(spdlog VERSION 1.0.0) +set(CMAKE_CXX_STANDARD 11) +set(CMAKE_CXX_STANDARD_REQUIRED ON) + add_library(spdlog INTERFACE) option(SPDLOG_BUILD_EXAMPLES "Build examples" OFF) From ee610efd7d27bd28da539b02e2a76ae7c37ab3b0 Mon Sep 17 00:00:00 2001 From: "Kevin M. Godby" Date: Fri, 18 Mar 2016 13:13:06 -0500 Subject: [PATCH 4/4] Add assignment operator to ansi color sink. Adjust default colors. --- include/spdlog/sinks/ansicolor_sink.h | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/include/spdlog/sinks/ansicolor_sink.h b/include/spdlog/sinks/ansicolor_sink.h index d3574171..0b79990b 100644 --- a/include/spdlog/sinks/ansicolor_sink.h +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -24,6 +24,9 @@ public: ansicolor_sink(sink_ptr sink); virtual ~ansicolor_sink(); + ansicolor_sink(const ansicolor_sink& other); + ansicolor_sink& operator=(const ansicolor_sink& other); + virtual void log(const details::log_msg& msg) override; virtual void flush() override; @@ -72,10 +75,10 @@ protected: inline ansicolor_sink::ansicolor_sink(sink_ptr sink) : sink_(sink) { - colors_[level::trace] = grey; - colors_[level::debug] = grey; + colors_[level::trace] = white; + colors_[level::debug] = white; colors_[level::info] = white; - colors_[level::notice] = yellow; + colors_[level::notice] = bold + white; colors_[level::warn] = bold + yellow; colors_[level::err] = red; colors_[level::critical] = bold + red; @@ -89,6 +92,22 @@ inline ansicolor_sink::~ansicolor_sink() flush(); } +inline ansicolor_sink::ansicolor_sink(const ansicolor_sink& other) : sink_(other.sink_), colors_(other.colors_) +{ + // do nothing +} + + +inline ansicolor_sink& ansicolor_sink::operator=(const ansicolor_sink& other) +{ + if (this == &other) + return *this; + + sink_ = other.sink_; + colors_ = other.colors_; + return *this; +} + inline void ansicolor_sink::log(const details::log_msg& msg) { // Wrap the originally formatted message in color codes