2016-04-25 13:26:07 +00:00
|
|
|
#include "logging.hh"
|
|
|
|
#include "util.hh"
|
|
|
|
|
2017-05-16 14:09:57 +00:00
|
|
|
#include <atomic>
|
|
|
|
|
2016-04-25 13:26:07 +00:00
|
|
|
namespace nix {
|
|
|
|
|
2017-08-25 15:49:40 +00:00
|
|
|
thread_local ActivityId curActivity = 0;
|
|
|
|
|
2017-04-12 12:52:49 +00:00
|
|
|
Logger * logger = makeDefaultLogger();
|
2016-04-25 13:26:07 +00:00
|
|
|
|
2017-04-12 12:53:10 +00:00
|
|
|
void Logger::warn(const std::string & msg)
|
|
|
|
{
|
|
|
|
log(lvlInfo, ANSI_RED "warning:" ANSI_NORMAL " " + msg);
|
|
|
|
}
|
|
|
|
|
2016-04-25 13:26:07 +00:00
|
|
|
class SimpleLogger : public Logger
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
bool systemd, tty;
|
|
|
|
|
|
|
|
SimpleLogger()
|
|
|
|
{
|
|
|
|
systemd = getEnv("IN_SYSTEMD") == "1";
|
|
|
|
tty = isatty(STDERR_FILENO);
|
|
|
|
}
|
|
|
|
|
|
|
|
void log(Verbosity lvl, const FormatOrString & fs) override
|
|
|
|
{
|
|
|
|
if (lvl > verbosity) return;
|
|
|
|
|
|
|
|
std::string prefix;
|
|
|
|
|
|
|
|
if (systemd) {
|
|
|
|
char c;
|
|
|
|
switch (lvl) {
|
|
|
|
case lvlError: c = '3'; break;
|
|
|
|
case lvlInfo: c = '5'; break;
|
|
|
|
case lvlTalkative: case lvlChatty: c = '6'; break;
|
|
|
|
default: c = '7';
|
|
|
|
}
|
|
|
|
prefix = std::string("<") + c + ">";
|
|
|
|
}
|
|
|
|
|
|
|
|
writeToStderr(prefix + (tty ? fs.s : filterANSIEscapes(fs.s)) + "\n");
|
|
|
|
}
|
2017-08-28 17:13:24 +00:00
|
|
|
|
|
|
|
void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
|
|
|
|
const std::string & s, const Fields & fields, ActivityId parent)
|
|
|
|
{
|
|
|
|
if (lvl <= verbosity && !s.empty())
|
|
|
|
log(lvl, s + "...");
|
|
|
|
}
|
2016-04-25 13:26:07 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
Verbosity verbosity = lvlInfo;
|
|
|
|
|
|
|
|
void warnOnce(bool & haveWarned, const FormatOrString & fs)
|
|
|
|
{
|
|
|
|
if (!haveWarned) {
|
2017-04-12 12:53:10 +00:00
|
|
|
warn(fs.s);
|
2016-04-25 13:26:07 +00:00
|
|
|
haveWarned = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void writeToStderr(const string & s)
|
|
|
|
{
|
|
|
|
try {
|
2016-09-16 16:52:42 +00:00
|
|
|
writeFull(STDERR_FILENO, s, false);
|
2016-04-25 13:26:07 +00:00
|
|
|
} catch (SysError & e) {
|
2016-09-16 16:52:42 +00:00
|
|
|
/* Ignore failing writes to stderr. We need to ignore write
|
|
|
|
errors to ensure that cleanup code that logs to stderr runs
|
|
|
|
to completion if the other side of stderr has been closed
|
|
|
|
unexpectedly. */
|
2016-04-25 13:26:07 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger * makeDefaultLogger()
|
|
|
|
{
|
|
|
|
return new SimpleLogger();
|
|
|
|
}
|
|
|
|
|
2017-05-29 13:53:16 +00:00
|
|
|
std::atomic<uint64_t> nextId{(uint64_t) getpid() << 32};
|
2017-05-16 14:09:57 +00:00
|
|
|
|
2017-08-28 17:13:24 +00:00
|
|
|
Activity::Activity(Logger & logger, Verbosity lvl, ActivityType type,
|
2017-08-25 15:49:40 +00:00
|
|
|
const std::string & s, const Logger::Fields & fields, ActivityId parent)
|
2017-08-16 14:38:23 +00:00
|
|
|
: logger(logger), id(nextId++)
|
2017-08-14 20:42:17 +00:00
|
|
|
{
|
2017-08-28 17:13:24 +00:00
|
|
|
logger.startActivity(id, lvl, type, s, fields, parent);
|
2017-08-14 20:42:17 +00:00
|
|
|
}
|
|
|
|
|
2016-04-25 13:26:07 +00:00
|
|
|
}
|