/area logging
/area security
/kind enhancement
What would you like to be added:
JSON log output for the backend (one object per line), used by default in production. The Gardener logging guidelines define json as the default format for production and text for development.
- Add a JSON format to
@gardener-dashboard/logger, using the record shape from the guidelines ({"level":"info","ts":"…","msg":"…"}). Because the whole record is JSON-encoded, line breaks and control characters in values are escaped in one place, and multi-line content stays inside its record.
- Honor the
logFormat setting (json or text). Default to json in production (the container image sets NODE_ENV=production) and to text for local development.
- Switch
logFormat: text to json in the Helm chart and in gardener-operator (pkg/component/gardener/dashboard/configmap.go). Since the backend ignores logFormat today, the order of these changes doesn't matter.
- Keep
text for local development, and document that it doesn't protect against the problems listed below.
Notes:
- The global logger is created on import and configured afterwards by
backend/lib/logger, which is how logLevel is applied today. If the format can be switched on the same instance, shared packages using globalLogger need no changes.
- Morgan passes finished access log lines to the logger, with its field values already escaped. Putting such a line into
msg escapes them again (a " becomes \\\"). Building the access log record from the request and response avoids this; the existing URL redaction must be kept. The record also needs a regular level instead of the current http method.
Logger#inspect always sets colors: true, but JSON output must not contain color codes.
- If arguments become separate fields instead of being formatted into
msg: JSON.stringify turns an Error into {} and throws on circular structures and BigInt values. Logging must never throw.
Why is this needed:
The backend only writes human-readable text lines (<timestamp> <level>: <message>) and fills in printf-style arguments with util.format. The chart and gardener-operator set logFormat: text, but the backend never reads that setting. In production, this has several downsides:
- Values from outside the dashboard, such as HTTP requests or responses from upstream APIs, are written as they are. A line break in such a value creates what looks like a separate log record. Terminal escape sequences are passed on to anyone who reads the logs in a terminal.
- A single record can span several lines, for example error stacks or response bodies logged at
trace level. Container logs are line-based, so log pipelines treat these lines as unrelated entries.
- Nothing is machine-readable. Level and timestamp are plain text, and the timestamp is in UTC but has no zone designator. Response bodies logged at
trace level contain ANSI color codes even when the output is not a terminal.
/area logging
/area security
/kind enhancement
What would you like to be added:
JSON log output for the backend (one object per line), used by default in production. The Gardener logging guidelines define
jsonas the default format for production andtextfor development.@gardener-dashboard/logger, using the record shape from the guidelines ({"level":"info","ts":"…","msg":"…"}). Because the whole record is JSON-encoded, line breaks and control characters in values are escaped in one place, and multi-line content stays inside its record.logFormatsetting (jsonortext). Default tojsonin production (the container image setsNODE_ENV=production) and totextfor local development.logFormat: texttojsonin the Helm chart and in gardener-operator (pkg/component/gardener/dashboard/configmap.go). Since the backend ignoreslogFormattoday, the order of these changes doesn't matter.textfor local development, and document that it doesn't protect against the problems listed below.Notes:
backend/lib/logger, which is howlogLevelis applied today. If the format can be switched on the same instance, shared packages usingglobalLoggerneed no changes.msgescapes them again (a"becomes\\\"). Building the access log record from the request and response avoids this; the existing URL redaction must be kept. The record also needs a regularlevelinstead of the currenthttpmethod.Logger#inspectalways setscolors: true, but JSON output must not contain color codes.msg:JSON.stringifyturns anErrorinto{}and throws on circular structures andBigIntvalues. Logging must never throw.Why is this needed:
The backend only writes human-readable text lines (
<timestamp> <level>: <message>) and fills in printf-style arguments withutil.format. The chart and gardener-operator setlogFormat: text, but the backend never reads that setting. In production, this has several downsides:tracelevel. Container logs are line-based, so log pipelines treat these lines as unrelated entries.tracelevel contain ANSI color codes even when the output is not a terminal.