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/kubernetes/BUILD.bazel b/core/internal/kubernetes/BUILD.bazel
index 69afe18..bef0eb7 100644
--- a/core/internal/kubernetes/BUILD.bazel
+++ b/core/internal/kubernetes/BUILD.bazel
@@ -26,6 +26,7 @@
         "//core/pkg/fileargs:go_default_library",
         "//core/pkg/fsquota:go_default_library",
         "//core/pkg/logbuffer:go_default_library",
+        "//core/pkg/logtree:go_default_library",
         "//core/proto/api:go_default_library",
         "@com_github_container_storage_interface_spec//lib/go/csi:go_default_library",
         "@io_bazel_rules_go//proto/wkt:wrappers_go_proto",
@@ -50,6 +51,5 @@
         "@org_golang_google_grpc//codes:go_default_library",
         "@org_golang_google_grpc//status:go_default_library",
         "@org_golang_x_sys//unix:go_default_library",
-        "@org_uber_go_zap//:go_default_library",
     ],
 )
diff --git a/core/internal/kubernetes/clusternet/BUILD.bazel b/core/internal/kubernetes/clusternet/BUILD.bazel
index dd5c58e..d011e2f 100644
--- a/core/internal/kubernetes/clusternet/BUILD.bazel
+++ b/core/internal/kubernetes/clusternet/BUILD.bazel
@@ -13,6 +13,7 @@
         "//core/internal/common/supervisor:go_default_library",
         "//core/internal/localstorage:go_default_library",
         "//core/pkg/jsonpatch:go_default_library",
+        "//core/pkg/logtree:go_default_library",
         "@com_github_vishvananda_netlink//:go_default_library",
         "@com_zx2c4_golang_wireguard_wgctrl//:go_default_library",
         "@com_zx2c4_golang_wireguard_wgctrl//wgtypes:go_default_library",
@@ -22,6 +23,5 @@
         "@io_k8s_client_go//informers:go_default_library",
         "@io_k8s_client_go//kubernetes:go_default_library",
         "@io_k8s_client_go//tools/cache:go_default_library",
-        "@org_uber_go_zap//:go_default_library",
     ],
 )
diff --git a/core/internal/kubernetes/clusternet/clusternet.go b/core/internal/kubernetes/clusternet/clusternet.go
index bb1f183..15e3d5b 100644
--- a/core/internal/kubernetes/clusternet/clusternet.go
+++ b/core/internal/kubernetes/clusternet/clusternet.go
@@ -33,12 +33,13 @@
 	"net"
 	"os"
 
+	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
+
 	"k8s.io/client-go/informers"
 
 	"k8s.io/client-go/kubernetes"
 
 	"github.com/vishvananda/netlink"
-	"go.uber.org/zap"
 	"golang.zx2c4.com/wireguard/wgctrl"
 	"golang.zx2c4.com/wireguard/wgctrl/wgtypes"
 	corev1 "k8s.io/api/core/v1"
@@ -66,7 +67,7 @@
 
 	wgClient *wgctrl.Client
 	privKey  wgtypes.Key
-	logger   *zap.Logger
+	logger   logtree.LeveledLogger
 }
 
 // ensureNode creates/updates the corresponding WireGuard peer entry for the given node objet
@@ -87,12 +88,12 @@
 	for _, addr := range newNode.Status.Addresses {
 		if addr.Type == corev1.NodeInternalIP {
 			if internalIP != nil {
-				s.logger.Warn("More than one NodeInternalIP specified, using the first one")
+				s.logger.Warningf("More than one NodeInternalIP specified, using the first one")
 				break
 			}
 			internalIP = net.ParseIP(addr.Address)
 			if internalIP == nil {
-				s.logger.Warn("failed to parse Internal IP")
+				s.logger.Warningf("Failed to parse Internal IP %s", addr.Address)
 			}
 		}
 	}
