Skip to content

Commit 3a5f967

Browse files
committed
Add shim log options
Signed-off-by: Austin Vazquez <austin.vazquez@docker.com>
1 parent 052ce77 commit 3a5f967

2 files changed

Lines changed: 70 additions & 4 deletions

File tree

pkg/logging/logging.go

Lines changed: 47 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -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
}

pkg/logging/logging_test.go

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,29 @@ func TestForwardConsoleLogs_DebugLevel(t *testing.T) {
235235
}
236236
}
237237

238+
func TestWithFormat(t *testing.T) {
239+
cfg := shimLogConfig{format: FormatText}
240+
WithFormat(FormatJSON)(&cfg)
241+
if cfg.format != FormatJSON {
242+
t.Errorf("WithFormat(FormatJSON): got %d, want %d", cfg.format, FormatJSON)
243+
}
244+
245+
cfg = shimLogConfig{format: FormatJSON}
246+
WithFormat(FormatText)(&cfg)
247+
if cfg.format != FormatText {
248+
t.Errorf("WithFormat(FormatText): got %d, want %d", cfg.format, FormatText)
249+
}
250+
}
251+
252+
func TestSetupShimLogDefaultIsText(t *testing.T) {
253+
// FormatText must be the zero value so that a shimLogConfig without
254+
// explicit initialisation defaults to text (backward-compatible).
255+
var cfg shimLogConfig
256+
if cfg.format != FormatText {
257+
t.Errorf("zero-value shimLogConfig.format = %d, want FormatText (%d)", cfg.format, FormatText)
258+
}
259+
}
260+
238261
func TestForwardJSONLog_InvalidJSON(t *testing.T) {
239262
SetBaseHandler(discardHandler{})
240263
if forwardJSONLog("{not json") {

0 commit comments

Comments
 (0)