Nix 2.93.3
Lix: A modern, delicious implementation of the Nix package manager; unstable internal interfaces
Loading...
Searching...
No Matches
logging.hh
Go to the documentation of this file.
1#pragma once
3
7
8namespace nix {
9
10typedef enum {
11 actUnknown = 0,
12 actCopyPath = 100,
13 actFileTransfer = 101,
14 actRealise = 102,
15 actCopyPaths = 103,
16 actBuilds = 104,
17
24 actBuild = 105,
25 actOptimiseStore = 106,
26 actVerifyPaths = 107,
27
33
39
44 actBuildWaiting = 111,
45} ActivityType;
46
47template<>
48struct json::is_integral_enum<ActivityType> : std::true_type {};
49
50typedef enum {
55
60 resUntrustedPath = 102,
61 resCorruptedPath = 103,
62
67
75
81
86} ResultType;
87
88template<>
89struct json::is_integral_enum<ResultType> : std::true_type {};
90
91typedef uint64_t ActivityId;
92
93struct LoggerSettings : Config
94{
95 #include "logging-settings.gen.inc"
96};
97
98extern LoggerSettings loggerSettings;
99
101{
102 friend struct Activity;
103
104public:
105
106 struct Field
107 {
108 // FIXME: use std::variant.
109 enum { tInt = 0, tString = 1 } type;
110 uint64_t i = 0;
111 std::string s;
112 Field(const std::string & s) : type(tString), s(s) { }
113 Field(const char * s) : type(tString), s(s) { }
114 Field(const uint64_t & i) : type(tInt), i(i) { }
115 };
116
117 typedef std::vector<Field> Fields;
118
119 virtual ~Logger() { }
120
121 virtual void pause() { };
122 virtual void resetProgress() { };
123 virtual void resume() { };
124
125 // Whether the logger prints the whole build log
126 virtual bool isVerbose() { return false; }
127
128 virtual void log(Verbosity lvl, std::string_view s) = 0;
129
130 void log(std::string_view s)
131 {
132 log(lvlInfo, s);
133 }
134
135 virtual void logEI(const ErrorInfo & ei) = 0;
136
137 void logEI(Verbosity lvl, ErrorInfo ei)
138 {
139 ei.level = lvl;
140 logEI(ei);
141 }
142
143 virtual void warn(const std::string & msg);
144
145 virtual void startActivity(ActivityId act, Verbosity lvl, ActivityType type,
146 const std::string & s, const Fields & fields, ActivityId parent) { };
147
148 virtual void stopActivity(ActivityId act) { };
149
150 virtual void result(ActivityId act, ResultType type, const Fields & fields) { };
151
152 virtual void writeToStdout(std::string_view s);
153
154 template<typename... Args>
155 inline void cout(const Args & ... args)
156 {
157 writeToStdout(fmt(args...));
158 }
159
160 virtual std::optional<char> ask(std::string_view s)
161 { return {}; }
162
163 virtual void setPrintBuildLogs(bool printBuildLogs)
164 { }
165
166 virtual void setPrintMultiline(bool printMultiline)
167 { }
168};
169
175struct nop
176{
177 template<typename... T> nop(T...)
178 { }
179};
180
181ActivityId getCurActivity();
182void setCurActivity(const ActivityId activityId);
183
184struct Activity
185{
186 Logger & logger;
187
188 const ActivityId id;
189
190 Activity(Logger & logger, Verbosity lvl, ActivityType type, const std::string & s = "",
191 const Logger::Fields & fields = {}, ActivityId parent = getCurActivity());
192
193 Activity(Logger & logger, ActivityType type,
194 const Logger::Fields & fields = {}, ActivityId parent = getCurActivity())
195 : Activity(logger, lvlError, type, "", fields, parent) { };
196
197 Activity(const Activity & act) = delete;
198
199 ~Activity();
200
201 void progress(uint64_t done = 0, uint64_t expected = 0, uint64_t running = 0, uint64_t failed = 0) const
202 { result(resProgress, done, expected, running, failed); }
203
204 void setExpected(ActivityType type2, uint64_t expected) const
205 { result(resSetExpected, type2, expected); }
206
207 template<typename... Args>
208 void result(ResultType type, const Args & ... args) const
209 {
210 Logger::Fields fields;
211 nop{(fields.emplace_back(Logger::Field(args)), 1)...};
212 result(type, fields);
213 }
214
215 void result(ResultType type, const Logger::Fields & fields) const
216 {
217 logger.result(id, type, fields);
218 }
219
220 friend class Logger;
221};
222
223class PushActivity
224{
225 std::optional<ActivityId> prevAct;
226
227public:
228 PushActivity(ActivityId act) : prevAct(getCurActivity())
229 {
230 setCurActivity(act);
231 }
232
233 PushActivity(PushActivity && other)
234 {
235 std::swap(prevAct, other.prevAct);
236 }
237
238 PushActivity & operator=(PushActivity && other)
239 {
240 auto tmp(std::move(other));
241 std::swap(prevAct, tmp.prevAct);
242 return *this;
243 }
244
245 ~PushActivity()
246 {
247 if (prevAct) {
248 setCurActivity(*prevAct);
249 }
250 }
251};
252
253extern Logger * logger;
254
255Logger * makeSimpleLogger(bool printBuildLogs = true);
256
257Logger * makeJSONLogger(Logger & prevLogger);
258
262extern Verbosity verbosity;
263
270#define logErrorInfo(level, errorInfo...) \
271 do { \
272 if ((level) <= nix::verbosity) { \
273 logger->logEI((level), errorInfo); \
274 } \
275 } while (0)
276
277#define logError(errorInfo...) logErrorInfo(lvlError, errorInfo)
278#define logWarning(errorInfo...) logErrorInfo(lvlWarn, errorInfo)
279
285#define printMsgUsing(loggerParam, level, args...) \
286 do { \
287 auto _lix_logger_print_lvl = level; \
288 if (_lix_logger_print_lvl <= nix::verbosity) { \
289 loggerParam->log(_lix_logger_print_lvl, fmt(args)); \
290 } \
291 } while (0)
292#define printMsg(level, args...) printMsgUsing(logger, level, args)
293
294#define printError(args...) printMsg(lvlError, args)
295#define notice(args...) printMsg(lvlNotice, args)
296#define printInfo(args...) printMsg(lvlInfo, args)
297#define printTalkative(args...) printMsg(lvlTalkative, args)
298#define debug(args...) printMsg(lvlDebug, args)
299#define vomit(args...) printMsg(lvlVomit, args)
300
304template<typename... Args>
305inline void warn(const std::string & fs, const Args & ... args)
306{
307 logger->warn(HintFmt(fs, args...).str());
308}
309
310void writeLogsToStderr(std::string_view s);
311
314void logFatal(std::string const & s);
315
319std::optional<JSON> parseJSONMessage(const std::string & msg, std::string_view source);
320
324bool handleJSONLogMessage(JSON & json,
325 const Activity & act, std::map<ActivityId, Activity> & activities,
326 std::string_view source,
327 bool trusted);
328
332bool handleJSONLogMessage(const std::string & msg,
333 const Activity & act, std::map<ActivityId, Activity> & activities,
334 std::string_view source,
335 bool trusted);
336
337}
Definition args.hh:31
Definition fmt.hh:157
Definition logging.hh:101
This file defines two main structs/classes used in nix error handling.
std::string fmt(const std::string &s)
Definition fmt.hh:127
void warn(const std::string &fs, const Args &... args)
Definition logging.hh:305
ActivityType
Definition logging.hh:10
@ actBuild
Definition logging.hh:24
@ actQueryPathInfo
Definition logging.hh:38
@ actSubstitute
Definition logging.hh:32
@ actPostBuildHook
Definition logging.hh:43
ResultType
Definition logging.hh:50
@ resPostBuildLogLine
Definition logging.hh:85
@ resBuildLogLine
Definition logging.hh:59
@ resSetPhase
Definition logging.hh:66
@ resProgress
Definition logging.hh:74
@ resFileLinked
Definition logging.hh:54
@ resSetExpected
Definition logging.hh:80
Definition logging.hh:94
Definition logging.hh:107
Definition json-fwd.hh:21
Definition logging.hh:176