core: replace zap with logtree
Test Plan: Effective refactor. Only tests that could be affected are e2e tests that should continue to run, because we still are logging into the qemu console, even if differently.
X-Origin-Diff: phab/D642
GitOrigin-RevId: 0f12b1bc985af08a3cc269569273184321763e4b
diff --git a/core/internal/common/supervisor/BUILD.bazel b/core/internal/common/supervisor/BUILD.bazel
index ca8b513..9f940f0 100644
--- a/core/internal/common/supervisor/BUILD.bazel
+++ b/core/internal/common/supervisor/BUILD.bazel
@@ -12,9 +12,9 @@
importpath = "git.monogon.dev/source/nexantic.git/core/internal/common/supervisor",
visibility = ["//core:__subpackages__"],
deps = [
+ "//core/pkg/logtree:go_default_library",
"@com_github_cenkalti_backoff_v4//:go_default_library",
"@org_golang_google_grpc//:go_default_library",
- "@org_uber_go_zap//:go_default_library",
],
)
@@ -22,5 +22,4 @@
name = "go_default_test",
srcs = ["supervisor_test.go"],
embed = [":go_default_library"],
- deps = ["@org_uber_go_zap//:go_default_library"],
)
diff --git a/core/internal/common/supervisor/supervisor.go b/core/internal/common/supervisor/supervisor.go
index db4489e..ef8a9cd 100644
--- a/core/internal/common/supervisor/supervisor.go
+++ b/core/internal/common/supervisor/supervisor.go
@@ -22,9 +22,10 @@
import (
"context"
+ "io"
"sync"
- "go.uber.org/zap"
+ "git.monogon.dev/source/nexantic.git/core/pkg/logtree"
)
// A Runnable is a function that will be run in a goroutine, and supervised throughout its lifetime. It can in turn
@@ -70,14 +71,6 @@
SignalDone
)
-// Logger returns a Zap logger that will be named after the Distinguished Name of a the runnable (ie its place in the
-// supervision tree, dot-separated).
-func Logger(ctx context.Context) *zap.Logger {
- node, unlock := fromContext(ctx)
- defer unlock()
- return node.getLogger()
-}
-
// supervisor represents and instance of the supervision system. It keeps track of a supervision tree and a request
// channel to its internal processor goroutine.
type supervisor struct {
@@ -86,10 +79,10 @@
// root is the root node of the supervision tree, named 'root'. It represents the Runnable started with the
// supervisor.New call.
root *node
- // logger is the Zap logger used to create loggers available to runnables.
- logger *zap.Logger
- // ilogger is the Zap logger used for internal logging by the supervisor.
- ilogger *zap.Logger
+ // logtree is the main logtree exposed to runnables and used internally.
+ logtree *logtree.LogTree
+ // ilogger is the internal logger logging to "supervisor" in the logtree.
+ ilogger logtree.LeveledLogger
// pReq is an interface channel to the lifecycle processor of the supervisor.
pReq chan *processorRequest
@@ -109,12 +102,17 @@
}
)
+func WithExistingLogtree(lt *logtree.LogTree) SupervisorOpt {
+ return func(s *supervisor) {
+ s.logtree = lt
+ }
+}
+
// New creates a new supervisor with its root running the given root runnable.
// The given context can be used to cancel the entire supervision tree.
-func New(ctx context.Context, logger *zap.Logger, rootRunnable Runnable, opts ...SupervisorOpt) *supervisor {
+func New(ctx context.Context, rootRunnable Runnable, opts ...SupervisorOpt) *supervisor {
sup := &supervisor{
- logger: logger,
- ilogger: logger.Named("supervisor"),
+ logtree: logtree.New(),
pReq: make(chan *processorRequest),
}
@@ -122,6 +120,7 @@
o(sup)
}
+ sup.ilogger = sup.logtree.MustLeveledFor("supervisor")
sup.root = newNode("root", rootRunnable, sup, nil)
go sup.processor(ctx)
@@ -132,3 +131,15 @@
return sup
}
+
+func Logger(ctx context.Context) logtree.LeveledLogger {
+ node, unlock := fromContext(ctx)
+ defer unlock()
+ return node.sup.logtree.MustLeveledFor(logtree.DN(node.dn()))
+}
+
+func RawLogger(ctx context.Context) io.Writer {
+ node, unlock := fromContext(ctx)
+ defer unlock()
+ return node.sup.logtree.MustRawFor(logtree.DN(node.dn()))
+}
diff --git a/core/internal/common/supervisor/supervisor_node.go b/core/internal/common/supervisor/supervisor_node.go
index e2af62c..a7caf82 100644
--- a/core/internal/common/supervisor/supervisor_node.go
+++ b/core/internal/common/supervisor/supervisor_node.go
@@ -23,7 +23,6 @@
"strings"
"github.com/cenkalti/backoff/v4"
- "go.uber.org/zap"
)
// node is a supervision tree node. It represents the state of a Runnable within this tree, its relation to other tree
@@ -281,8 +280,3 @@
n.bo.Reset()
}
}
-
-// getLogger creates a new logger for a given supervisor node, to be used by its runnable.
-func (n *node) getLogger() *zap.Logger {
- return n.sup.logger.Named(n.dn())
-}
diff --git a/core/internal/common/supervisor/supervisor_processor.go b/core/internal/common/supervisor/supervisor_processor.go
index c72ef89..965a667 100644
--- a/core/internal/common/supervisor/supervisor_processor.go
+++ b/core/internal/common/supervisor/supervisor_processor.go
@@ -22,8 +22,6 @@
"fmt"
"runtime/debug"
"time"
-
- "go.uber.org/zap"
)
// The processor maintains runnable goroutines - ie., when requested will start one, and then once it exists it will
@@ -76,7 +74,7 @@
for {
select {
case <-ctx.Done():
- s.ilogger.Info("supervisor processor exiting...", zap.Error(ctx.Err()))
+ s.ilogger.Infof("supervisor processor exiting: %v", ctx.Err())
s.processKill()
s.ilogger.Info("supervisor exited")
return
@@ -213,7 +211,7 @@
err = fmt.Errorf("returned error when %s: %w", n.state, err)
}
- s.ilogger.Error("Runnable died", zap.String("dn", n.dn()), zap.Error(err))
+ s.ilogger.Errorf("Runnable %s died: %v", n.dn(), err)
// Mark as dead.
n.state = nodeStateDead
@@ -393,7 +391,7 @@
// Prepare node for rescheduling - remove its children, reset its state to new.
n.reset()
- s.ilogger.Info("rescheduling supervised node", zap.String("dn", dn), zap.Duration("backoff", bo))
+ s.ilogger.Infof("rescheduling supervised node %s with backoff %s", dn, bo.String())
// Reschedule node runnable to run after backoff.
go func(n *node, bo time.Duration) {
diff --git a/core/internal/common/supervisor/supervisor_test.go b/core/internal/common/supervisor/supervisor_test.go
index 9a190c9..9c7bdb7 100644
--- a/core/internal/common/supervisor/supervisor_test.go
+++ b/core/internal/common/supervisor/supervisor_test.go
@@ -21,8 +21,6 @@
"fmt"
"testing"
"time"
-
- "go.uber.org/zap"
)
func runnableBecomesHealthy(healthy, done chan struct{}) Runnable {
@@ -182,10 +180,9 @@
h2 := make(chan struct{})
d2 := make(chan struct{})
- log, _ := zap.NewDevelopment()
ctx, ctxC := context.WithCancel(context.Background())
defer ctxC()
- s := New(ctx, log, func(ctx context.Context) error {
+ s := New(ctx, func(ctx context.Context) error {
err := RunGroup(ctx, map[string]Runnable{
"one": runnableBecomesHealthy(h1, d1),
"two": runnableBecomesHealthy(h2, d2),
@@ -217,10 +214,9 @@
d1 := make(chan struct{})
two := newRC()
- log, _ := zap.NewDevelopment()
ctx, ctxC := context.WithTimeout(context.Background(), 10*time.Second)
defer ctxC()
- s := New(ctx, log, func(ctx context.Context) error {
+ s := New(ctx, func(ctx context.Context) error {
err := RunGroup(ctx, map[string]Runnable{
"one": runnableBecomesHealthy(h1, d1),
"two": two.runnable(),
@@ -266,11 +262,9 @@
d1 := make(chan struct{})
two := newRC()
- log, _ := zap.NewDevelopment()
-
ctx, ctxC := context.WithTimeout(context.Background(), 10*time.Second)
defer ctxC()
- s := New(ctx, log, func(ctx context.Context) error {
+ s := New(ctx, func(ctx context.Context) error {
err := RunGroup(ctx, map[string]Runnable{
"one": runnableSpawnsMore(h1, d1, 5),
"two": two.runnable(),
@@ -315,10 +309,9 @@
d1 := make(chan struct{})
two := newRC()
- log, _ := zap.NewDevelopment()
ctx, ctxC := context.WithCancel(context.Background())
defer ctxC()
- s := New(ctx, log, func(ctx context.Context) error {
+ s := New(ctx, func(ctx context.Context) error {
err := RunGroup(ctx, map[string]Runnable{
"one": runnableBecomesHealthy(h1, d1),
"two": two.runnable(),
@@ -359,10 +352,9 @@
}
func TestMultipleLevelFailure(t *testing.T) {
- log, _ := zap.NewDevelopment()
ctx, ctxC := context.WithCancel(context.Background())
defer ctxC()
- New(ctx, log, func(ctx context.Context) error {
+ New(ctx, func(ctx context.Context) error {
err := RunGroup(ctx, map[string]Runnable{
"one": runnableSpawnsMore(nil, nil, 4),
"two": runnableSpawnsMore(nil, nil, 4),
@@ -379,11 +371,10 @@
func TestBackoff(t *testing.T) {
one := newRC()
- log, _ := zap.NewDevelopment()
ctx, ctxC := context.WithTimeout(context.Background(), 20*time.Second)
defer ctxC()
- s := New(ctx, log, func(ctx context.Context) error {
+ s := New(ctx, func(ctx context.Context) error {
if err := Run(ctx, "one", one.runnable()); err != nil {
return err
}
@@ -485,10 +476,9 @@
}
}
- log, _ := zap.NewDevelopment()
ctx, ctxC := context.WithCancel(context.Background())
defer ctxC()
- New(ctx, log, func(ctx context.Context) error {
+ New(ctx, func(ctx context.Context) error {
RunGroup(ctx, map[string]Runnable{
"one": one,
"oneSibling": oneSibling.runnable(),
@@ -538,12 +528,10 @@
return nil
}
- log, _ := zap.NewDevelopment()
-
// Start a supervision tree with a root runnable.
ctx, ctxC := context.WithCancel(context.Background())
defer ctxC()
- New(ctx, log, func(ctx context.Context) error {
+ New(ctx, func(ctx context.Context) error {
err := Run(ctx, "child", child)
if err != nil {
return fmt.Errorf("could not run 'child': %w", err)