@@ -31,18 +31,53 @@ import (
3131 "github.com/containerd/log"
3232)
3333
34+ // Format identifies the encoding used for shim log output.
35+ type Format int
36+
37+ const (
38+ // FormatText emits human-readable slog text output (the default).
39+ FormatText Format = iota
40+ // FormatJSON emits one JSON object per line.
41+ FormatJSON
42+ )
43+
44+ // Option configures [SetupShimLog].
45+ type Option func (* shimLogConfig )
46+
47+ type shimLogConfig struct {
48+ format Format
49+ }
50+
51+ // WithFormat sets the log output format. The default is [FormatText], which
52+ // preserves the existing shim log format. Pass [FormatJSON] to emit one JSON
53+ // object per line, which allows structured log consumers (e.g. sandboxd) to
54+ // unwrap records directly instead of treating each line as an opaque message.
55+ func WithFormat (f Format ) Option {
56+ return func (c * shimLogConfig ) {
57+ c .format = f
58+ }
59+ }
60+
3461// SetupShimLog configures slog-based logging for the shim process.
3562// It opens the platform-specific log output (FIFO on Unix, named pipe
36- // on Windows), then creates a slog TextHandler and sets it as the
37- // default logger with a "component=shim" attribute.
63+ // on Windows), then creates a slog handler and sets it as the default
64+ // logger with a "component=shim" attribute.
65+ //
66+ // The handler's format defaults to [FormatText]. Pass [WithFormat]([FormatJSON])
67+ // to emit JSON, which structured log consumers can unwrap directly.
3868//
3969// The base handler (without component) is stored for use by
4070// [ForwardConsoleLogs] so that forwarded records carry their own
4171// component rather than inheriting "shim".
4272//
4373// For the short-lived start and delete actions, only [log.UseSlog] is
4474// called to route logrus through slog; the log output is not opened.
45- func SetupShimLog () {
75+ func SetupShimLog (opts ... Option ) {
76+ cfg := shimLogConfig {format : FormatText }
77+ for _ , o := range opts {
78+ o (& cfg )
79+ }
80+
4681 log .UseSlog ()
4782
4883 var (
@@ -81,7 +116,15 @@ func SetupShimLog() {
81116 log .SetLevel ("debug" ) //nolint:errcheck
82117 }
83118
84- handler := slog .NewTextHandler (w , & slog.HandlerOptions {Level : & level }).WithAttrs (attrs )
119+ handlerOpts := & slog.HandlerOptions {Level : & level }
120+ var handler slog.Handler
121+ switch cfg .format {
122+ case FormatJSON :
123+ handler = slog .NewJSONHandler (w , handlerOpts )
124+ default :
125+ handler = slog .NewTextHandler (w , handlerOpts )
126+ }
127+ handler = handler .WithAttrs (attrs )
85128 SetBaseHandler (handler )
86129 slog .SetDefault (slog .New (handler ).With ("component" , "shim" ))
87130}
0 commit comments