From 60b65a9a245c9344d012238be4b2cf0a7699a8c3 Mon Sep 17 00:00:00 2001 From: Danny Robson Date: Mon, 21 Mar 2016 14:21:14 +1100 Subject: [PATCH] log: add ANSI colours to output --- log.cpp | 111 ++++++++++++++++++++++++++++++++++++++++++++++++-------- log.hpp | 8 +++- 2 files changed, 103 insertions(+), 16 deletions(-) diff --git a/log.cpp b/log.cpp index b398aa02..a2d8dc3a 100644 --- a/log.cpp +++ b/log.cpp @@ -18,14 +18,33 @@ #include "log.hpp" #include "debug.hpp" -#include "types.hpp" +#include "term.hpp" #include "time.hpp" +#include "types.hpp" #include #include #include #include #include +#include + + +/////////////////////////////////////////////////////////////////////////////// +static +const util::level_t +ALL_LEVELS[] = { + util::EMERGENCY, + util::ALERT, + util::CRITICAL, + util::ERROR, + util::WARN, + util::WARN, + util::NOTICE, + util::INFO, + util::INFO, + util::DEBUG, +}; /////////////////////////////////////////////////////////////////////////////// @@ -59,23 +78,31 @@ to_level (std::string name) } +/////////////////////////////////////////////////////////////////////////////// +const std::string& +util::to_string (level_t l) +{ + switch (l) { + #define CASE(L) \ + case util::L: { \ + static const std::string STR = #L; \ + return STR; \ + } + + MAP_LEVEL_T(CASE) + + #undef CASE + } + + unreachable (); +} + + //----------------------------------------------------------------------------- std::ostream& util::operator<< (std::ostream& os, util::level_t l) { - switch (l) { - case util::EMERGENCY: return os << "EMERGENCY"; - case util::ALERT: return os << "ALERT"; - case util::CRITICAL: return os << "CRITICAL"; - case util::ERROR: return os << "ERROR"; - case util::WARNING: return os << "WARNING"; - case util::NOTICE: return os << "NOTICE"; - case util::INFORMATIONAL: return os << "INFO"; - case util::DEBUG: return os << "DEBUG"; - - default: - unreachable (); - } + return os << to_string (l); } @@ -117,6 +144,53 @@ needs_break (util::level_t level) } +//----------------------------------------------------------------------------- +static +util::term::csi::graphics +level_colour (util::level_t level) +{ + using util::term::csi::graphics; + + switch (level) { + case util::EMERGENCY: + case util::ALERT: + case util::CRITICAL: + case util::ERROR: + return graphics (graphics::FOREGROUND, graphics::RED); + + case util::WARNING: + return graphics (graphics::FOREGROUND, graphics::YELLOW); + + case util::NOTICE: + case util::INFORMATIONAL: + return graphics (graphics::FOREGROUND, graphics::GREEN); + + case util::DEBUG: + return graphics (graphics::FOREGROUND, graphics::WHITE); + } + + unreachable (); +} + + +//----------------------------------------------------------------------------- +static +size_t +level_width (void) +{ + static size_t width = [] { + size_t hi = 0; + + for (auto i: ALL_LEVELS) + hi = util::max (to_string (i).size (), hi); + + return hi; + } (); + + return width; +} + + /////////////////////////////////////////////////////////////////////////////// void util::log (util::level_t level, const std::string &msg) @@ -141,7 +215,14 @@ util::log (util::level_t level, const std::string &msg) return; } - std::cerr << time_string << " [" << level << "] " << msg << std::endl; + std::cerr << time_string << " [" + << level_colour (level) + << std::setw (level_width ()) + << std::left + << level + << std::setw (0) + << util::term::csi::graphics::RESET + << "] " << msg << std::endl; } diff --git a/log.hpp b/log.hpp index 26f1c7cf..505df6d3 100644 --- a/log.hpp +++ b/log.hpp @@ -17,7 +17,8 @@ #ifndef __UTIL_LOG_HPP #define __UTIL_LOG_HPP -#include "nocopy.hpp" +#include "./nocopy.hpp" +#include "./preprocessor.hpp" #include #include @@ -45,8 +46,13 @@ namespace util { DEBUG /** debug-level messages */ }; + #define MAP_LEVEL_T(F) MAP(F, EMERGENCY, ALERT, CRITICAL, ERROR, WARN, NOTICE, INFO, DEBUG) + constexpr auto DEFAULT_LOG_LEVEL = INFO; + //------------------------------------------------------------------------- + const std::string& to_string (level_t); + //------------------------------------------------------------------------- std::ostream& operator<< (std::ostream&, level_t);