From 4b91f4769b8cd01453d83cb0c323a85cfcf3e930 Mon Sep 17 00:00:00 2001 From: Janelle Law Date: Thu, 12 Oct 2023 17:28:26 +0000 Subject: [PATCH 1/4] setup slog logger --- go.mod | 2 + go.sum | 4 ++ logging.go | 205 ++++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 155 insertions(+), 56 deletions(-) diff --git a/go.mod b/go.mod index 335bbd4..e117078 100644 --- a/go.mod +++ b/go.mod @@ -44,6 +44,7 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/kr/pretty v0.3.1 // indirect + github.com/lmittmann/tint v1.0.2 // indirect github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.19 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect @@ -53,6 +54,7 @@ require ( github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/samber/lo v1.38.1 // indirect + github.com/samber/slog-multi v1.0.2 github.com/stretchr/testify v1.8.4 // indirect go.opentelemetry.io/contrib/propagators/aws v1.17.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect diff --git a/go.sum b/go.sum index 7b2c288..a1378ea 100644 --- a/go.sum +++ b/go.sum @@ -182,6 +182,8 @@ github.com/kralicky/gpkg v0.0.0-20220311205216-0d8ea9557555 h1:w/v9aYd9gdL0pEofC github.com/kralicky/gpkg v0.0.0-20220311205216-0d8ea9557555/go.mod h1:EJrGSfmocDg2CBjHDm3zy9oxNKCSGhf+MNTiN1DRbKA= github.com/kralicky/ragu v1.0.11-0.20230530191519-84f5aaa5fd69 h1:Iqg6oc2ty1dLRiBJfj7EwyKy1O81zL8+wcW5uMRlnIg= github.com/kralicky/ragu v1.0.11-0.20230530191519-84f5aaa5fd69/go.mod h1:njQGnwU5IHm4Qx6/oOY0ll7Z6WA0apfP0ClpVA0M27Q= +github.com/lmittmann/tint v1.0.2 h1:9XZ+JvEzjvd3VNVugYqo3j+dl0NRju8k9FquAusJExM= +github.com/lmittmann/tint v1.0.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= @@ -215,6 +217,8 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/slog-multi v1.0.2 h1:6BVH9uHGAsiGkbbtQgAOQJMpKgV8unMrHhhJaw+X1EQ= +github.com/samber/slog-multi v1.0.2/go.mod h1:uLAvHpGqbYgX4FSL0p1ZwoLuveIAJvBECtE07XmYvFo= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= diff --git a/logging.go b/logging.go index f9ec79a..0e47bf4 100644 --- a/logging.go +++ b/logging.go @@ -1,21 +1,26 @@ package totem import ( + "context" "fmt" + "log/slog" "math" "math/rand" "os" + "path/filepath" + "strconv" "strings" "github.com/charmbracelet/lipgloss" gsync "github.com/kralicky/gpkg/sync" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" + "github.com/lmittmann/tint" + slogmulti "github.com/samber/slog-multi" ) var ( - Log *zap.Logger - LogLevel = zap.NewAtomicLevelAt(zapcore.WarnLevel) + Log *slog.Logger + LogLevel = slog.LevelWarn + OutputPath = os.Stderr ) var ( @@ -23,67 +28,90 @@ var ( callerStyle = lipgloss.NewStyle().Faint(true) ) +const ( + ansiRed = "\033[91m" + ansiYellow = "\033[93m" + ansiBlue = "\033[94m" + ansiMagenta = "\033[95m" + ansiReset = "\033[0m" + ISO8601Format = "2006-01-02 15:04:05:000" +) + +func parseLogLevel(levelStr string) slog.Level { + var level slog.Level + switch levelStr { + case "debug": + level = slog.LevelDebug + case "info": + level = slog.LevelInfo + case "warn": + level = slog.LevelWarn + case "error": + level = slog.LevelError + default: + level = LogLevel + } + return level +} + func init() { colorCache.Store("totem", lipgloss.NewStyle().Background(lipgloss.Color("15")).Foreground(lipgloss.Color("0"))) + logLevel := LogLevel if levelStr, ok := os.LookupEnv("TOTEM_LOG_LEVEL"); ok { - if level, err := zapcore.ParseLevel(levelStr); err == nil { - LogLevel.SetLevel(level) - } + logLevel = parseLogLevel(levelStr) } - encoderConfig := zapcore.EncoderConfig{ - MessageKey: "M", - LevelKey: "L", - TimeKey: "T", - NameKey: "N", - CallerKey: "C", - FunctionKey: "", - StacktraceKey: "S", - LineEnding: "\n", - EncodeTime: zapcore.ISO8601TimeEncoder, - EncodeCaller: func(ec zapcore.EntryCaller, enc zapcore.PrimitiveArrayEncoder) { - path := ec.FullPath() - // remove the package name - if i := strings.LastIndex(path, "/"); i >= 0 { - path = path[i+1:] - } - enc.AppendString(callerStyle.Render(path)) - }, - EncodeName: func(s string, enc zapcore.PrimitiveArrayEncoder) { - parts := strings.Split(s, ".") - sb := strings.Builder{} - for i, part := range parts { - if c, ok := colorCache.Load(part); !ok { - newStyle := newRandomForegroundStyle() - colorCache.Store(part, newStyle) - sb.WriteString(newStyle.Render(part)) - } else { - sb.WriteString(c.Render(part)) + + options := &tint.Options{ + AddSource: true, + Level: logLevel, + NoColor: false, + ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr { + switch a.Key { + case slog.TimeKey: // format time + a.Value = slog.StringValue(a.Value.Time().Format(ISO8601Format)) + case slog.SourceKey: // remove package name + sb := strings.Builder{} + switch cv := a.Value.Any().(type) { + case *slog.Source: + _, filename := filepath.Split(cv.File) + sb.WriteString(filename) + sb.WriteByte(':') + sb.WriteString(strconv.Itoa(cv.Line)) + a.Value = slog.StringValue(callerStyle.Render(sb.String())) } - if i < len(parts)-1 { - sb.WriteString(".") + case slog.LevelKey: // format level string + switch cv := a.Value.Any().(type) { + case slog.Level: + lvlStr := strings.Builder{} + switch cv { + case slog.LevelDebug: + lvlStr.WriteString(ansiMagenta) + lvlStr.WriteString("DEBUG") + case slog.LevelInfo: + lvlStr.WriteString(ansiBlue) + lvlStr.WriteString("INFO") + case slog.LevelWarn: + lvlStr.WriteString(ansiYellow) + lvlStr.WriteString("WARN") + case slog.LevelError: + lvlStr.WriteString(ansiRed) + lvlStr.WriteString("ERROR") + default: + return a + } + lvlStr.WriteString(ansiReset) + a.Value = slog.StringValue(lvlStr.String()) + default: + return a } } - enc.AppendString(sb.String()) + return a }, - EncodeDuration: zapcore.MillisDurationEncoder, - ConsoleSeparator: " ", - EncodeLevel: zapcore.CapitalColorLevelEncoder, - } - zapConfig := zap.Config{ - Level: LogLevel, - Development: false, - DisableCaller: false, - DisableStacktrace: false, - Encoding: "console", - EncoderConfig: encoderConfig, - OutputPaths: []string{"stderr"}, - ErrorOutputPaths: []string{"stderr"}, } - lg, err := zapConfig.Build() - if err != nil { - panic(err) - } - Log = lg.Named("totem") + + nameFormatter := newNameFormatMiddleware() + + Log = slog.New(slogmulti.Pipe(nameFormatter).Handler(tint.NewHandler(OutputPath, options))).WithGroup("totem") } func newRandomForegroundStyle() lipgloss.Style { @@ -92,3 +120,68 @@ func newRandomForegroundStyle() lipgloss.Style { b := math.Round(rand.Float64()*127) + 127 return lipgloss.NewStyle().Foreground(lipgloss.Color(fmt.Sprintf("#%02x%02x%02x", int(r), int(g), int(b)))) } + +func newNameFormatMiddleware() slogmulti.Middleware { + return func(next slog.Handler) slog.Handler { + return &nameFormatMiddleware{ + next: next, + } + } +} + +type nameFormatMiddleware struct { + next slog.Handler + groups []string +} + +func (h *nameFormatMiddleware) Enabled(ctx context.Context, level slog.Level) bool { + return h.next.Enabled(ctx, level) +} + +func (h *nameFormatMiddleware) Handle(ctx context.Context, record slog.Record) error { + attrs := []slog.Attr{} + + record.Attrs(func(attr slog.Attr) bool { + attrs = append(attrs, attr) + return true + }) + + sb := strings.Builder{} + for i, part := range h.groups { + if c, ok := colorCache.Load(part); !ok { + newStyle := newRandomForegroundStyle() + colorCache.Store(part, newStyle) + sb.WriteString(newStyle.Render(part)) + } else { + sb.WriteString(c.Render(part)) + } + if i < len(h.groups)-1 { + sb.WriteString(".") + } else { + sb.WriteByte(' ') + } + } + + // insert logger name before message + sb.WriteString(record.Message) + + record = slog.NewRecord(record.Time, record.Level, sb.String(), record.PC) + record.AddAttrs(attrs...) + + return h.next.Handle(ctx, record) +} + +func (h *nameFormatMiddleware) WithAttrs(attrs []slog.Attr) slog.Handler { + + return &nameFormatMiddleware{ + next: h.next.WithAttrs(attrs), + groups: h.groups, + } +} + +func (h *nameFormatMiddleware) WithGroup(name string) slog.Handler { + return &nameFormatMiddleware{ + next: h.next.WithGroup(name), + groups: append(h.groups, name), + } +} From 44fbfc62614bb14573fb93e7ae329b5994b2e14c Mon Sep 17 00:00:00 2001 From: Janelle Law Date: Thu, 12 Oct 2023 18:11:09 +0000 Subject: [PATCH 2/4] replace zap usage with slog --- clientconn.go | 55 ++++++++++++++++++++---------------------------- discovery.go | 12 ++++------- go.mod | 2 -- go.sum | 4 ---- invokers.go | 40 +++++++++++++++-------------------- server.go | 47 ++++++++++++++++------------------------- stream.go | 58 ++++++++++++++++++++++----------------------------- 7 files changed, 87 insertions(+), 131 deletions(-) diff --git a/clientconn.go b/clientconn.go index 4b2fc5e..61562a2 100644 --- a/clientconn.go +++ b/clientconn.go @@ -3,12 +3,12 @@ package totem import ( "context" "fmt" + "log/slog" "time" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" @@ -18,7 +18,7 @@ import ( type ClientConn struct { controller *StreamController interceptor grpc.UnaryClientInterceptor - logger *zap.Logger + logger *slog.Logger metrics *MetricsExporter } @@ -65,25 +65,23 @@ func (cc *ClientConn) invoke( mdSupplier := metadataSupplier{&md} lg := cc.logger.With( - zap.String("requestType", fmt.Sprintf("%T", req)), - zap.String("replyType", fmt.Sprintf("%T", reply)), + "requestType", fmt.Sprintf("%T", req), + "replyType", fmt.Sprintf("%T", reply), ) var reqMsg []byte switch req := req.(type) { case *RPC: serviceName = req.ServiceName methodName = req.MethodName - lg.With( - zap.String("method", method), - ).Debug("forwarding rpc") + lg.Debug("forwarding rpc", "method", method) + reqMsg = req.GetRequest() if req.Metadata != nil { md = metadata.Join(md, req.Metadata.ToMD()) } case protoadapt.MessageV2: - lg.With( - zap.String("method", method), - ).Debug("invoking method") + lg.Debug("invoking method", "method", method) + var err error reqMsg, err = proto.Marshal(req) if err != nil { @@ -91,9 +89,8 @@ func (cc *ClientConn) invoke( } case protoadapt.MessageV1: reqv2 := protoadapt.MessageV2Of(req) - lg.With( - zap.String("method", method), - ).Debug("invoking method") + lg.Debug("invoking method", "method", method) + var err error reqMsg, err = proto.Marshal(reqv2) if err != nil { @@ -132,19 +129,17 @@ func (cc *ClientConn) invoke( resp := rpc.GetResponse() stat := resp.GetStatus() if err := stat.Err(); err != nil { - cc.logger.With( - zap.Uint64("tag", rpc.Tag), - zap.String("method", method), - zap.Error(err), - ).Debug("received reply with error") + cc.logger.Debug("received reply with error", "tag", rpc.Tag, + "method", method, + "error", err) + recordErrorStatus(span, stat) return err } - cc.logger.With( - zap.Uint64("tag", rpc.Tag), - zap.String("method", method), - ).Debug("received reply") + cc.logger.Debug("received reply", "tag", rpc.Tag, + "method", method) + recordSuccess(span) cc.metrics.TrackSvcTxLatency(serviceName, methodName, time.Since(startTime)) cc.metrics.TrackRxBytes(serviceName, methodName, int64(len(resp.Response))) @@ -165,22 +160,18 @@ func (cc *ClientConn) invoke( } case protoadapt.MessageV2: if err := proto.Unmarshal(resp.GetResponse(), reply); err != nil { - cc.logger.With( - zap.Uint64("tag", rpc.Tag), - zap.String("method", method), - zap.Error(err), - ).Error("received malformed response message") + cc.logger.Error("received malformed response message", "tag", rpc.Tag, + "method", method, + "error", err) return fmt.Errorf("[totem] malformed response: %w", err) } case protoadapt.MessageV1: replyv2 := protoadapt.MessageV2Of(reply) if err := proto.Unmarshal(resp.GetResponse(), replyv2); err != nil { - cc.logger.With( - zap.Uint64("tag", rpc.Tag), - zap.String("method", method), - zap.Error(err), - ).Error("received malformed response message") + cc.logger.Error("received malformed response message", "tag", rpc.Tag, + "method", method, + "error", err) return fmt.Errorf("[totem] malformed response: %w", err) } diff --git a/discovery.go b/discovery.go index ae1dbf9..55415c0 100644 --- a/discovery.go +++ b/discovery.go @@ -6,7 +6,6 @@ import ( "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" "google.golang.org/protobuf/proto" ) @@ -34,7 +33,7 @@ func discoverServices(ctx context.Context, ctrl *StreamController, opts discover ) defer span.End() lg = lg.With( - zap.String("traceID", span.SpanContext().TraceID().String()), + "traceID", span.SpanContext().TraceID().String(), ) } lg.Debug("starting service discovery") @@ -51,9 +50,8 @@ func discoverServices(ctx context.Context, ctrl *StreamController, opts discover respMsg := resp.GetResponse() stat := respMsg.GetStatus() if err := stat.Err(); err != nil { - lg.With( - zap.Error(err), - ).Warn("discovery failed") + lg.Warn("discovery failed", "error", err) + return nil, err } @@ -69,9 +67,7 @@ func discoverServices(ctx context.Context, ctrl *StreamController, opts discover ), trace.WithTimestamp(time.Now())) } - lg.With( - zap.Any("services", infoMsg.ServiceNames()), - ).Debug("discovery complete") + lg.Debug("discovery complete", "services", infoMsg.ServiceNames()) return infoMsg, nil } diff --git a/go.mod b/go.mod index e117078..4f54140 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,6 @@ require ( go.opentelemetry.io/otel/sdk/metric v0.39.0 go.opentelemetry.io/otel/trace v1.16.0 go.uber.org/atomic v1.11.0 - go.uber.org/zap v1.25.0 google.golang.org/genproto/googleapis/rpc v0.0.0-20230803162519-f966b187b2e5 google.golang.org/grpc v1.57.0 google.golang.org/protobuf v1.31.0 @@ -30,7 +29,6 @@ require ( require ( github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect - github.com/benbjohnson/clock v1.3.3 // indirect github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/bufbuild/protocompile v0.5.2-0.20230523010820-2b297241d0ff // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect diff --git a/go.sum b/go.sum index a1378ea..6d1217d 100644 --- a/go.sum +++ b/go.sum @@ -44,8 +44,6 @@ github.com/alitto/pond v1.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6 github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= -github.com/benbjohnson/clock v1.3.3 h1:g+rSsSaAzhHJYcIQE78hJ3AhyjjtQvleKDjlhdBnIhc= -github.com/benbjohnson/clock v1.3.3/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= github.com/bufbuild/protocompile v0.5.2-0.20230523010820-2b297241d0ff h1:rWp2XsgkEgqvNbtQ2Hp4r6HSAOmGglit5ulwwSPIATM= @@ -276,8 +274,6 @@ go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -go.uber.org/zap v1.25.0 h1:4Hvk6GtkucQ790dqmj7l1eEnRdKm3k3ZUrUMS2d5+5c= -go.uber.org/zap v1.25.0/go.mod h1:JIAUzQIH94IC4fOJQm7gMmBJP5k7wQfdcnYdPoEXJYk= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= diff --git a/invokers.go b/invokers.go index 011fcd0..0c19afe 100644 --- a/invokers.go +++ b/invokers.go @@ -2,11 +2,11 @@ package totem import ( "context" + "log/slog" "time" "go.opentelemetry.io/otel/attribute" "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" @@ -26,7 +26,7 @@ type localServiceInvoker struct { service *grpc.ServiceDesc methods map[string]grpc.MethodDesc streams map[string]grpc.StreamDesc - logger *zap.Logger + logger *slog.Logger interceptor grpc.UnaryServerInterceptor metrics *MetricsExporter flags TopologyFlags @@ -35,7 +35,7 @@ type localServiceInvoker struct { func newLocalServiceInvoker( serviceImpl interface{}, service *grpc.ServiceDesc, - logger *zap.Logger, + logger *slog.Logger, interceptor grpc.UnaryServerInterceptor, metrics *MetricsExporter, baseTopologyFlags TopologyFlags, @@ -64,12 +64,10 @@ func (l *localServiceInvoker) Invoke(ctx context.Context, req *RPC) ([]byte, err serviceName := req.GetServiceName() methodName := req.GetMethodName() - l.logger.With( - zap.String("service", serviceName), - zap.String("method", methodName), - zap.Uint64("tag", req.GetTag()), - zap.Strings("md", req.GetMetadata().Keys()), - ).Debug("invoking method using local service") + l.logger.Debug("invoking method using local service", "service", serviceName, + "method", methodName, + "tag", req.GetTag(), + "md", req.GetMetadata().Keys()) span := trace.SpanFromContext(ctx) @@ -140,11 +138,11 @@ func (l *localServiceInvoker) TopologyFlags() TopologyFlags { type streamControllerInvoker struct { controller *StreamController - logger *zap.Logger + logger *slog.Logger flags TopologyFlags } -func newStreamControllerInvoker(ctrl *StreamController, flags TopologyFlags, logger *zap.Logger) *streamControllerInvoker { +func newStreamControllerInvoker(ctrl *StreamController, flags TopologyFlags, logger *slog.Logger) *streamControllerInvoker { return &streamControllerInvoker{ controller: ctrl, logger: logger, @@ -155,12 +153,10 @@ func newStreamControllerInvoker(ctrl *StreamController, flags TopologyFlags, log func (r *streamControllerInvoker) Invoke(ctx context.Context, req *RPC) ([]byte, error) { serviceName := req.GetServiceName() methodName := req.GetMethodName() - r.logger.With( - zap.String("service", serviceName), - zap.String("method", methodName), - zap.Uint64("tag", req.GetTag()), - zap.Strings("md", req.GetMetadata().Keys()), - ).Debug("invoking method using stream controller") + r.logger.Debug("invoking method using stream controller", "service", serviceName, + "method", methodName, + "tag", req.GetTag(), + "md", req.GetMetadata().Keys()) // convert the incoming context to an outgoing context md, ok := metadata.FromIncomingContext(ctx) @@ -200,12 +196,10 @@ func (r *streamControllerInvoker) InvokeStream(ctx context.Context, req *RPC, wc serviceName := req.GetServiceName() methodName := req.GetMethodName() - r.logger.With( - zap.String("service", serviceName), - zap.String("method", methodName), - zap.Uint64("tag", req.GetTag()), - zap.Strings("md", req.GetMetadata().Keys()), - ).Debug("invoking stream using stream controller") + r.logger.Debug("invoking stream using stream controller", "service", serviceName, + "method", methodName, + "tag", req.GetTag(), + "md", req.GetMetadata().Keys()) // convert the incoming context to an outgoing context md, ok := metadata.FromIncomingContext(ctx) diff --git a/server.go b/server.go index e1a952b..ac582c0 100644 --- a/server.go +++ b/server.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "log" + "log/slog" "reflect" "sync" "time" @@ -12,7 +13,6 @@ import ( "go.opentelemetry.io/otel/sdk/metric" "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/trace" - "go.uber.org/zap" "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -24,7 +24,7 @@ type Server struct { stream Stream lock sync.RWMutex controller *StreamController - logger *zap.Logger + logger *slog.Logger splicedControllers []*StreamController tracer trace.Tracer @@ -100,7 +100,7 @@ func NewServer(stream Stream, opts ...ServerOption) (*Server, error) { } options.apply(opts...) - lg := Log.Named(options.name) + lg := Log.WithGroup(options.name) ctrl := NewStreamController(stream, StreamControllerOptions{ Logger: lg, @@ -175,9 +175,8 @@ func (r *Server) Splice(stream Stream, opts ...ServerOption) error { if proto.HasExtension(sh.Descriptor.Options, E_Visibility) { vis := proto.GetExtension(sh.Descriptor.Options, E_Visibility).(*Visibility) if vis.SplicedClients { - r.logger.With( - zap.String("service", sh.Descriptor.GetName()), - ).Debug("enabling local service on spliced controller due to visibility option") + r.logger.Debug("enabling local service on spliced controller due to visibility option", "service", sh.Descriptor.GetName()) + ctrl.RegisterServiceHandler(sh) } } @@ -191,9 +190,8 @@ func (r *Server) Splice(stream Stream, opts ...ServerOption) error { if status.Code(err) == codes.Canceled { r.logger.Debug("stream closed") } else { - r.logger.With( - zap.Error(err), - ).Warn("stream exited with error") + r.logger.Warn("stream exited with error", "error", err) + } } }() @@ -205,9 +203,7 @@ func (r *Server) Splice(stream Stream, opts ...ServerOption) error { err := fmt.Errorf("service discovery failed: %w", err) return err } - r.logger.With( - zap.Any("methods", info.MethodNames()), - ).Debug("splicing stream") + r.logger.Debug("splicing stream", "methods", info.MethodNames()) handlerInvoker := ctrl.NewInvoker() for _, desc := range info.Services { @@ -225,9 +221,7 @@ func (r *Server) Splice(stream Stream, opts ...ServerOption) error { func (r *Server) register(serviceDesc *grpc.ServiceDesc, impl interface{}) { r.lock.Lock() defer r.lock.Unlock() - r.logger.With( - zap.String("service", serviceDesc.ServiceName), - ).Debug("registering service") + r.logger.Debug("registering service", "service", serviceDesc.ServiceName) if TracingEnabled { r.setupSpan.AddEvent("Registering Local Service", trace.WithAttributes( @@ -258,13 +252,11 @@ func (r *Server) Serve() (grpc.ClientConnInterface, <-chan error) { runErr := r.controller.Run(r.Context()) if runErr != nil { if status.Code(runErr) == codes.Canceled { - r.logger.With( - zap.Error(runErr), - ).Debug("stream canceled") + r.logger.Debug("stream canceled", "error", runErr) + } else { - r.logger.With( - zap.Error(runErr), - ).Warn("stream exited with error") + r.logger.Warn("stream exited with error", "error", runErr) + } } else { r.logger.Debug("stream closed") @@ -274,10 +266,9 @@ func (r *Server) Serve() (grpc.ClientConnInterface, <-chan error) { r.lock.Lock() defer r.lock.Unlock() if runErr != nil { - r.logger.With( - zap.Error(runErr), - zap.Int("numControllers", len(r.splicedControllers)), - ).Debug("kicking spliced controllers") + r.logger.Debug("kicking spliced controllers", "error", runErr, + "numControllers", len(r.splicedControllers)) + } for _, spliced := range r.splicedControllers { if runErr != nil { @@ -299,9 +290,7 @@ func (r *Server) Serve() (grpc.ClientConnInterface, <-chan error) { return nil, ch } - r.logger.With( - zap.Any("methods", info.MethodNames()), - ).Debug("service discovery complete") + r.logger.Debug("service discovery complete", "methods", info.MethodNames()) r.setupSpan.AddEvent("Service Discovery Complete", trace.WithAttributes( attribute.StringSlice("services", info.ServiceNames()), @@ -324,7 +313,7 @@ func (r *Server) Serve() (grpc.ClientConnInterface, <-chan error) { return &ClientConn{ controller: r.controller, interceptor: r.interceptors.Outgoing, - logger: r.logger.Named("cc"), + logger: r.logger.WithGroup("cc"), metrics: r.metrics, }, ch } diff --git a/stream.go b/stream.go index d04852b..3e21912 100644 --- a/stream.go +++ b/stream.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "log/slog" "sync" "time" @@ -18,7 +19,6 @@ import ( "go.opentelemetry.io/otel/sdk/resource" "go.opentelemetry.io/otel/trace" "go.uber.org/atomic" - "go.uber.org/zap" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/protobuf/proto" @@ -55,7 +55,7 @@ func DefaultWorkerPoolParams() WorkerPoolParameters { type StreamControllerOptions struct { Metrics *MetricsExporter Name string - Logger *zap.Logger + Logger *slog.Logger // Rx/Tx metrics are tracked in the following places: // - For outgoing requests/incoming replies, in the clientconn. @@ -82,9 +82,9 @@ type WorkerPoolParameters struct { // There can be at most one stream controller per stream. func NewStreamController(stream Stream, opts StreamControllerOptions) *StreamController { if opts.Logger == nil { - opts.Logger = Log.Named(opts.Name) + opts.Logger = Log.WithGroup(opts.Name) } else { - opts.Logger = opts.Logger.Named(opts.Name) + opts.Logger = opts.Logger.WithGroup(opts.Name) } sh := &StreamController{ @@ -113,9 +113,7 @@ func NewStreamController(stream Stream, opts StreamControllerOptions) *StreamCon func (sh *StreamController) RegisterServiceHandler(handler *ServiceHandler) { name := handler.Descriptor.GetName() - sh.Logger.With( - zap.String("service", name), - ).Debug("registering service handler") + sh.Logger.Debug("registering service handler", "service", name) list, _ := sh.services.LoadOrStore(name, &ServiceHandlerList{}) list.Append(handler) @@ -126,10 +124,10 @@ func (sh *StreamController) Request(ctx context.Context, m *RPC) <-chan *RPC { methodName := m.GetMethodName() lg := sh.Logger.With( - zap.Uint64("tag", m.GetTag()), - zap.String("service", serviceName), - zap.String("method", methodName), - zap.Strings("md", m.GetMetadata().Keys()), + "tag", m.GetTag(), + "service", serviceName, + "method", methodName, + "md", m.GetMetadata().Keys(), ) lg.Debug("request") @@ -164,7 +162,7 @@ func (sh *StreamController) Request(ctx context.Context, m *RPC) <-chan *RPC { func (sh *StreamController) Reply(ctx context.Context, tag uint64, data []byte) { lg := sh.Logger.With( - zap.Uint64("tag", tag), + "tag", tag, ) lg.Debug("reply (success)") @@ -199,8 +197,8 @@ func (sh *StreamController) Reply(ctx context.Context, tag uint64, data []byte) func (sh *StreamController) ReplyErr(ctx context.Context, tag uint64, reply error) { lg := sh.Logger.With( - zap.Uint64("tag", tag), - zap.Error(reply), + "tag", tag, + slog.Any("error", reply), ) lg.Debug("reply") @@ -235,7 +233,7 @@ func (sh *StreamController) ReplyErr(ctx context.Context, tag uint64, reply erro func (sh *StreamController) StreamReply(tag uint64, msg *ServerStreamMessage) { lg := sh.Logger.With( - zap.Uint64("tag", tag), + "tag", tag, ) lg.Debug("reply (in stream)") @@ -257,7 +255,7 @@ func (sh *StreamController) StreamReply(tag uint64, msg *ServerStreamMessage) { func (sh *StreamController) Kick(err error) { lg := sh.Logger.With( - zap.Error(err), + "error", err, ) sh.kickOnce.Do(func() { if status.Code(err) == codes.Canceled { @@ -362,9 +360,8 @@ func (sh *StreamController) Run(ctx context.Context) error { } } sh.pendingRPCs.Range(func(tag uint64, future chan *RPC) bool { - sh.Logger.With( - zap.Uint64("tag", tag), - ).Debug("cancelling pending RPC") + sh.Logger.Debug("cancelling pending RPC", "tag", tag) + future <- &RPC{ Tag: tag, Content: &RPC_Response{ @@ -384,11 +381,9 @@ func (sh *StreamController) Run(ctx context.Context) error { } func (sh *StreamController) ListServices(ctx context.Context, req *DiscoveryRequest) (*ServiceInfo, error) { - sh.Logger.With( - zap.String("initiator", req.Initiator), - zap.Any("visited", req.Visited), - zap.Int("remainingHops", int(req.GetRemainingHops())), - ).Debug("ListServices") + sh.Logger.Debug("ListServices", "initiator", req.Initiator, + "visited", req.Visited, + "remainingHops", int(req.GetRemainingHops())) var span trace.Span if TracingEnabled { @@ -502,16 +497,14 @@ func (sh *StreamController) ListServices(ctx context.Context, req *DiscoveryRequ }, }) if err != nil { - sh.Logger.With( - zap.Error(err), - ).Warn("error invoking ListServices") + sh.Logger.Warn("error invoking ListServices", "error", err) + return true } remoteInfo := &ServiceInfo{} if err := proto.Unmarshal(respData, remoteInfo); err != nil { - sh.Logger.With( - zap.Error(err), - ).Warn("error unmarshaling ListServices response") + sh.Logger.Warn("error unmarshaling ListServices response", "error", err) + return true } if TracingEnabled { @@ -664,9 +657,8 @@ func (sh *StreamController) handleRequest(ctx context.Context, msg *RPC, md meta } // No handler found - sh.Logger.With( - zap.String("service", svcName), - ).Debug("unknown service") + sh.Logger.Debug("unknown service", "service", svcName) + err := status.Errorf(codes.Unimplemented, "unknown service: %q", svcName) recordError(span, err) sh.ReplyErr(ctx, requestTag, err) From 1f56365cb569b1f91df1adb224931f08d831f531 Mon Sep 17 00:00:00 2001 From: Janelle Law Date: Fri, 13 Oct 2023 13:55:08 +0000 Subject: [PATCH 3/4] pass logger as server option --- logging.go | 187 -------------------------------------------- server.go | 17 ++-- stream.go | 4 +- totem_suite_test.go | 3 + 4 files changed, 16 insertions(+), 195 deletions(-) delete mode 100644 logging.go diff --git a/logging.go b/logging.go deleted file mode 100644 index 0e47bf4..0000000 --- a/logging.go +++ /dev/null @@ -1,187 +0,0 @@ -package totem - -import ( - "context" - "fmt" - "log/slog" - "math" - "math/rand" - "os" - "path/filepath" - "strconv" - "strings" - - "github.com/charmbracelet/lipgloss" - gsync "github.com/kralicky/gpkg/sync" - "github.com/lmittmann/tint" - slogmulti "github.com/samber/slog-multi" -) - -var ( - Log *slog.Logger - LogLevel = slog.LevelWarn - OutputPath = os.Stderr -) - -var ( - colorCache gsync.Map[string, lipgloss.Style] - callerStyle = lipgloss.NewStyle().Faint(true) -) - -const ( - ansiRed = "\033[91m" - ansiYellow = "\033[93m" - ansiBlue = "\033[94m" - ansiMagenta = "\033[95m" - ansiReset = "\033[0m" - ISO8601Format = "2006-01-02 15:04:05:000" -) - -func parseLogLevel(levelStr string) slog.Level { - var level slog.Level - switch levelStr { - case "debug": - level = slog.LevelDebug - case "info": - level = slog.LevelInfo - case "warn": - level = slog.LevelWarn - case "error": - level = slog.LevelError - default: - level = LogLevel - } - return level -} - -func init() { - colorCache.Store("totem", lipgloss.NewStyle().Background(lipgloss.Color("15")).Foreground(lipgloss.Color("0"))) - logLevel := LogLevel - if levelStr, ok := os.LookupEnv("TOTEM_LOG_LEVEL"); ok { - logLevel = parseLogLevel(levelStr) - } - - options := &tint.Options{ - AddSource: true, - Level: logLevel, - NoColor: false, - ReplaceAttr: func(groups []string, a slog.Attr) slog.Attr { - switch a.Key { - case slog.TimeKey: // format time - a.Value = slog.StringValue(a.Value.Time().Format(ISO8601Format)) - case slog.SourceKey: // remove package name - sb := strings.Builder{} - switch cv := a.Value.Any().(type) { - case *slog.Source: - _, filename := filepath.Split(cv.File) - sb.WriteString(filename) - sb.WriteByte(':') - sb.WriteString(strconv.Itoa(cv.Line)) - a.Value = slog.StringValue(callerStyle.Render(sb.String())) - } - case slog.LevelKey: // format level string - switch cv := a.Value.Any().(type) { - case slog.Level: - lvlStr := strings.Builder{} - switch cv { - case slog.LevelDebug: - lvlStr.WriteString(ansiMagenta) - lvlStr.WriteString("DEBUG") - case slog.LevelInfo: - lvlStr.WriteString(ansiBlue) - lvlStr.WriteString("INFO") - case slog.LevelWarn: - lvlStr.WriteString(ansiYellow) - lvlStr.WriteString("WARN") - case slog.LevelError: - lvlStr.WriteString(ansiRed) - lvlStr.WriteString("ERROR") - default: - return a - } - lvlStr.WriteString(ansiReset) - a.Value = slog.StringValue(lvlStr.String()) - default: - return a - } - } - return a - }, - } - - nameFormatter := newNameFormatMiddleware() - - Log = slog.New(slogmulti.Pipe(nameFormatter).Handler(tint.NewHandler(OutputPath, options))).WithGroup("totem") -} - -func newRandomForegroundStyle() lipgloss.Style { - r := math.Round(rand.Float64()*127) + 127 - g := math.Round(rand.Float64()*127) + 127 - b := math.Round(rand.Float64()*127) + 127 - return lipgloss.NewStyle().Foreground(lipgloss.Color(fmt.Sprintf("#%02x%02x%02x", int(r), int(g), int(b)))) -} - -func newNameFormatMiddleware() slogmulti.Middleware { - return func(next slog.Handler) slog.Handler { - return &nameFormatMiddleware{ - next: next, - } - } -} - -type nameFormatMiddleware struct { - next slog.Handler - groups []string -} - -func (h *nameFormatMiddleware) Enabled(ctx context.Context, level slog.Level) bool { - return h.next.Enabled(ctx, level) -} - -func (h *nameFormatMiddleware) Handle(ctx context.Context, record slog.Record) error { - attrs := []slog.Attr{} - - record.Attrs(func(attr slog.Attr) bool { - attrs = append(attrs, attr) - return true - }) - - sb := strings.Builder{} - for i, part := range h.groups { - if c, ok := colorCache.Load(part); !ok { - newStyle := newRandomForegroundStyle() - colorCache.Store(part, newStyle) - sb.WriteString(newStyle.Render(part)) - } else { - sb.WriteString(c.Render(part)) - } - if i < len(h.groups)-1 { - sb.WriteString(".") - } else { - sb.WriteByte(' ') - } - } - - // insert logger name before message - sb.WriteString(record.Message) - - record = slog.NewRecord(record.Time, record.Level, sb.String(), record.PC) - record.AddAttrs(attrs...) - - return h.next.Handle(ctx, record) -} - -func (h *nameFormatMiddleware) WithAttrs(attrs []slog.Attr) slog.Handler { - - return &nameFormatMiddleware{ - next: h.next.WithAttrs(attrs), - groups: h.groups, - } -} - -func (h *nameFormatMiddleware) WithGroup(name string) slog.Handler { - return &nameFormatMiddleware{ - next: h.next.WithGroup(name), - groups: append(h.groups, name), - } -} diff --git a/server.go b/server.go index ac582c0..78f2b63 100644 --- a/server.go +++ b/server.go @@ -3,6 +3,7 @@ package totem import ( "context" "fmt" + "io" "log" "log/slog" "reflect" @@ -24,7 +25,6 @@ type Server struct { stream Stream lock sync.RWMutex controller *StreamController - logger *slog.Logger splicedControllers []*StreamController tracer trace.Tracer @@ -33,6 +33,7 @@ type Server struct { } type ServerOptions struct { + logger *slog.Logger name string discoveryHopLimit int32 interceptors InterceptorConfig @@ -94,16 +95,23 @@ func WithName(name string) ServerOption { } } +func WithLogger(logger *slog.Logger) ServerOption { + return func(o *ServerOptions) { + o.logger = logger + } +} + +var defaultNoopLogger = slog.New(slog.NewTextHandler(io.Discard, &slog.HandlerOptions{Level: slog.LevelError})) + func NewServer(stream Stream, opts ...ServerOption) (*Server, error) { options := ServerOptions{ discoveryHopLimit: -1, + logger: defaultNoopLogger, } options.apply(opts...) - lg := Log.WithGroup(options.name) - ctrl := NewStreamController(stream, StreamControllerOptions{ - Logger: lg, + Logger: options.logger, Name: options.name, Metrics: options.metrics, WorkerPoolParams: DefaultWorkerPoolParams(), @@ -120,7 +128,6 @@ func NewServer(stream Stream, opts ...ServerOption) (*Server, error) { ServerOptions: options, stream: stream, controller: ctrl, - logger: lg, setupCtx: setupCtx, setupSpan: span, tracer: tracer, diff --git a/stream.go b/stream.go index 3e21912..7042ef2 100644 --- a/stream.go +++ b/stream.go @@ -82,9 +82,7 @@ type WorkerPoolParameters struct { // There can be at most one stream controller per stream. func NewStreamController(stream Stream, opts StreamControllerOptions) *StreamController { if opts.Logger == nil { - opts.Logger = Log.WithGroup(opts.Name) - } else { - opts.Logger = opts.Logger.WithGroup(opts.Name) + opts.Logger = slog.Default() } sh := &StreamController{ diff --git a/totem_suite_test.go b/totem_suite_test.go index a715011..60e1b43 100644 --- a/totem_suite_test.go +++ b/totem_suite_test.go @@ -5,6 +5,7 @@ import ( "crypto/sha1" "encoding/hex" "fmt" + "log/slog" "net" "os" "runtime" @@ -20,6 +21,7 @@ import ( "go.opentelemetry.io/otel/sdk/resource" tracesdk "go.opentelemetry.io/otel/sdk/trace" semconv "go.opentelemetry.io/otel/semconv/v1.12.0" + "google.golang.org/grpc" "google.golang.org/grpc/codes" "google.golang.org/grpc/status" @@ -36,6 +38,7 @@ var defaultServerOpts = []grpc.ServerOption{ } func TestTotem(t *testing.T) { + slog.SetDefault(slog.New(slog.NewTextHandler(GinkgoWriter, &slog.HandlerOptions{Level: slog.LevelDebug}))) SetDefaultEventuallyTimeout(60 * time.Second) RegisterFailHandler(Fail) RunSpecs(t, "Totem Suite") From c8427f9dd41ccc9ec31f80097f451d06ef3216eb Mon Sep 17 00:00:00 2001 From: Joe Kralicky Date: Fri, 13 Oct 2023 15:22:42 -0400 Subject: [PATCH 4/4] tidy --- go.mod | 10 ---------- go.sum | 24 ------------------------ totem_suite_test.go | 2 -- 3 files changed, 36 deletions(-) diff --git a/go.mod b/go.mod index 4f54140..dc97b72 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.21 require ( github.com/alitto/pond v1.8.3 - github.com/charmbracelet/lipgloss v0.7.1 github.com/google/uuid v1.3.0 github.com/jhump/protoreflect v1.15.1 github.com/kralicky/gpkg v0.0.0-20220311205216-0d8ea9557555 @@ -28,7 +27,6 @@ require ( ) require ( - github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/bmatcuk/doublestar v1.3.4 // indirect github.com/bufbuild/protocompile v0.5.2-0.20230523010820-2b297241d0ff // indirect github.com/cenkalti/backoff/v4 v4.2.1 // indirect @@ -42,17 +40,9 @@ require ( github.com/grpc-ecosystem/grpc-gateway/v2 v2.7.0 // indirect github.com/iancoleman/strcase v0.3.0 // indirect github.com/kr/pretty v0.3.1 // indirect - github.com/lmittmann/tint v1.0.2 // indirect - github.com/lucasb-eyer/go-colorful v1.2.0 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect - github.com/mattn/go-runewidth v0.0.15 // indirect - github.com/muesli/reflow v0.3.0 // indirect - github.com/muesli/termenv v0.15.1 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect - github.com/rivo/uniseg v0.4.4 // indirect github.com/rogpeppe/go-internal v1.11.0 // indirect github.com/samber/lo v1.38.1 // indirect - github.com/samber/slog-multi v1.0.2 github.com/stretchr/testify v1.8.4 // indirect go.opentelemetry.io/contrib/propagators/aws v1.17.0 // indirect go.opentelemetry.io/contrib/propagators/b3 v1.17.0 // indirect diff --git a/go.sum b/go.sum index 6d1217d..ec05bc3 100644 --- a/go.sum +++ b/go.sum @@ -42,8 +42,6 @@ github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAE github.com/alitto/pond v1.8.3 h1:ydIqygCLVPqIX/USe5EaV/aSRXTRXDEI9JwuDdu+/xs= github.com/alitto/pond v1.8.3/go.mod h1:CmvIIGd5jKLasGI3D87qDkQxjzChdKMmnXMg3fG6M6Q= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= -github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= -github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/bmatcuk/doublestar v1.3.4 h1:gPypJ5xD31uhX6Tf54sDPUOBXTqKH4c9aPY66CyQrS0= github.com/bmatcuk/doublestar v1.3.4/go.mod h1:wiQtGV+rzVYxB7WIlirSN++5HPtPlXEo9MEoZQC/PmE= github.com/bufbuild/protocompile v0.5.2-0.20230523010820-2b297241d0ff h1:rWp2XsgkEgqvNbtQ2Hp4r6HSAOmGglit5ulwwSPIATM= @@ -53,8 +51,6 @@ github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyY github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/charmbracelet/lipgloss v0.7.1 h1:17WMwi7N1b1rVWOjMT+rCh7sQkvDU75B2hbZpc5Kc1E= -github.com/charmbracelet/lipgloss v0.7.1/go.mod h1:yG0k3giv8Qj8edTCbbg6AlQ5e8KNWpFujkNawKNhE2c= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= @@ -180,21 +176,8 @@ github.com/kralicky/gpkg v0.0.0-20220311205216-0d8ea9557555 h1:w/v9aYd9gdL0pEofC github.com/kralicky/gpkg v0.0.0-20220311205216-0d8ea9557555/go.mod h1:EJrGSfmocDg2CBjHDm3zy9oxNKCSGhf+MNTiN1DRbKA= github.com/kralicky/ragu v1.0.11-0.20230530191519-84f5aaa5fd69 h1:Iqg6oc2ty1dLRiBJfj7EwyKy1O81zL8+wcW5uMRlnIg= github.com/kralicky/ragu v1.0.11-0.20230530191519-84f5aaa5fd69/go.mod h1:njQGnwU5IHm4Qx6/oOY0ll7Z6WA0apfP0ClpVA0M27Q= -github.com/lmittmann/tint v1.0.2 h1:9XZ+JvEzjvd3VNVugYqo3j+dl0NRju8k9FquAusJExM= -github.com/lmittmann/tint v1.0.2/go.mod h1:HIS3gSy7qNwGCj+5oRjAutErFBl4BzdQP6cJZ0NfMwE= -github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= -github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/magefile/mage v1.15.0 h1:BvGheCMAsG3bWUDbZ8AyXXpCNwU9u5CB6sM+HNb9HYg= github.com/magefile/mage v1.15.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXqQg881A= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk= -github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U= -github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= -github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= -github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= -github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs= -github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/ginkgo/v2 v2.11.0/go.mod h1:ZhrRA5XmEE3x3rhlzamx/JJvujdZoJ2uvgI7kR0iZvM= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= @@ -204,10 +187,6 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U= github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= -github.com/rivo/uniseg v0.4.4 h1:8TfxU8dW6PdqD27gjM8MVNuicgxIjxpm4K7x4jp8sis= -github.com/rivo/uniseg v0.4.4/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= @@ -215,8 +194,6 @@ github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDN github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= -github.com/samber/slog-multi v1.0.2 h1:6BVH9uHGAsiGkbbtQgAOQJMpKgV8unMrHhhJaw+X1EQ= -github.com/samber/slog-multi v1.0.2/go.mod h1:uLAvHpGqbYgX4FSL0p1ZwoLuveIAJvBECtE07XmYvFo= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.5.0 h1:1zr/of2m5FGMsad5YfcqgdqdWrIhu+EBEJRhR1U7z/c= @@ -388,7 +365,6 @@ golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= diff --git a/totem_suite_test.go b/totem_suite_test.go index 60e1b43..3ba71ba 100644 --- a/totem_suite_test.go +++ b/totem_suite_test.go @@ -5,7 +5,6 @@ import ( "crypto/sha1" "encoding/hex" "fmt" - "log/slog" "net" "os" "runtime" @@ -38,7 +37,6 @@ var defaultServerOpts = []grpc.ServerOption{ } func TestTotem(t *testing.T) { - slog.SetDefault(slog.New(slog.NewTextHandler(GinkgoWriter, &slog.HandlerOptions{Level: slog.LevelDebug}))) SetDefaultEventuallyTimeout(60 * time.Second) RegisterFailHandler(Fail) RunSpecs(t, "Totem Suite")