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) 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..0b79990b --- /dev/null +++ b/include/spdlog/sinks/ansicolor_sink.h @@ -0,0 +1,134 @@ +// +// 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(); + + 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; + + 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_; +}; + +inline ansicolor_sink::ansicolor_sink(sink_ptr sink) : sink_(sink) +{ + colors_[level::trace] = white; + colors_[level::debug] = white; + colors_[level::info] = white; + colors_[level::notice] = bold + white; + 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() +{ + 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 + 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 +