From 3d5b1032a193419cfa7406f0e42a7621994d70af Mon Sep 17 00:00:00 2001 From: Ben Burdette Date: Fri, 17 Apr 2020 15:07:44 -0600 Subject: [PATCH] logError, logWarning; Logger functions; switch to Verbosity enum --- src/error-demo/error-demo.cc | 67 ++++++++++++++++++------------------ src/libstore/daemon.cc | 4 +++ src/libutil/error.cc | 50 +++++++++++++++++++-------- src/libutil/error.hh | 19 +++++----- src/libutil/logging.cc | 18 ++++++++++ src/libutil/logging.hh | 30 ++++++++++------ src/nix/progress-bar.cc | 6 ++++ 7 files changed, 128 insertions(+), 66 deletions(-) diff --git a/src/error-demo/error-demo.cc b/src/error-demo/error-demo.cc index a9ff6057c..b7dd4cc22 100644 --- a/src/error-demo/error-demo.cc +++ b/src/error-demo/error-demo.cc @@ -1,4 +1,4 @@ -#include "error.hh" +#include "logging.hh" #include "nixexpr.hh" #include @@ -8,24 +8,25 @@ int main() { using namespace nix; + std::unique_ptr logger(makeDefaultLogger()); + + verbosity = lvlError; + // In each program where errors occur, this has to be set. ErrorInfo::programName = std::optional("error-demo"); // Error in a program; no hint and no nix code. - printErrorInfo( - ErrorInfo { .level = elError, - .name = "name", + logError( + ErrorInfo { .name = "name", .description = "error description", }); // Warning with name, description, and hint. // The hintfmt function makes all the substituted text yellow. - printErrorInfo( - ErrorInfo { .level = elWarning, - .name = "name", + logWarning( + ErrorInfo { .name = "name", .description = "error description", - .hint = std::optional( - hintfmt("there was a %1%", "warning")), + .hint = hintfmt("there was a %1%", "warning"), }); @@ -34,32 +35,32 @@ int main() SymbolTable testTable; auto problem_file = testTable.create("myfile.nix"); - printErrorInfo( - ErrorInfo{ - .level = elWarning, - .name = "warning name", - .description = "warning description", - .hint = hintfmt("this hint has %1% templated %2%!!", "yellow", "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13), - .prevLineOfCode = std::nullopt, - .errLineOfCode = "this is the problem line of code", - .nextLineOfCode = std::nullopt - }}); + logWarning( + ErrorInfo { .name = "warning name", + .description = "warning description", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = std::nullopt, + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = std::nullopt + }}); // Error with previous and next lines of code. - printErrorInfo( - ErrorInfo{ - .level = elError, - .name = "error name", - .description = "error description", - .hint = hintfmt("this hint has %1% templated %2%!!", "yellow", "values"), - .nixCode = NixCode { - .errPos = Pos(problem_file, 40, 13), - .prevLineOfCode = std::optional("previous line of code"), - .errLineOfCode = "this is the problem line of code", - .nextLineOfCode = std::optional("next line of code"), - }}); + logError( + ErrorInfo { .name = "error name", + .description = "error description", + .hint = hintfmt("this hint has %1% templated %2%!!", + "yellow", + "values"), + .nixCode = NixCode { + .errPos = Pos(problem_file, 40, 13), + .prevLineOfCode = std::optional("previous line of code"), + .errLineOfCode = "this is the problem line of code", + .nextLineOfCode = std::optional("next line of code"), + }}); return 0; diff --git a/src/libstore/daemon.cc b/src/libstore/daemon.cc index 8e9f9d71b..c8daef57c 100644 --- a/src/libstore/daemon.cc +++ b/src/libstore/daemon.cc @@ -73,6 +73,10 @@ struct TunnelLogger : public Logger enqueueMsg(*buf.s); } + void logEI(const ErrorInfo & ei) override + { + } + /* startWork() means that we're starting an operation for which we want to send out stderr to the client. */ void startWork() diff --git a/src/libutil/error.cc b/src/libutil/error.cc index a5571d4ec..779f519c0 100644 --- a/src/libutil/error.cc +++ b/src/libutil/error.cc @@ -2,6 +2,7 @@ #include #include +#include "serialise.hh" namespace nix { @@ -66,25 +67,45 @@ void printCodeLines(const string &prefix, const NixCode &nixCode) } } -void printErrorInfo(const ErrorInfo &einfo) +std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo) { int errwidth = 80; string prefix = " "; string levelString; switch (einfo.level) { - case ErrLevel::elError: { + case Verbosity::lvlError: { levelString = ANSI_RED; levelString += "error:"; levelString += ANSI_NORMAL; break; } - case ErrLevel::elWarning: { + case Verbosity::lvlWarn: { levelString = ANSI_YELLOW; levelString += "warning:"; levelString += ANSI_NORMAL; break; } + case Verbosity::lvlInfo: { + levelString = ANSI_YELLOW; + levelString += "info:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlTalkative: + case Verbosity::lvlChatty: + case Verbosity::lvlVomit: { + levelString = ANSI_GREEN; + levelString += "info:"; + levelString += ANSI_NORMAL; + break; + } + case Verbosity::lvlDebug: { + levelString = ANSI_YELLOW; + levelString += "debug:"; + levelString += ANSI_NORMAL; + break; + } default: { levelString = fmt("invalid error level: %1%", einfo.level); break; @@ -99,7 +120,7 @@ void printErrorInfo(const ErrorInfo &einfo) dashes.append("-"); // divider. - std::cout << fmt("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL, + out << fmt("%1%%2%" ANSI_BLUE " %3% %4% %5% %6%" ANSI_NORMAL, prefix, levelString, "---", @@ -115,32 +136,33 @@ void printErrorInfo(const ErrorInfo &einfo) ? string(" ") + showErrPos(einfo.nixCode->errPos) : ""; - std::cout << fmt("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL, + out << fmt("%1%in file: " ANSI_BLUE "%2%%3%" ANSI_NORMAL, prefix, einfo.nixCode->errPos.nixFile, eline) << std::endl; - std::cout << prefix << std::endl; + out << prefix << std::endl; } else { - std::cout << fmt("%1%from command line argument", prefix) << std::endl; - std::cout << prefix << std::endl; + out << fmt("%1%from command line argument", prefix) << std::endl; + out << prefix << std::endl; } } // description - std::cout << prefix << einfo.description << std::endl; - std::cout << prefix << std::endl; + out << prefix << einfo.description << std::endl; + out << prefix << std::endl; // lines of code. if (einfo.nixCode->errLineOfCode != "") { printCodeLines(prefix, *einfo.nixCode); - std::cout << prefix << std::endl; + out << prefix << std::endl; } // hint if (einfo.hint.has_value()) { - std::cout << prefix << *einfo.hint << std::endl; - std::cout << prefix << std::endl; + out << prefix << *einfo.hint << std::endl; + out << prefix << std::endl; } -} + return out; +} } diff --git a/src/libutil/error.hh b/src/libutil/error.hh index f402b692e..0419a1b52 100644 --- a/src/libutil/error.hh +++ b/src/libutil/error.hh @@ -11,9 +11,14 @@ namespace nix { typedef enum { - elWarning, - elError -} ErrLevel; + lvlError = 0, + lvlWarn, + lvlInfo, + lvlTalkative, + lvlChatty, + lvlDebug, + lvlVomit +} Verbosity; struct ErrPos { @@ -101,7 +106,7 @@ inline hintformat hintfmt(const std::string & fs, const Args & ... args) // ErrorInfo. struct ErrorInfo { - ErrLevel level; + Verbosity level; string name; string description; std::optional hint; @@ -110,11 +115,7 @@ struct ErrorInfo static std::optional programName; }; -// -------------------------------------------------------- -// error printing - -// just to cout for now. -void printErrorInfo(const ErrorInfo &einfo); +std::ostream& operator<<(std::ostream &out, const ErrorInfo &einfo); } diff --git a/src/libutil/logging.cc b/src/libutil/logging.cc index fa5c84a27..98f500a65 100644 --- a/src/libutil/logging.cc +++ b/src/libutil/logging.cc @@ -3,6 +3,7 @@ #include #include +#include namespace nix { @@ -57,6 +58,14 @@ public: writeToStderr(prefix + filterANSIEscapes(fs.s, !tty) + "\n"); } + void logEI(const ErrorInfo & ei) override + { + std::stringstream oss; + oss << ei; + + log(ei.level, oss.str()); + } + void startActivity(ActivityId act, Verbosity lvl, ActivityType type, const std::string & s, const Fields & fields, ActivityId parent) override @@ -135,6 +144,15 @@ struct JSONLogger : Logger write(json); } + void logEI(const ErrorInfo & ei) override + { + // nlohmann::json json; + // json["action"] = "msg"; + // json["level"] = lvl; + // json["msg"] = fs.s; + // write(json); + } + void startActivity(ActivityId act, Verbosity lvl, ActivityType type, const std::string & s, const Fields & fields, ActivityId parent) override { diff --git a/src/libutil/logging.hh b/src/libutil/logging.hh index beb5e6b64..ba6f39ac9 100644 --- a/src/libutil/logging.hh +++ b/src/libutil/logging.hh @@ -1,19 +1,10 @@ #pragma once #include "types.hh" +#include "error.hh" namespace nix { -typedef enum { - lvlError = 0, - lvlWarn, - lvlInfo, - lvlTalkative, - lvlChatty, - lvlDebug, - lvlVomit -} Verbosity; - typedef enum { actUnknown = 0, actCopyPath = 100, @@ -70,6 +61,13 @@ public: log(lvlInfo, fs); } + virtual void logEI(const ErrorInfo &ei) = 0; + + void logEI(Verbosity lvl, ErrorInfo ei) { + ei.level = lvl; + logEI(ei); + } + virtual void warn(const std::string & msg); virtual void startActivity(ActivityId act, Verbosity lvl, ActivityType type, @@ -157,6 +155,18 @@ extern Verbosity verbosity; /* suppress msgs > this */ #define debug(args...) printMsg(lvlDebug, args) #define vomit(args...) printMsg(lvlVomit, args) +#define logErrorInfo(level, errorInfo...) \ + do { \ + if (level <= nix::verbosity) { \ + logger->logEI(level, errorInfo); \ + } \ + } while (0) + +#define logError(errorInfo...) logErrorInfo(lvlError, errorInfo) +#define logWarning(errorInfo...) logErrorInfo(lvlWarn, errorInfo) + + + template inline void warn(const std::string & fs, const Args & ... args) { diff --git a/src/nix/progress-bar.cc b/src/nix/progress-bar.cc index 26631416c..41f3d4cd7 100644 --- a/src/nix/progress-bar.cc +++ b/src/nix/progress-bar.cc @@ -124,6 +124,12 @@ public: log(*state, lvl, fs.s); } + void logEI(const ErrorInfo &ei) override + { + auto state(state_.lock()); + // log(*state, lvl, ei.as_str()); + } + void log(State & state, Verbosity lvl, const std::string & s) { if (state.active) {