@@ -103,14 +104,13 @@
 	for _, podNetStr := range newNode.Spec.PodCIDRs {
 		_, podNet, err := net.ParseCIDR(podNetStr)
 		if err != nil {
-			s.logger.Warn("Node PodCIDR failed to parse, ignored", zap.Error(err), zap.String("node", newNode.Name))
+			s.logger.Warningf("Node %s PodCIDR failed to parse, ignored: %v", newNode.Name, err)
 			continue
 		}
 		allowedIPs = append(allowedIPs, *podNet)
 	}
 	allowedIPs = append(allowedIPs, net.IPNet{IP: internalIP, Mask: net.CIDRMask(32, 32)})
-	s.logger.Debug("Adding/Updating WireGuard peer node", zap.String("node", newNode.Name),
-		zap.String("endpointIP", internalIP.String()), zap.Any("allowedIPs", allowedIPs))
+	s.logger.V(1).Infof("Adding/Updating WireGuard peer node %s, endpoint %s, allowedIPs %+v", newNode.Name, internalIP.String(), allowedIPs)
 	// WireGuard's kernel side has create/update semantics on peers by default. So we can just add the peer multiple
 	// times to update it.
 	err = s.wgClient.ConfigureDevice(clusterNetDeviceName, wgtypes.Config{
@@ -244,31 +244,31 @@
 		AddFunc: func(new interface{}) {
 			newNode, ok := new.(*corev1.Node)
 			if !ok {
-				logger.Error("Received non-node item in node event handler", zap.Reflect("item", new))
+				logger.Errorf("Received non-node item %+v in node event handler", new)
 				return
 			}
 			if err := s.ensureNode(newNode); err != nil {
-				logger.Warn("Failed to sync node", zap.Error(err))
+				logger.Warningf("Failed to sync node: %v", err)
 			}
 		},
 		UpdateFunc: func(old, new interface{}) {
 			newNode, ok := new.(*corev1.Node)
 			if !ok {
-				logger.Error("Received non-node item in node event handler", zap.Reflect("item", new))
+				logger.Errorf("Received non-node item %+v in node event handler", new)
 				return
 			}
 			if err := s.ensureNode(newNode); err != nil {
-				logger.Warn("Failed to sync node", zap.Error(err))
+				logger.Warningf("Failed to sync node: %v", err)
 			}
 		},
 		DeleteFunc: func(old interface{}) {
 			oldNode, ok := old.(*corev1.Node)
 			if !ok {
-				logger.Error("Received non-node item in node event handler", zap.Reflect("item", oldNode))
+				logger.Errorf("Received non-node item %+v in node event handler", oldNode)
 				return
 			}
 			if err := s.removeNode(oldNode); err != nil {
-				logger.Warn("Failed to sync node", zap.Error(err))
+				logger.Warningf("Failed to sync node: %v", err)
 			}
 		},
 	})
diff --git a/core/internal/kubernetes/csi.go b/core/internal/kubernetes/csi.go
index e151396..def1d6d 100644
--- a/core/internal/kubernetes/csi.go
+++ b/core/internal/kubernetes/csi.go
@@ -24,9 +24,10 @@
 	"path/filepath"
 	"regexp"
 
+	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
+
 	"github.com/container-storage-interface/spec/lib/go/csi"
 	"github.com/golang/protobuf/ptypes/wrappers"
-	"go.uber.org/zap"
 	"golang.org/x/sys/unix"
 	"google.golang.org/grpc"
 	"google.golang.org/grpc/codes"
@@ -49,7 +50,7 @@
 	KubeletDirectory *localstorage.DataKubernetesKubeletDirectory
 	VolumesDirectory *localstorage.DataVolumesDirectory
 
