encode method
Encodes log as a single JSON line (no trailing newline).
Implementation
String encode(Log log) {
final levelTheme = theme[log.level];
// `data` is the sanitizer's scope, so a rule may drop the whole root.
// The drop is signalled out of band — an empty rendering is legal on
// its own — and it removes the key entirely, the same way the console
// printer removes the data block instead of printing a bare colon.
Object? data;
var hasData = log.hasData;
if (hasData) {
switch (dataFormat) {
case FileLogDataFormat.text:
final rendered = Loggable.renderRoot(
log.data,
theme: levelTheme,
config: config,
);
data = rendered.text;
hasData = !rendered.dropped;
case FileLogDataFormat.json:
final rendered = Loggable.renderRootJson(
log.data,
config: jsonConfig,
);
data = rendered.json;
hasData = !rendered.dropped;
}
}
return jsonEncode(<String, Object?>{
'num': log.num,
'level': log.level,
'levelName': log.levelName,
'time': log.time.toUtc().toIso8601String(),
if (log.path.isNotEmpty) 'path': log.path,
if (log.traceIds.isNotEmpty)
'traceIds': [for (final id in log.traceIds) id.toString()],
'message': levelTheme.formatMessage(
levelTheme.formatValue(
log.message,
escapeAnsiCodes: LoggableConfig.appEscapeAnsiCodes,
),
escapeAnsiCodes: false,
),
if (log.tags.isNotEmpty) 'tags': [...log.tags],
if (hasData) 'data': data,
// The error and the stack trace are outside the sanitizer's
// documented scope (values inside `data` only): both are rendered
// with the root offer suppressed, so a `depth == 0` rule cannot
// erase or rewrite them.
if (log.error case final error?)
'error': Loggable.renderOutsideSanitizerScope(error.toString),
if (log.stackTrace case final stackTrace?)
'stackTrace': Loggable.renderOutsideSanitizerScope(
stackTrace.toString,
),
});
}