diff --git a/benchmark_test.go b/benchmark_test.go index d6b51f4b..7545f268 100644 --- a/benchmark_test.go +++ b/benchmark_test.go @@ -16,13 +16,12 @@ import ( "bufio" "context" "fmt" + "log/slog" "os" "path/filepath" "strings" "testing" - "github.com/sirupsen/logrus" - "github.com/firecracker-microvm/firecracker-go-sdk/client/models" ) @@ -69,9 +68,7 @@ func createMachine(ctx context.Context, name string, forwardSignals []os.Signal) WithBin(getFirecrackerBinaryPath()). Build(ctx) - log := logrus.New() - log.SetLevel(logrus.FatalLevel) - machine, err := NewMachine(ctx, config, WithProcessRunner(cmd), WithLogger(logrus.NewEntry(log))) + machine, err := NewMachine(ctx, config, WithProcessRunner(cmd), WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil)))) if err != nil { return nil, cleanup, err } diff --git a/client_transports.go b/client_transports.go index 0ad8b358..fc87aa3c 100644 --- a/client_transports.go +++ b/client_transports.go @@ -15,18 +15,19 @@ package firecracker import ( "context" - "github.com/go-openapi/runtime" + "log/slog" "net" "net/http" + "github.com/go-openapi/runtime" + httptransport "github.com/go-openapi/runtime/client" - "github.com/sirupsen/logrus" "github.com/firecracker-microvm/firecracker-go-sdk/client" ) // NewUnixSocketTransport creates a new clientTransport configured at the specified Unix socketPath. -func NewUnixSocketTransport(socketPath string, logger *logrus.Entry, debug bool) runtime.ClientTransport { +func NewUnixSocketTransport(socketPath string, logger *slog.Logger, debug bool) runtime.ClientTransport { socketTransport := &http.Transport{ DialContext: func(ctx context.Context, network, path string) (net.Conn, error) { addr, err := net.ResolveUnixAddr("unix", socketPath) @@ -46,7 +47,8 @@ func NewUnixSocketTransport(socketPath string, logger *logrus.Entry, debug bool) } if logger != nil { - transport.SetLogger(logger) + // TODO: fix this + // transport.SetLogger(logger) } return transport diff --git a/example_test.go b/example_test.go index 5f4d9c93..6ff57009 100644 --- a/example_test.go +++ b/example_test.go @@ -15,11 +15,10 @@ package firecracker_test import ( "context" "fmt" + "log/slog" "os" "time" - log "github.com/sirupsen/logrus" - "github.com/firecracker-microvm/firecracker-go-sdk" models "github.com/firecracker-microvm/firecracker-go-sdk/client/models" ) @@ -279,8 +278,7 @@ func ExampleJailerConfig_enablingJailer() { f.Close() } - logger := log.New() - m, err := firecracker.NewMachine(vmmCtx, fcCfg, firecracker.WithLogger(log.NewEntry(logger))) + m, err := firecracker.NewMachine(vmmCtx, fcCfg, firecracker.WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil)))) if err != nil { panic(err) } diff --git a/fctesting/utils.go b/fctesting/utils.go index b287ef9a..d135f32a 100644 --- a/fctesting/utils.go +++ b/fctesting/utils.go @@ -15,13 +15,13 @@ package fctesting import ( "fmt" + "io" + "log/slog" "os" "os/user" "testing" "golang.org/x/sys/unix" - - log "github.com/sirupsen/logrus" ) const rootDisableEnvName = "DISABLE_ROOT_TESTS" @@ -68,23 +68,24 @@ func RequiresRoot(t testing.TB) { } } -func newLogger(t testing.TB) *log.Logger { - str := os.Getenv(logLevelEnvName) - l := log.New() - if str == "" { - return l - } - - logLevel, err := log.ParseLevel(str) - if err != nil { - t.Fatalf("Failed to parse %q as Log Level: %v", str, err) - } - - l.SetLevel(logLevel) - return l -} +// func newLogger(t testing.TB) *log.Logger { +// str := os.Getenv(logLevelEnvName) +// l := log.New() +// if str == "" { +// return l +// } +// +// logLevel, err := log.ParseLevel(str) +// if err != nil { +// t.Fatalf("Failed to parse %q as Log Level: %v", str, err) +// } +// +// l.SetLevel(logLevel) +// return l +// } // NewLogEntry creates log.Entry. The level is specified by "FC_TEST_LOG_LEVEL" environment variable -func NewLogEntry(t testing.TB) *log.Entry { - return log.NewEntry(newLogger(t)) +func NewLogEntry(t testing.TB, level slog.Level, w io.Writer) *slog.Logger { + return slog.New(slog.NewTextHandler(w, &slog.HandlerOptions{Level: level})) + //return log.NewEntry(newLogger(t)) } diff --git a/fctesting/utils_test.go b/fctesting/utils_test.go index 35f9dad7..63f0f920 100644 --- a/fctesting/utils_test.go +++ b/fctesting/utils_test.go @@ -13,6 +13,7 @@ package fctesting import ( + "log/slog" "os" "testing" ) @@ -25,6 +26,6 @@ func TestLoggingPanic(t *testing.T) { }() os.Setenv("FC_TEST_LOG_LEVEL", "debug") - l := NewLogEntry(t) + l := NewLogEntry(t, slog.LevelDebug, os.Stdout) l.Debug("TestLoggingPanic") } diff --git a/firecracker.go b/firecracker.go index 0df8b55b..93f8ad92 100644 --- a/firecracker.go +++ b/firecracker.go @@ -15,12 +15,11 @@ package firecracker import ( "context" + "log/slog" "time" "github.com/go-openapi/strfmt" - "github.com/sirupsen/logrus" - "github.com/firecracker-microvm/firecracker-go-sdk/client" models "github.com/firecracker-microvm/firecracker-go-sdk/client/models" ops "github.com/firecracker-microvm/firecracker-go-sdk/client/operations" @@ -34,7 +33,7 @@ const ( ) // newFirecrackerClient creates a FirecrackerClient -func newFirecrackerClient(socketPath string, logger *logrus.Entry, debug bool) *client.Firecracker { +func newFirecrackerClient(socketPath string, logger *slog.Logger, debug bool) *client.Firecracker { httpClient := client.NewHTTPClient(strfmt.NewFormats()) transport := NewUnixSocketTransport(socketPath, logger, debug) @@ -62,7 +61,7 @@ type Client struct { } // NewClient creates a Client -func NewClient(socketPath string, logger *logrus.Entry, debug bool, opts ...ClientOpt) *Client { +func NewClient(socketPath string, logger *slog.Logger, debug bool, opts ...ClientOpt) *Client { httpClient := newFirecrackerClient(socketPath, logger, debug) c := &Client{client: httpClient} c.firecrackerRequestTimeout = envValueOrDefaultInt(firecrackerRequestTimeoutEnv, defaultFirecrackerRequestTimeout) diff --git a/firecracker_test.go b/firecracker_test.go index 32647482..23746ec1 100644 --- a/firecracker_test.go +++ b/firecracker_test.go @@ -14,6 +14,8 @@ package firecracker import ( "context" + "log/slog" + "os" "path/filepath" "testing" "time" @@ -54,7 +56,7 @@ func TestClient(t *testing.T) { PathOnHost: String(filepath.Join(testDataPath, "drive-2.img")), } - client := NewClient(socketpath, fctesting.NewLogEntry(t), true) + client := NewClient(socketpath, fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), true) deadlineCtx, deadlineCancel := context.WithTimeout(ctx, 250*time.Millisecond) defer deadlineCancel() if err := waitForAliveVMM(deadlineCtx, client); err != nil { @@ -90,7 +92,7 @@ func TestGetFirecrackerVersion(t *testing.T) { } }() - client := NewClient(socketpath, fctesting.NewLogEntry(t), true) + client := NewClient(socketpath, fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), true) deadlineCtx, deadlineCancel := context.WithTimeout(ctx, 250*time.Millisecond) defer deadlineCancel() if err := waitForAliveVMM(deadlineCtx, client); err != nil { diff --git a/handlers.go b/handlers.go index d9d022d8..ac0265c7 100644 --- a/handlers.go +++ b/handlers.go @@ -16,6 +16,7 @@ package firecracker import ( "context" "fmt" + "log/slog" "os" ) @@ -135,7 +136,7 @@ var StartVMMHandler = Handler{ func createFifoOrFile(ctx context.Context, m *Machine, fifo, path string) error { if len(fifo) > 0 { - if err := createFifo(fifo); err != nil { + if err := createFifo(fifo, m.logger); err != nil { return err } @@ -171,7 +172,7 @@ var CreateLogFilesHandler = Handler{ if m.Cfg.FifoLogWriter != nil { if err := m.captureFifoToFile(ctx, m.logger, m.Cfg.LogFifo, m.Cfg.FifoLogWriter); err != nil { - m.logger.Warnf("captureFifoToFile() returned %s. Continuing anyway.", err) + m.logger.Warn("captureFifoToFile() errored. Continuing anyway.", slog.Any("err", err)) } } @@ -192,7 +193,7 @@ var BootstrapLoggingHandler = Handler{ if err := m.setupMetrics(ctx); err != nil { return err } - m.logger.Debugf("setup logging: success") + m.logger.Debug("setup logging: success") return nil }, } @@ -466,9 +467,9 @@ func (l HandlerList) Clear() HandlerList { // any of the handlers, then the list will halt execution and return the error. func (l HandlerList) Run(ctx context.Context, m *Machine) error { for _, handler := range l.list { - m.logger.Debugf("Running handler %s", handler.Name) + m.logger.Debug("Running handler", slog.String("handler_name", handler.Name)) if err := handler.Fn(ctx, m); err != nil { - m.logger.Warnf("Failed handler %q: %v", handler.Name, err) + m.logger.Warn("Failed handler", slog.String("handler_name", handler.Name), slog.Any("err", err)) return err } } diff --git a/handlers_test.go b/handlers_test.go index c0a634a6..f220d6a8 100644 --- a/handlers_test.go +++ b/handlers_test.go @@ -15,6 +15,7 @@ package firecracker import ( "context" "fmt" + "log/slog" "net" "os" "path/filepath" @@ -186,7 +187,7 @@ func TestHandlerListRun(t *testing.T) { ctx := context.Background() m := &Machine{ - logger: fctesting.NewLogEntry(t), + logger: fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), } if err := h.Run(ctx, m); err != bazErr { t.Errorf("expected an error, but received %v", err) @@ -679,8 +680,8 @@ func TestHandlers(t *testing.T) { // resetting called for the next test called = "" - client := NewClient(socketpath, fctesting.NewLogEntry(t), true, WithOpsClient(&c.Client)) - m, err := NewMachine(ctx, c.Config, WithClient(client), WithLogger(fctesting.NewLogEntry(t))) + client := NewClient(socketpath, fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), true, WithOpsClient(&c.Client)) + m, err := NewMachine(ctx, c.Config, WithClient(client), WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) if err != nil { t.Fatalf("failed to create machine: %v", err) } diff --git a/machine.go b/machine.go index a812b986..16c555cb 100644 --- a/machine.go +++ b/machine.go @@ -19,6 +19,7 @@ import ( "errors" "fmt" "io" + "log/slog" "net" "os" "os/exec" @@ -36,8 +37,6 @@ import ( "github.com/google/uuid" "github.com/hashicorp/go-multierror" - log "github.com/sirupsen/logrus" - models "github.com/firecracker-microvm/firecracker-go-sdk/client/models" ) @@ -262,7 +261,7 @@ type Machine struct { Cfg Config client *Client cmd *exec.Cmd - logger *log.Entry + logger *slog.Logger machineConfig models.MachineConfiguration // The actual machine config as reported by Firecracker // startOnce ensures that the machine can only be started once startOnce sync.Once @@ -279,8 +278,8 @@ type Machine struct { } // Logger returns a logrus logger appropriate for logging hypervisor messages -func (m *Machine) Logger() *log.Entry { - return m.logger.WithField("subsystem", userAgent) +func (m *Machine) Logger() *slog.Logger { + return m.logger.With(slog.String("subsystem", userAgent)) } // PID returns the machine's running process PID or an error if not running @@ -385,9 +384,7 @@ func NewMachine(ctx context.Context, cfg Config, opts ...Opt) (*Machine, error) } if m.logger == nil { - logger := log.New() - - m.logger = log.NewEntry(logger) + m.logger = slog.New(slog.NewTextHandler(os.Stdout, nil)) } if m.client == nil { @@ -442,8 +439,8 @@ func (m *Machine) Start(ctx context.Context) error { defer func() { if err != nil { if cleanupErr := m.doCleanup(); cleanupErr != nil { - m.Logger().Errorf( - "failed to cleanup VM after previous start failure: %v", cleanupErr) + m.Logger().Error( + "failed to cleanup VM after previous start failure", slog.Any("err", cleanupErr)) } } }() @@ -483,7 +480,7 @@ func (m *Machine) Wait(ctx context.Context) error { func (m *Machine) GetFirecrackerVersion(ctx context.Context) (string, error) { resp, err := m.client.GetFirecrackerVersion(ctx) if err != nil { - m.logger.Errorf("Getting firecracker version: %s", err) + m.logger.Error("Getting firecracker version", slog.Any("err", err)) return "", err } @@ -533,10 +530,10 @@ func (m *Machine) addVsocks(ctx context.Context, vsocks ...VsockDevice) error { func (m *Machine) attachDrives(ctx context.Context, drives ...models.Drive) error { for _, dev := range drives { if err := m.attachDrive(ctx, dev); err != nil { - m.logger.Errorf("While attaching drive %s, got error %s", StringValue(dev.PathOnHost), err) + m.logger.Error("Errored while attaching drive", slog.String("drive", StringValue(dev.PathOnHost)), slog.Any("err", err)) return err } - m.logger.Debugf("attachDrive returned for %s", StringValue(dev.PathOnHost)) + m.logger.Debug("attachDrive returned", slog.String("drive", StringValue(dev.PathOnHost))) } return nil @@ -548,10 +545,10 @@ func (m *Machine) defaultNetNSPath() string { // startVMM starts the firecracker vmm process and configures logging. func (m *Machine) startVMM(ctx context.Context) error { - m.logger.Printf("Called startVMM(), setting up a VMM on %s", m.Cfg.SocketPath) + m.logger.Debug("Called startVMM(), setting up a VMM", slog.String("socket_path", m.Cfg.SocketPath)) startCmd := m.cmd.Start - m.logger.Debugf("Starting %v", m.cmd.Args) + m.logger.Debug("Starting", slog.String("args", strings.Join(m.cmd.Args, " "))) var err error if m.Cfg.NetNS != "" && m.Cfg.JailerCfg == nil { @@ -567,14 +564,14 @@ func (m *Machine) startVMM(ctx context.Context) error { } if err != nil { - m.logger.Errorf("Failed to start VMM: %s", err) + m.logger.Error("Failed to start VMM", slog.Any("err", err)) m.fatalErr = err close(m.exitCh) return err } - m.logger.Debugf("VMM started socket path is %s", m.Cfg.SocketPath) + m.logger.Debug("VMM started", slog.String("socket_path", m.Cfg.SocketPath)) m.cleanupFuncs = append(m.cleanupFuncs, func() error { @@ -589,14 +586,14 @@ func (m *Machine) startVMM(ctx context.Context) error { go func() { waitErr := m.cmd.Wait() if waitErr != nil { - m.logger.Warnf("firecracker exited: %s", waitErr.Error()) + m.logger.Warn("firecracker exited", slog.String("err", waitErr.Error())) } else { - m.logger.Printf("firecracker exited: status=0") + m.logger.Debug("firecracker exited: status=0") } cleanupErr := m.doCleanup() if cleanupErr != nil { - m.logger.Errorf("failed to cleanup after VM exit: %v", cleanupErr) + m.logger.Error("failed to cleanup after VM exit", slog.Any("err", cleanupErr)) } errCh <- multierror.Append(waitErr, cleanupErr).ErrorOrNil() @@ -633,7 +630,7 @@ func (m *Machine) startVMM(ctx context.Context) error { } err := m.stopVMM() if err != nil { - m.logger.WithError(err).Errorf("failed to stop vm %q", m.Cfg.VMID) + m.logger.Error("failed to stop vm", slog.String("vmid", m.Cfg.VMID), slog.Any("err", err)) } }() @@ -641,11 +638,11 @@ func (m *Machine) startVMM(ctx context.Context) error { // (gracefully or not). go func() { m.fatalErr = <-errCh - m.logger.Debugf("closing the exitCh %v", m.fatalErr) + m.logger.Debug("closing the exitCh", slog.Any("err", m.fatalErr)) close(m.exitCh) }() - m.logger.Debugf("returning from startVMM()") + m.logger.Debug("returning from startVMM()") return nil } @@ -672,8 +669,8 @@ func (m *Machine) stopVMM() error { } // createFifo sets up a FIFOs -func createFifo(path string) error { - log.Debugf("Creating FIFO %s", path) +func createFifo(path string, log *slog.Logger) error { + log.Debug("Creating FIFO", slog.String("path", path)) if err := syscall.Mkfifo(path, 0700); err != nil { return fmt.Errorf("Failed to create log fifo: %v", err) } @@ -688,7 +685,7 @@ func (m *Machine) setupLogging(ctx context.Context) error { if len(path) == 0 { // No logging configured - m.logger.Printf("VMM logging disabled.") + m.logger.Info("VMM logging disabled.") return nil } @@ -711,7 +708,7 @@ func (m *Machine) setupLogging(ctx context.Context) error { return err } - m.logger.Debugf("Configured VMM logging to %s", path) + m.logger.Debug("Configured VMM logging", slog.String("path", path)) return nil } @@ -724,7 +721,7 @@ func (m *Machine) setupMetrics(ctx context.Context) error { if len(path) == 0 { // No logging configured - m.logger.Printf("VMM metrics disabled.") + m.logger.Debug("VMM metrics disabled.") return nil } @@ -735,16 +732,16 @@ func (m *Machine) setupMetrics(ctx context.Context) error { return err } - m.logger.Debugf("Configured VMM metrics to %s", path) + m.logger.Debug("Configured VMM metrics", slog.String("path", path)) return nil } -func (m *Machine) captureFifoToFile(ctx context.Context, logger *log.Entry, fifoPath string, w io.Writer) error { +func (m *Machine) captureFifoToFile(ctx context.Context, logger *slog.Logger, fifoPath string, w io.Writer) error { return m.captureFifoToFileWithChannel(ctx, logger, fifoPath, w, make(chan error, 1)) } -func (m *Machine) captureFifoToFileWithChannel(ctx context.Context, logger *log.Entry, fifoPath string, w io.Writer, done chan error) error { +func (m *Machine) captureFifoToFileWithChannel(ctx context.Context, logger *slog.Logger, fifoPath string, w io.Writer, done chan error) error { // open the fifo pipe which will be used // to write its contents to a file. fifoPipe, err := fifo.OpenFifo(ctx, fifoPath, syscall.O_RDONLY|syscall.O_NONBLOCK, 0600) @@ -752,7 +749,7 @@ func (m *Machine) captureFifoToFileWithChannel(ctx context.Context, logger *log. return fmt.Errorf("Failed to open fifo path at %q: %v", fifoPath, err) } - logger.Debugf("Capturing %q to writer", fifoPath) + logger.Debug("Capturing to writer", slog.String("fifoPath", fifoPath)) // this goroutine is to track the life of the application along with whether // or not the context has been cancelled which is signified by the exitCh. In @@ -760,7 +757,7 @@ func (m *Machine) captureFifoToFileWithChannel(ctx context.Context, logger *log. go func() { <-m.exitCh if err := fifoPipe.Close(); err != nil { - logger.WithError(err).Debug("failed to close fifo") + logger.Debug("failed to close fifo", slog.Any("err", err)) } }() @@ -771,16 +768,16 @@ func (m *Machine) captureFifoToFileWithChannel(ctx context.Context, logger *log. go func() { defer func() { if err := fifoPipe.Close(); err != nil { - logger.Warnf("Failed to close fifo pipe: %v", err) + logger.Warn("Failed to close fifo pipe", slog.Any("err", err)) } if err := syscall.Unlink(fifoPath); err != nil { - logger.Warnf("Failed to unlink %s: %v", fifoPath, err) + logger.Warn("Failed to unlink", slog.String("fifoPath", fifoPath), slog.Any("err", err)) } }() if _, err := io.Copy(w, fifoPipe); err != nil { - logger.WithError(err).Warn("io.Copy failed to copy contents of fifo pipe") + logger.Warn("io.Copy failed to copy contents of fifo pipe", slog.Any("err", err)) done <- err } @@ -793,14 +790,14 @@ func (m *Machine) captureFifoToFileWithChannel(ctx context.Context, logger *log. func (m *Machine) createMachine(ctx context.Context) error { resp, err := m.client.PutMachineConfiguration(ctx, &m.Cfg.MachineCfg) if err != nil { - m.logger.Errorf("PutMachineConfiguration returned %s", resp.Error()) + m.logger.Error("PutMachineConfiguration failed", slog.Any("err", resp.Error())) return err } m.logger.Debug("PutMachineConfiguration returned") err = m.refreshMachineConfiguration() if err != nil { - m.logger.Errorf("Unable to inspect Firecracker MachineConfiguration. Continuing anyway. %s", err) + m.logger.Warn("Unable to inspect Firecracker MachineConfiguration. Continuing anyway.", slog.Any("err", err)) } m.logger.Debug("createMachine returning") return err @@ -815,7 +812,7 @@ func (m *Machine) createBootSource(ctx context.Context, imagePath, initrdPath, k resp, err := m.client.PutGuestBootSource(ctx, &bsrc) if err == nil { - m.logger.Printf("PutGuestBootSource: %s", resp.Error()) + m.logger.Debug("PutGuestBootSource", slog.Any("err", resp.Error())) } return err @@ -830,8 +827,11 @@ func (m *Machine) createNetworkInterface(ctx context.Context, iface NetworkInter return errors.New("invalid nil state for network interface") } - m.logger.Printf("Attaching NIC %s (hwaddr %s) at index %s", - iface.StaticConfiguration.HostDevName, iface.StaticConfiguration.MacAddress, ifaceID) + m.logger.Debug("Attaching NIC at index", + slog.String("device_name", iface.StaticConfiguration.HostDevName), + slog.String("mac_addr", iface.StaticConfiguration.MacAddress), + slog.String("interface_id", ifaceID), + ) ifaceCfg := models.NetworkInterface{ IfaceID: &ifaceID, @@ -849,10 +849,10 @@ func (m *Machine) createNetworkInterface(ctx context.Context, iface NetworkInter resp, err := m.client.PutGuestNetworkInterfaceByID(ctx, ifaceID, &ifaceCfg) if err == nil { - m.logger.Debugf("PutGuestNetworkInterfaceByID: %s", resp.Error()) + m.logger.Debug("PutGuestNetworkInterfaceByID", slog.Any("err", resp.Error())) } - m.logger.Debugf("createNetworkInterface returned for %s", iface.StaticConfiguration.HostDevName) + m.logger.Debug("createNetworkInterface returned", slog.String("device_name", iface.StaticConfiguration.HostDevName)) return err } @@ -868,23 +868,23 @@ func (m *Machine) UpdateGuestNetworkInterfaceRateLimit(ctx context.Context, ifac iface.TxRateLimiter = rateLimiters.InRateLimiter } if _, err := m.client.PatchGuestNetworkInterfaceByID(ctx, ifaceID, &iface, opts...); err != nil { - m.logger.Errorf("Update network interface failed: %s: %v", ifaceID, err) + m.logger.Error("Update network interface failed: %s: %v", slog.String("interface_id", ifaceID), slog.Any("err", err)) return err } - m.logger.Infof("Updated network interface: %s", ifaceID) + m.logger.Info("Updated network interface", slog.String("interface_id", ifaceID)) return nil } // attachDrive attaches a secondary block device func (m *Machine) attachDrive(ctx context.Context, dev models.Drive) error { hostPath := StringValue(dev.PathOnHost) - m.logger.Infof("Attaching drive %s, slot %s, root %t.", hostPath, StringValue(dev.DriveID), BoolValue(dev.IsRootDevice)) + m.logger.Debug("Attaching drive", slog.String("drive_path", hostPath), slog.String("slot", StringValue(dev.DriveID)), slog.Bool("root", BoolValue(dev.IsRootDevice))) respNoContent, err := m.client.PutGuestDriveByID(ctx, StringValue(dev.DriveID), &dev) if err == nil { - m.logger.Printf("Attached drive %s: %s", hostPath, respNoContent.Error()) + m.logger.Debug("Attached drive", slog.String("drive_path", hostPath), slog.String("err", respNoContent.Error())) } else { - m.logger.Errorf("Attach drive failed: %s: %s", hostPath, err) + m.logger.Error("Attach drive failed", slog.String("drive_path", hostPath), slog.Any("err", err)) } return err } @@ -901,7 +901,7 @@ func (m *Machine) addVsock(ctx context.Context, dev VsockDevice) error { if err != nil { return err } - m.logger.Debugf("Attach vsock %s successful: %s", dev.Path, resp.Error()) + m.logger.Debug("Attach vsock successful", slog.String("path", dev.Path), slog.String("err", resp.Error())) return nil } @@ -917,9 +917,9 @@ func (m *Machine) startInstance(ctx context.Context) error { resp, err := m.client.CreateSyncAction(ctx, &info) if err == nil { - m.logger.Printf("startInstance successful: %s", resp.Error()) + m.logger.Debug("startInstance successful", slog.String("err", resp.Error())) } else { - m.logger.Errorf("Starting instance: %s", err) + m.logger.Error("Starting instance failed", slog.Any("err", err)) } return err } @@ -932,9 +932,9 @@ func (m *Machine) sendCtrlAltDel(ctx context.Context) error { resp, err := m.client.CreateSyncAction(ctx, &info) if err == nil { - m.logger.Printf("Sent instance shutdown request: %s", resp.Error()) + m.logger.Info("Sent instance shutdown request", slog.String("err", resp.Error())) } else { - m.logger.Errorf("Unable to send CtrlAltDel: %s", err) + m.logger.Error("Unable to send CtrlAltDel", slog.Any("err", err)) } return err } @@ -960,11 +960,11 @@ func (m *Machine) setMmdsConfig(ctx context.Context, address net.IP, ifaces Netw // When configuring the microVM, if MMDS needs to be activated, a network interface // has to be configured to allow MMDS requests. if len(mmdsCfg.NetworkInterfaces) == 0 { - m.logger.Infof("No interfaces are allowed to access MMDS, skipping MMDS config") + m.logger.Info("No interfaces are allowed to access MMDS, skipping MMDS config") return nil } if _, err := m.client.PutMmdsConfig(ctx, &mmdsCfg); err != nil { - m.logger.Errorf("Setting mmds configuration failed: %s: %v", address, err) + m.logger.Error("Setting mmds configuration failed", slog.Any("address", address), slog.Any("err", err)) return err } @@ -975,22 +975,22 @@ func (m *Machine) setMmdsConfig(ctx context.Context, address net.IP, ifaces Netw // SetMetadata sets the machine's metadata for MDDS func (m *Machine) SetMetadata(ctx context.Context, metadata interface{}) error { if _, err := m.client.PutMmds(ctx, metadata); err != nil { - m.logger.Errorf("Setting metadata: %s", err) + m.logger.Error("Setting metadata", slog.Any("err", err)) return err } - m.logger.Printf("SetMetadata successful") + m.logger.Debug("SetMetadata successful") return nil } // UpdateMetadata patches the machine's metadata for MDDS func (m *Machine) UpdateMetadata(ctx context.Context, metadata interface{}) error { if _, err := m.client.PatchMmds(ctx, metadata); err != nil { - m.logger.Errorf("Updating metadata: %s", err) + m.logger.Error("Updating metadata", slog.Any("err", err)) return err } - m.logger.Printf("UpdateMetadata successful") + m.logger.Info("UpdateMetadata successful") return nil } @@ -998,22 +998,22 @@ func (m *Machine) UpdateMetadata(ctx context.Context, metadata interface{}) erro func (m *Machine) GetMetadata(ctx context.Context, v interface{}) error { resp, err := m.client.GetMmds(ctx) if err != nil { - m.logger.Errorf("Getting metadata: %s", err) + m.logger.Error("Getting metadata", slog.Any("err", err)) return err } payloadData, err := json.Marshal(resp.Payload) if err != nil { - m.logger.Errorf("Getting metadata failed parsing payload: %s", err) + m.logger.Error("Getting metadata failed parsing payload", slog.Any("err", err)) return err } if err := json.Unmarshal(payloadData, v); err != nil { - m.logger.Errorf("Getting metadata failed parsing payload: %s", err) + m.logger.Error("Getting metadata failed parsing payload", slog.Any("err", err)) return err } - m.logger.Printf("GetMetadata successful") + m.logger.Info("GetMetadata successful") return nil } @@ -1021,11 +1021,11 @@ func (m *Machine) GetMetadata(ctx context.Context, v interface{}) error { // parameters of the partialDrive. func (m *Machine) UpdateGuestDrive(ctx context.Context, driveID, pathOnHost string, opts ...PatchGuestDriveByIDOpt) error { if _, err := m.client.PatchGuestDriveByID(ctx, driveID, pathOnHost, opts...); err != nil { - m.logger.Errorf("PatchGuestDrive failed: %v", err) + m.logger.Error("PatchGuestDrive failed", slog.Any("err", err)) return err } - m.logger.Printf("PatchGuestDrive successful") + m.logger.Info("PatchGuestDrive successful") return nil } @@ -1033,16 +1033,16 @@ func (m *Machine) DescribeInstanceInfo(ctx context.Context) (models.InstanceInfo var instanceInfo models.InstanceInfo resp, err := m.client.GetInstanceInfo(ctx) if err != nil { - m.logger.Errorf("Getting Instance Info: %s", err) + m.logger.Error("Getting Instance Info", slog.Any("err", err)) return instanceInfo, err } instanceInfo = *resp.Payload if err != nil { - m.logger.Errorf("Getting Instance info failed parsing payload: %s", err) + m.logger.Error("Getting Instance info failed parsing payload", slog.Any("err", err)) } - m.logger.Printf("GetInstanceInfo successful") + m.logger.Info("GetInstanceInfo successful") return instanceInfo, err } @@ -1051,10 +1051,10 @@ func (m *Machine) DescribeInstanceInfo(ctx context.Context) (models.InstanceInfo func (m *Machine) refreshMachineConfiguration() error { resp, err := m.client.GetMachineConfiguration() if err != nil { + m.logger.Error("refreshMachineConfiguration", slog.String("err", resp.Error())) return err } - m.logger.Infof("refreshMachineConfiguration: %s", resp.Error()) m.machineConfig = *resp.Payload return nil } @@ -1099,7 +1099,7 @@ func (m *Machine) setupSignals() { return } - m.logger.Debugf("Setting up signal handler: %v", signals) + m.logger.Debug("Setting up signal handler", slog.Any("signals", signals)) sigchan := make(chan os.Signal, len(signals)) signal.Notify(sigchan, signals...) @@ -1108,7 +1108,7 @@ func (m *Machine) setupSignals() { for { select { case sig := <-sigchan: - m.logger.Debugf("Caught signal %s", sig) + m.logger.Debug("Caught signal", slog.Any("sig", sig)) // Some signals kill the process, some of them are not. m.cmd.Process.Signal(sig) case <-m.exitCh: @@ -1129,7 +1129,7 @@ func (m *Machine) PauseVM(ctx context.Context, opts ...PatchVMOpt) error { } if _, err := m.client.PatchVM(ctx, vm, opts...); err != nil { - m.logger.Errorf("failed to pause the VM: %v", err) + m.logger.Error("failed to pause the VM", slog.Any("err", err)) return err } @@ -1144,7 +1144,7 @@ func (m *Machine) ResumeVM(ctx context.Context, opts ...PatchVMOpt) error { } if _, err := m.client.PatchVM(ctx, vm, opts...); err != nil { - m.logger.Errorf("failed to resume the VM: %v", err) + m.logger.Error("failed to resume the VM", slog.Any("err", err)) return err } @@ -1160,7 +1160,7 @@ func (m *Machine) CreateSnapshot(ctx context.Context, memFilePath, snapshotPath } if _, err := m.client.CreateSnapshot(ctx, snapshotParams, opts...); err != nil { - m.logger.Errorf("failed to create a snapshot of the VM: %v", err) + m.logger.Error("failed to create a snapshot of the VM", slog.Any("err", err)) return err } @@ -1196,7 +1196,7 @@ func (m *Machine) CreateBalloon(ctx context.Context, amountMib int64, deflateOnO _, err := m.client.PutBalloon(ctx, &balloon, opts...) if err != nil { - m.logger.Errorf("Create balloon device failed : %s", err) + m.logger.Error("Create balloon device failed", slog.Any("err", err)) return err } @@ -1209,7 +1209,7 @@ func (m *Machine) GetBalloonConfig(ctx context.Context) (models.Balloon, error) var balloonConfig models.Balloon resp, err := m.client.DescribeBalloonConfig(ctx) if err != nil { - m.logger.Errorf("Getting balloonConfig: %s", err) + m.logger.Error("Getting balloonConfig", slog.Any("err", err)) return balloonConfig, err } @@ -1225,7 +1225,7 @@ func (m *Machine) UpdateBalloon(ctx context.Context, amountMib int64, opts ...Pa } _, err := m.client.PatchBalloon(ctx, &ballonUpdate, opts...) if err != nil { - m.logger.Errorf("Update balloon device failed : %s", err) + m.logger.Error("Update balloon device failed", slog.Any("err", err)) return err } @@ -1238,7 +1238,7 @@ func (m *Machine) GetBalloonStats(ctx context.Context) (models.BalloonStats, err var balloonStats models.BalloonStats resp, err := m.client.DescribeBalloonStats(ctx) if err != nil { - m.logger.Errorf("Getting balloonStats: %s", err) + m.logger.Error("Getting balloonStats", slog.Any("err", err)) return balloonStats, err } balloonStats = *resp.Payload @@ -1254,7 +1254,7 @@ func (m *Machine) UpdateBalloonStats(ctx context.Context, statsPollingIntervals } if _, err := m.client.PatchBalloonStatsInterval(ctx, &balloonStatsUpdate, opts...); err != nil { - m.logger.Errorf("UpdateBalloonStats failed: %v", err) + m.logger.Error("UpdateBalloonStats failed", slog.Any("err", err)) return err } diff --git a/machine_test.go b/machine_test.go index 6b330d30..9b7c7ef4 100644 --- a/machine_test.go +++ b/machine_test.go @@ -20,6 +20,7 @@ import ( "flag" "fmt" "io" + "log/slog" "net" "os" "os/exec" @@ -120,7 +121,7 @@ func TestNewMachine(t *testing.T) { Smt: Bool(false), }, }, - WithLogger(fctesting.NewLogEntry(t))) + WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) if err != nil { t.Fatalf("failed to create new machine: %v", err) } @@ -272,7 +273,7 @@ func TestJailerMicroVMExecution(t *testing.T) { } ctx := context.Background() - m, err := NewMachine(ctx, cfg, WithLogger(fctesting.NewLogEntry(t))) + m, err := NewMachine(ctx, cfg, WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) if err != nil { t.Fatalf("failed to create new machine: %v", err) } @@ -339,7 +340,7 @@ func TestMicroVMExecution(t *testing.T) { WithBin(getFirecrackerBinaryPath()). Build(ctx) - m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t))) + m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) if err != nil { t.Fatalf("failed to create new machine: %v", err) } @@ -421,7 +422,7 @@ func TestStartVMM(t *testing.T) { WithSocketPath(cfg.SocketPath). WithBin(getFirecrackerBinaryPath()). Build(ctx) - m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t))) + m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) if err != nil { t.Fatalf("failed to create new machine: %v", err) } @@ -523,7 +524,7 @@ func testLogAndMetrics(t *testing.T, logLevel string) string { } ctx := context.Background() cmd := configureBuilder(VMCommandBuilder{}.WithBin(getFirecrackerBinaryPath()), cfg).Build(ctx) - m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t))) + m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) require.NoError(t, err) timeout, cancel := context.WithTimeout(ctx, 250*time.Millisecond) @@ -580,7 +581,7 @@ func TestStartVMMOnce(t *testing.T) { WithSocketPath(cfg.SocketPath). WithBin(getFirecrackerBinaryPath()). Build(ctx) - m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t))) + m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) if err != nil { t.Fatalf("unexpected error: %v", err) } @@ -870,7 +871,7 @@ func TestStopVMMCleanup(t *testing.T) { WithSocketPath(cfg.SocketPath). WithBin(getFirecrackerBinaryPath()). Build(ctx) - m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t))) + m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) require.NoError(t, err) err = m.Start(ctx) require.NoError(t, err) @@ -907,7 +908,7 @@ func TestWaitForSocket(t *testing.T) { m := Machine{ Cfg: Config{SocketPath: filename}, - logger: fctesting.NewLogEntry(t), + logger: fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), } go func() { @@ -920,13 +921,13 @@ func TestWaitForSocket(t *testing.T) { }() // Socket file created, HTTP request succeeded - m.client = NewClient(filename, fctesting.NewLogEntry(t), true, WithOpsClient(&okClient)) + m.client = NewClient(filename, fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), true, WithOpsClient(&okClient)) if err := m.waitForSocket(500*time.Millisecond, errchan); err != nil { t.Errorf("waitForSocket returned unexpected error %s", err) } // Socket file exists, HTTP request failed - m.client = NewClient(filename, fctesting.NewLogEntry(t), true, WithOpsClient(&errClient)) + m.client = NewClient(filename, fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), true, WithOpsClient(&errClient)) if err := m.waitForSocket(500*time.Millisecond, errchan); err != context.DeadlineExceeded { t.Error("waitforSocket did not return an expected timeout error") } @@ -999,7 +1000,7 @@ func TestMicroVMExecutionWithMmdsV2(t *testing.T) { WithBin(getFirecrackerBinaryPath()). Build(ctx) - m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t))) + m, err := NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) if err != nil { t.Fatalf("failed to create new machine: %v", err) } @@ -1117,7 +1118,7 @@ func TestLogFiles(t *testing.T) { }, } ctx := context.Background() - client := NewClient("socket-path", fctesting.NewLogEntry(t), true, WithOpsClient(&opClient)) + client := NewClient("socket-path", fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), true, WithOpsClient(&opClient)) stdoutPath := filepath.Join(testDataPath, "stdout.log") stderrPath := filepath.Join(testDataPath, "stderr.log") @@ -1152,7 +1153,7 @@ func TestLogFiles(t *testing.T) { cfg, WithClient(client), WithProcessRunner(cmd), - WithLogger(fctesting.NewLogEntry(t)), + WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout)), ) if err != nil { t.Fatalf("failed to create new machine: %v", err) @@ -1215,7 +1216,7 @@ func TestCaptureFifoToFile(t *testing.T) { m := &Machine{ exitCh: make(chan struct{}), } - if err := m.captureFifoToFile(context.Background(), fctesting.NewLogEntry(t), fifoPath, testWriter); err != nil { + if err := m.captureFifoToFile(context.Background(), fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), fifoPath, testWriter); err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1261,7 +1262,7 @@ func TestCaptureFifoToFile_nonblock(t *testing.T) { m := &Machine{ exitCh: make(chan struct{}), } - if err := m.captureFifoToFile(context.Background(), fctesting.NewLogEntry(t), fifoPath, testWriter); err != nil { + if err := m.captureFifoToFile(context.Background(), fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), fifoPath, testWriter); err != nil { t.Errorf("Unexpected error: %v", err) } @@ -1395,7 +1396,7 @@ func TestPID(t *testing.T) { WithBin(getFirecrackerBinaryPath()). Build(ctx) - m, err = NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t))) + m, err = NewMachine(ctx, cfg, WithProcessRunner(cmd), WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout))) if err != nil { t.Errorf("expected no error during create machine, but received %v", err) } @@ -1459,9 +1460,7 @@ func TestCaptureFifoToFile_leak(t *testing.T) { buf := bytes.NewBuffer(nil) loggerBuffer := bytes.NewBuffer(nil) - logger := fctesting.NewLogEntry(t) - logger.Logger.Level = logrus.WarnLevel - logger.Logger.Out = loggerBuffer + logger := fctesting.NewLogEntry(t, slog.LevelWarn, loggerBuffer) done := make(chan error) err = m.captureFifoToFileWithChannel(context.Background(), logger, fifoPath, buf, done) @@ -1546,7 +1545,9 @@ func TestWait(t *testing.T) { // some unexported members args := m.cmd.Args[1:] m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) - }, WithLogger(logrus.NewEntry(machineLogger))) + }, + WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil)))) + require.NoError(t, err) err = m.Start(vmContext) @@ -1741,7 +1742,7 @@ func TestSignalForwarding(t *testing.T) { opClient := fctesting.MockClient{} ctx := context.Background() - client := NewClient(cfg.SocketPath, fctesting.NewLogEntry(t), true, WithOpsClient(&opClient)) + client := NewClient(cfg.SocketPath, fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout), true, WithOpsClient(&opClient)) fd, err := net.Listen("unix", cfg.SocketPath) if err != nil { @@ -1762,7 +1763,7 @@ func TestSignalForwarding(t *testing.T) { cfg, WithClient(client), WithProcessRunner(cmd), - WithLogger(fctesting.NewLogEntry(t)), + WithLogger(fctesting.NewLogEntry(t, slog.LevelDebug, os.Stdout)), ) if err != nil { t.Fatalf("failed to create new machine: %v", err) @@ -1898,7 +1899,8 @@ func TestPauseResume(t *testing.T) { // some unexported members args := m.cmd.Args[1:] m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) - }, WithLogger(logrus.NewEntry(machineLogger))) + }, + WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil)))) require.NoError(t, err) err = m.PauseVM(ctx) @@ -1977,7 +1979,8 @@ func TestCreateSnapshot(t *testing.T) { // some unexported members args := m.cmd.Args[1:] m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) - }, WithLogger(logrus.NewEntry(machineLogger))) + }, + WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil)))) require.NoError(t, err) err = m.Start(ctx) @@ -2092,7 +2095,8 @@ func TestLoadSnapshot(t *testing.T) { // some unexported members args := m.cmd.Args[1:] m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) - }, WithLogger(logrus.NewEntry(machineLogger))) + }, + WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil)))) require.NoError(t, err) err = m.Start(ctx) @@ -2129,9 +2133,11 @@ func TestLoadSnapshot(t *testing.T) { // some unexported members args := m.cmd.Args[1:] m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) - }, WithLogger(logrus.NewEntry(machineLogger)), WithSnapshot(memPath, snapPath, func(config *SnapshotConfig) { - config.ResumeVM = true - })) + }, + WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil))), + WithSnapshot(memPath, snapPath, func(config *SnapshotConfig) { + config.ResumeVM = true + })) require.NoError(t, err) require.Equal(t, m.Cfg.Snapshot.ResumeVM, true) @@ -2152,7 +2158,8 @@ func TestLoadSnapshot(t *testing.T) { // some unexported members args := m.cmd.Args[1:] m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) - }, WithLogger(logrus.NewEntry(machineLogger))) + }, + WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil)))) require.NoError(t, err) err = m.Start(ctx) @@ -2187,7 +2194,8 @@ func TestLoadSnapshot(t *testing.T) { // some unexported members args := m.cmd.Args[1:] m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) - }, WithLogger(logrus.NewEntry(machineLogger)), WithSnapshot("", snapPath, WithMemoryBackend("File", memPath))) + }, WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil))), + WithSnapshot("", snapPath, WithMemoryBackend("File", memPath))) require.NoError(t, err) err = m.Start(ctx) @@ -2210,7 +2218,7 @@ func TestLoadSnapshot(t *testing.T) { // some unexported members args := m.cmd.Args[1:] m.cmd = exec.Command(getFirecrackerBinaryPath(), args...) - }, WithLogger(logrus.NewEntry(machineLogger)), WithSnapshot(memPath, snapPath)) + }, WithLogger(slog.New(slog.NewTextHandler(os.Stdout, nil))), WithSnapshot(memPath, snapPath)) require.NoError(t, err) err = m.Start(ctx) diff --git a/network.go b/network.go index 35352996..358971b0 100644 --- a/network.go +++ b/network.go @@ -16,17 +16,18 @@ package firecracker import ( "context" "fmt" + "log/slog" "net" "os" "path/filepath" "runtime" + "strings" "github.com/containernetworking/cni/libcni" "github.com/containernetworking/cni/pkg/types" current "github.com/containernetworking/cni/pkg/types/100" "github.com/containernetworking/plugins/pkg/ns" - log "github.com/sirupsen/logrus" "golang.org/x/sys/unix" models "github.com/firecracker-microvm/firecracker-go-sdk/client/models" @@ -97,7 +98,7 @@ func (networkInterfaces NetworkInterfaces) setupNetwork( ctx context.Context, vmID string, netNSPath string, - logger *log.Entry, + logger *slog.Logger, ) (error, []func() error) { var cleanupFuncs []func() error @@ -143,8 +144,8 @@ func (networkInterfaces NetworkInterfaces) setupNetwork( if vmNetConf.VMIPConfig != nil { if len(vmNetConf.VMNameservers) > 2 { - logger.Warnf("more than 2 nameservers provided from CNI result, only the first 2 %+v will be applied", - vmNetConf.VMNameservers[:2]) + logger.Warn("more than 2 nameservers provided from CNI result, only the first 2 will be applied", + slog.String("nameservers", strings.Join(vmNetConf.VMNameservers[:2], ","))) vmNetConf.VMNameservers = vmNetConf.VMNameservers[:2] } @@ -317,7 +318,7 @@ func (cniConf CNIConfiguration) asCNIRuntimeConf() *libcni.RuntimeConf { } } -func (cniConf CNIConfiguration) invokeCNI(ctx context.Context, logger *log.Entry) (*types.Result, error, []func() error) { +func (cniConf CNIConfiguration) invokeCNI(ctx context.Context, logger *slog.Logger) (*types.Result, error, []func() error) { var cleanupFuncs []func() error cniPlugin := libcni.NewCNIConfigWithCacheDir(cniConf.BinPath, cniConf.CacheDir, nil) @@ -360,7 +361,7 @@ func (cniConf CNIConfiguration) invokeCNI(ctx context.Context, logger *log.Entry // try to create a new network on top of a possibly half-deleted previous one. return nil, fmt.Errorf(errMsg+": %w", err), cleanupFuncs } - logger.Error(err, errMsg) + logger.Error("invoke cni failed", slog.Any("err", err), slog.String("errMsg", errMsg)) } // Append cleanup of the network list before calling AddNetworkList to handle diff --git a/opts.go b/opts.go index c3a70caf..2588e1d6 100644 --- a/opts.go +++ b/opts.go @@ -14,10 +14,10 @@ package firecracker import ( + "log/slog" "os/exec" "github.com/firecracker-microvm/firecracker-go-sdk/client/models" - "github.com/sirupsen/logrus" ) // Opt represents a functional option to help modify functionality of a Machine. @@ -33,7 +33,7 @@ func WithClient(client *Client) Opt { } // WithLogger will allow for the Machine to use the provided logger. -func WithLogger(logger *logrus.Entry) Opt { +func WithLogger(logger *slog.Logger) Opt { return func(machine *Machine) { machine.logger = logger }