-	logger *zap.Logger
+	logger logtree.LeveledLogger
 }
 
 func (s *csiPluginServer) Run(ctx context.Context) error {
@@ -240,7 +241,7 @@
 
 func (s *csiPluginServer) NotifyRegistrationStatus(ctx context.Context, req *pluginregistration.RegistrationStatus) (*pluginregistration.RegistrationStatusResponse, error) {
 	if req.Error != "" {
-		s.logger.Warn("Kubelet failed registering CSI plugin", zap.String("error", req.Error))
+		s.logger.Warningf("Kubelet failed registering CSI plugin: %v", req.Error)
 	}
 	return &pluginregistration.RegistrationStatusResponse{}, nil
 }
diff --git a/core/internal/kubernetes/pki/BUILD.bazel b/core/internal/kubernetes/pki/BUILD.bazel
index e188bfa..ab45382 100644
--- a/core/internal/kubernetes/pki/BUILD.bazel
+++ b/core/internal/kubernetes/pki/BUILD.bazel
@@ -11,9 +11,9 @@
     visibility = ["//core:__subpackages__"],
     deps = [
         "//core/internal/common:go_default_library",
+        "//core/pkg/logtree:go_default_library",
         "@io_etcd_go_etcd//clientv3:go_default_library",
         "@io_k8s_client_go//tools/clientcmd:go_default_library",
         "@io_k8s_client_go//tools/clientcmd/api:go_default_library",
-        "@org_uber_go_zap//:go_default_library",
     ],
 )
diff --git a/core/internal/kubernetes/pki/kubernetes.go b/core/internal/kubernetes/pki/kubernetes.go
index 0de8f6d..9931f03 100644
--- a/core/internal/kubernetes/pki/kubernetes.go
+++ b/core/internal/kubernetes/pki/kubernetes.go
@@ -25,7 +25,7 @@
 	"fmt"
 	"net"
 
-	"go.uber.org/zap"
+	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
 
 	"go.etcd.io/etcd/clientv3"
 	"k8s.io/client-go/tools/clientcmd"
@@ -77,12 +77,12 @@
 // KubernetesPKI manages all PKI resources required to run Kubernetes on Smalltown. It contains all static certificates,
 // which can be retrieved, or be used to generate Kubeconfigs from.
 type KubernetesPKI struct {
-	logger       *zap.Logger
+	logger       logtree.LeveledLogger
 	KV           clientv3.KV
 	Certificates map[KubeCertificateName]*Certificate
 }
 
-func NewKubernetes(l *zap.Logger, kv clientv3.KV) *KubernetesPKI {
+func NewKubernetes(l logtree.LeveledLogger, kv clientv3.KV) *KubernetesPKI {
 	pki := KubernetesPKI{
 		logger:       l,
 		KV:           kv,
@@ -121,7 +121,7 @@
 // EnsureAll ensures that all static certificates (and the serviceaccount key) are present on etcd.
 func (k *KubernetesPKI) EnsureAll(ctx context.Context) error {
 	for n, v := range k.Certificates {
-		k.logger.Info("ensureing certificate existence", zap.String("name", string(n)))
+		k.logger.Infof("Ensuring %s exists", string(n))
 		_, _, err := v.Ensure(ctx, k.KV)
 		if err != nil {
 			return fmt.Errorf("could not ensure certificate %q exists: %w", n, err)
diff --git a/core/internal/kubernetes/provisioner.go b/core/internal/kubernetes/provisioner.go
index 0e9e419..3be25e0 100644
--- a/core/internal/kubernetes/provisioner.go
+++ b/core/internal/kubernetes/provisioner.go
@@ -24,7 +24,8 @@
 	"os"
 	"path/filepath"
 
-	"go.uber.org/zap"
+	"git.monogon.dev/source/nexantic.git/core/pkg/logtree"
+
 	v1 "k8s.io/api/core/v1"
 	storagev1 "k8s.io/api/storage/v1"
 	apierrs "k8s.io/apimachinery/pkg/api/errors"
@@ -64,7 +65,7 @@
 	pvcInformer          coreinformers.PersistentVolumeClaimInformer
 	pvInformer           coreinformers.PersistentVolumeInformer
 	storageClassInformer storageinformers.StorageClassInformer
-	logger               *zap.Logger
+	logger               logtree.LeveledLogger
 }
 
 // runCSIProvisioner runs the main provisioning machinery. It consists of a bunch of informers which keep track of
@@ -144,7 +145,7 @@
 func (p *csiProvisionerServer) enqueueClaim(obj interface{}) {
 	key, err := cache.MetaNamespaceKeyFunc(obj)
 	if err != nil {
-		p.logger.Error("Not queuing PVC because key could not be derived", zap.Error(err))
+		p.logger.Errorf("Not queuing PVC because key could not be derived: %v", err)
 		return
 	}
 	p.claimQueue.Add(key)
@@ -154,7 +155,7 @@
 func (p *csiProvisionerServer) enqueuePV(obj interface{}) {
 	key, err := cache.MetaNamespaceKeyFunc(obj)
 	if err != nil {
-		p.logger.Error("Not queuing PV because key could not be derived", zap.Error(err))
+		p.logger.Errorf("Not queuing PV because key could not be derived: %v", err)
 		return
 	}
 	p.pvQueue.Add(key)
@@ -174,13 +175,12 @@
 			key, ok := obj.(string)
 			if !ok {
 				queue.Forget(obj)
-				p.logger.Error("Expected string in workqueue", zap.Any("actual", obj))
+				p.logger.Errorf("Expected string in workqueue, got %+v", obj)
 				return
 			}
 
 			if err := process(key); err != nil {
-				p.logger.Warn("Failed processing item, requeueing", zap.String("name", key),
-					zap.Int("num_requeues", queue.NumRequeues(obj)), zap.Error(err))
+				p.logger.Warningf("Failed processing item %q, requeueing (numrequeues: %d): %v", key, queue.NumRequeues(obj), err)
 				queue.AddRateLimited(obj)
 			}
 
@@ -263,7 +263,7 @@
 	volumeID := "pvc-" + string(pvc.ObjectMeta.UID)
 	volumePath := p.volumePath(volumeID)
 
-	p.logger.Info("Creating local PV", zap.String("volume-id", volumeID))
+	p.logger.Infof("Creating local PV %s", volumeID)
 	if err := os.Mkdir(volumePath, 0644); err != nil && !os.IsExist(err) {
 		return fmt.Errorf("failed to create volume directory: %w", err)
 	}
@@ -346,7 +346,7 @@
 	volumePath := p.volumePath(pv.Spec.CSI.VolumeHandle)
 
 	// Log deletes for auditing purposes
-	p.logger.Info("Deleting persistent volume", zap.String("name", pv.Spec.CSI.VolumeHandle))
+	p.logger.Infof("Deleting persistent volume %s", pv.Spec.CSI.VolumeHandle)
 	if err := fsquota.SetQuota(volumePath, 0, 0); err != nil {
 		// We record these here manually since a successful deletion removes the PV we'd be attaching them to
 		p.recorder.Eventf(pv, v1.EventTypeWarning, "DeprovisioningFailed", "Failed to remove quota: %v", err)
diff --git a/core/internal/kubernetes/reconciler/BUILD.bazel b/core/internal/kubernetes/reconciler/BUILD.bazel
index fb77ae2..dcfbc49 100644
--- a/core/internal/kubernetes/reconciler/BUILD.bazel
+++ b/core/internal/kubernetes/reconciler/BUILD.bazel
@@ -21,7 +21,6 @@
         "@io_k8s_api//storage/v1:go_default_library",
         "@io_k8s_apimachinery//pkg/apis/meta/v1:go_default_library",
         "@io_k8s_client_go//kubernetes:go_default_library",
-        "@org_uber_go_zap//:go_default_library",
     ],
 )
 
diff --git a/core/internal/kubernetes/reconciler/reconciler.go b/core/internal/kubernetes/reconciler/reconciler.go
index c972996..24a34ef 100644
--- a/core/internal/kubernetes/reconciler/reconciler.go
+++ b/core/internal/kubernetes/reconciler/reconciler.go
@@ -31,7 +31,6 @@
 
 	meta "k8s.io/apimachinery/pkg/apis/meta/v1"
 
-	"go.uber.org/zap"
 	"k8s.io/client-go/kubernetes"
 )
 
@@ -120,7 +119,7 @@
 		reconcileAll := func() {
 			for name, resource := range resources {
 				if err := reconcile(ctx, resource); err != nil {
-					log.Warn("Failed to reconcile built-in resources", zap.String("kind", name), zap.Error(err))
+					log.Warningf("Failed to reconcile built-in resources %s: %v", name, err)
 				}
 			}
 		}