]> git.r.bdr.sh - rbdr/mobius/commitdiff
Replace zap logger with slog
authorJeff Halter <redacted>
Mon, 10 Jun 2024 23:49:37 +0000 (16:49 -0700)
committerJeff Halter <redacted>
Mon, 10 Jun 2024 23:53:31 +0000 (16:53 -0700)
cmd/mobius-hotline-server/main.go
go.mod
go.sum
hotline/client_conn.go
hotline/panic.go
hotline/server.go
hotline/server_blackbox_test.go
hotline/server_test.go
hotline/transaction_handlers.go

index 2bda39bf3a1bbfeebd8963bc5b7ab1df43989da3..c027d187c55e3555b9d2820ddcb52253b1ed5196 100644 (file)
@@ -7,11 +7,10 @@ import (
        "flag"
        "fmt"
        "github.com/jhalter/mobius/hotline"
-       "go.uber.org/zap"
-       "go.uber.org/zap/zapcore"
        "gopkg.in/natefinch/lumberjack.v2"
        "io"
        "log"
+       "log/slog"
        "net/http"
        "os"
        "path/filepath"
@@ -21,9 +20,13 @@ import (
 //go:embed mobius/config
 var cfgTemplate embed.FS
 
-const (
-       defaultPort = 5500
-)
+const defaultPort = 5500
+
+var logLevels = map[string]slog.Level{
+       "debug": slog.LevelDebug,
+       "info":  slog.LevelInfo,
+       "error": slog.LevelError,
+}
 
 func main() {
        ctx, cancel := context.WithCancel(context.Background())
@@ -60,46 +63,44 @@ func main() {
                os.Exit(0)
        }
 
-       zapLvl, ok := zapLogLevel[*logLevel]
-       if !ok {
-               fmt.Printf("Invalid log level %s.  Must be debug, info, warn, or error.\n", *logLevel)
-               os.Exit(0)
-       }
-
-       cores := []zapcore.Core{
-               newStdoutCore(zapLvl),
-       }
-
-       if *logFile != "" {
-               cores = append(cores, newLogFileCore(*logFile, zapLvl))
-       }
-
-       l := zap.New(zapcore.NewTee(cores...))
-       defer func() { _ = l.Sync() }()
-       logger := l.Sugar()
+       slogger := slog.New(
+               slog.NewTextHandler(
+                       io.MultiWriter(os.Stdout, &lumberjack.Logger{
+                               Filename:   *logFile,
+                               MaxSize:    100, // MB
+                               MaxBackups: 3,
+                               MaxAge:     365, // days
+                       }),
+                       &slog.HandlerOptions{Level: logLevels[*logLevel]},
+               ),
+       )
 
        if *init {
                if _, err := os.Stat(filepath.Join(*configDir, "/config.yaml")); os.IsNotExist(err) {
                        if err := os.MkdirAll(*configDir, 0750); err != nil {
-                               logger.Fatal(err)
+                               slogger.Error(fmt.Sprintf("error creating config dir: %s", err))
+                               os.Exit(1)
                        }
 
                        if err := copyDir("mobius/config", *configDir); err != nil {
-                               logger.Fatal(err)
+                               slogger.Error(fmt.Sprintf("error copying config dir: %s", err))
+                               os.Exit(1)
                        }
-                       logger.Infow("Config dir initialized at " + *configDir)
+                       slogger.Info("Config dir initialized at " + *configDir)
                } else {
-                       logger.Infow("Existing config dir found.  Skipping initialization.")
+                       slogger.Info("Existing config dir found.  Skipping initialization.")
                }
        }
 
        if _, err := os.Stat(*configDir); os.IsNotExist(err) {
-               logger.Fatalw("Configuration directory not found.  Correct the path or re-run with -init to generate initial config.", "path", configDir)
+               slogger.Error(fmt.Sprintf("Configuration directory not found.  Correct the path or re-run with -init to generate initial config."))
+               os.Exit(1)
        }
 
-       srv, err := hotline.NewServer(*configDir, *netInterface, *basePort, logger, &hotline.OSFileStore{})
+       srv, err := hotline.NewServer(*configDir, *netInterface, *basePort, slogger, &hotline.OSFileStore{})
        if err != nil {
-               logger.Fatal(err)
+               slogger.Error(fmt.Sprintf("Error starting server: %s", err))
+               os.Exit(1)
        }
 
        sh := statHandler{hlServer: srv}
@@ -116,7 +117,7 @@ func main() {
        }
 
        // Serve Hotline requests until program exit
-       logger.Fatal(srv.ListenAndServe(ctx, cancel))
+       log.Fatal(srv.ListenAndServe(ctx, cancel))
 }
 
 type statHandler struct {
@@ -132,43 +133,6 @@ func (sh *statHandler) RenderStats(w http.ResponseWriter, _ *http.Request) {
        _, _ = io.WriteString(w, string(u))
 }
 
-func newStdoutCore(level zapcore.Level) zapcore.Core {
-       encoderCfg := zap.NewProductionEncoderConfig()
-       encoderCfg.TimeKey = "timestamp"
-       encoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder
-
-       return zapcore.NewCore(
-               zapcore.NewConsoleEncoder(encoderCfg),
-               zapcore.Lock(os.Stdout),
-               level,
-       )
-}
-
-func newLogFileCore(path string, level zapcore.Level) zapcore.Core {
-       encoderCfg := zap.NewProductionEncoderConfig()
-       encoderCfg.TimeKey = "timestamp"
-       encoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder
-       writer := zapcore.AddSync(&lumberjack.Logger{
-               Filename:   path,
-               MaxSize:    100, // MB
-               MaxBackups: 3,
-               MaxAge:     365, // days
-       })
-
-       return zapcore.NewCore(
-               zapcore.NewConsoleEncoder(encoderCfg),
-               writer,
-               level,
-       )
-}
-
-var zapLogLevel = map[string]zapcore.Level{
-       "debug": zap.DebugLevel,
-       "info":  zap.InfoLevel,
-       "warn":  zap.WarnLevel,
-       "error": zap.ErrorLevel,
-}
-
 func defaultConfigPath() (cfgPath string) {
        switch runtime.GOOS {
        case "windows":
diff --git a/go.mod b/go.mod
index 43c9a332eaf7b72e02e51bdcb5cf3fd1071aaf37..868d867a860296e0ccc7aba01894078b268efece 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -7,7 +7,6 @@ require (
        github.com/go-playground/validator/v10 v10.19.0
        github.com/rivo/tview v0.0.0-20240413115534-b0d41c484b95
        github.com/stretchr/testify v1.9.0
-       go.uber.org/zap v1.27.0
        golang.org/x/crypto v0.22.0
        golang.org/x/text v0.14.0
        gopkg.in/natefinch/lumberjack.v2 v2.2.1
@@ -26,7 +25,6 @@ require (
        github.com/pmezard/go-difflib v1.0.0 // indirect
        github.com/rivo/uniseg v0.4.7 // indirect
        github.com/stretchr/objx v0.5.2 // indirect
-       go.uber.org/multierr v1.11.0 // indirect
        golang.org/x/net v0.24.0 // indirect
        golang.org/x/sys v0.19.0 // indirect
        golang.org/x/term v0.19.0 // indirect
diff --git a/go.sum b/go.sum
index bd4d433539e5d0ee0b5a595cc84a3221a4005990..89836297fbb71480d3df3c7649f602ad75ddf83b 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -2,7 +2,6 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/gabriel-vasile/mimetype v1.4.3 h1:in2uUcidCuFcDKtdcBxlR0rJ1+fsokWf+uqxgUFjbI0=
 github.com/gabriel-vasile/mimetype v1.4.3/go.mod h1:d8uq/6HKRL6CGdk+aubisF/M5GcPfT7nKyLpA0lbSSk=
-github.com/gdamore/encoding v1.0.0 h1:+7OoQ1Bc6eTm5niUzBa0Ctsh6JbMW6Ra+YNuAtDBdko=
 github.com/gdamore/encoding v1.0.0/go.mod h1:alR0ol34c49FCSBLjhosxzcPHQbf2trDkoo5dl+VrEg=
 github.com/gdamore/encoding v1.0.1 h1:YzKZckdBL6jVt2Gc+5p82qhrGiqMdG/eNs6Wy0u3Uhw=
 github.com/gdamore/encoding v1.0.1/go.mod h1:0Z0cMFinngz9kS1QfMjCP8TY7em3bZYeeklsSDPivEo=
@@ -24,8 +23,6 @@ github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZ
 github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
-github.com/rivo/tview v0.0.0-20240307173318-e804876934a1 h1:bWLHTRekAy497pE7+nXSuzXwwFHI0XauRzz6roUvY+s=
-github.com/rivo/tview v0.0.0-20240307173318-e804876934a1/go.mod h1:02iFIz7K/A9jGCvrizLPvoqr4cEIx7q54RH5Qudkrss=
 github.com/rivo/tview v0.0.0-20240413115534-b0d41c484b95 h1:dPivHKc1ZAicSlawH/eAmGPSCfOuCYRQLl+Eq1eRKNU=
 github.com/rivo/tview v0.0.0-20240413115534-b0d41c484b95/go.mod h1:02iFIz7K/A9jGCvrizLPvoqr4cEIx7q54RH5Qudkrss=
 github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
@@ -37,16 +34,8 @@ github.com/stretchr/objx v0.5.2/go.mod h1:FRsXN1f5AsAjCGJKqEizvkpNtU+EGNCLh3NxZ/
 github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
 github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-go.uber.org/goleak v1.3.0 h1:2K3zAYmnTNqV73imy9J1T3WC+gmCePx2hEGkimedGto=
-go.uber.org/goleak v1.3.0/go.mod h1:CoHD4mav9JJNrW/WLlf7HGZPjdw8EucARQHekz1X6bE=
-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.27.0 h1:aJMhYGrd5QSmlpLMr2MftRKl7t8J8PTZPA732ud/XR8=
-go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
-golang.org/x/crypto v0.21.0 h1:X31++rzVUdKhX5sWmSOFZxx8UW/ldWx55cbf08iNAMA=
-golang.org/x/crypto v0.21.0/go.mod h1:0BP7YvVV9gBbVKyeTG0Gyn+gZm94bibOW5BjDEYAOMs=
 golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
 golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
 golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
@@ -55,8 +44,6 @@ golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLL
 golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.21.0 h1:AQyQV4dYCvJ7vGmJyKki9+PBdyvhkSd8EIx/qb0AYv4=
-golang.org/x/net v0.21.0/go.mod h1:bIjVDfnllIU7BJ2DNgfnXvpSvtn8VRwhlsaeUTyUS44=
 golang.org/x/net v0.24.0 h1:1PcaxkF854Fu3+lvBIx5SYn9wRlBzzcnHZSiaFFAb0w=
 golang.org/x/net v0.24.0/go.mod h1:2Q7sJY5mzlzWjKtYUEXSlBWCdyaioyXzRB2RtU8KVE8=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@@ -69,16 +56,12 @@ golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.17.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
-golang.org/x/sys v0.18.0 h1:DBdB3niSjOA/O0blCZBqDefyWNYveAYMNF1Wum0DYQ4=
-golang.org/x/sys v0.18.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o=
 golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.17.0/go.mod h1:lLRBjIVuehSbZlaOtGMbcMncT+aqLLLmKrsjNrUguwk=
-golang.org/x/term v0.18.0 h1:FcHjZXDMxI8mM3nwhX9HlKop4C0YQvCVCdwYl2wOtE8=
-golang.org/x/term v0.18.0/go.mod h1:ILwASektA3OnRv7amZ1xhE/KTR+u50pbXfZ03+6Nx58=
 golang.org/x/term v0.19.0 h1:+ThwsDv+tYfnJFhF4L8jITxu1tdTWRTZpdsWgEgjL6Q=
 golang.org/x/term v0.19.0/go.mod h1:2CuTdWZ7KHSQwUzKva0cbMg6q2DMI3Mmxp+gKJbskEk=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
index 48a6947b7fbbc325995f21d3b1103d784b199d27..f73265d6f7a0f8643384dc53331bc2d1ae0236ff 100644 (file)
@@ -3,9 +3,9 @@ package hotline
 import (
        "encoding/binary"
        "fmt"
-       "go.uber.org/zap"
        "golang.org/x/crypto/bcrypt"
        "io"
+       "log/slog"
        "math/big"
        "sort"
        "strings"
@@ -44,7 +44,7 @@ type ClientConn struct {
        transfersMU sync.Mutex
        transfers   map[int]map[[4]byte]*FileTransfer
 
-       logger *zap.SugaredLogger
+       logger *slog.Logger
 }
 
 func (cc *ClientConn) sendAll(t int, fields ...Field) {
@@ -61,7 +61,7 @@ func (cc *ClientConn) handleTransaction(transaction Transaction) error {
 
                        // Validate that required field is present
                        if field.ID == nil {
-                               cc.logger.Errorw(
+                               cc.logger.Error(
                                        "Missing required field",
                                        "RequestType", handler.Name, "FieldID", reqField.ID,
                                )
@@ -69,7 +69,7 @@ func (cc *ClientConn) handleTransaction(transaction Transaction) error {
                        }
 
                        if len(field.Data) < reqField.minLen {
-                               cc.logger.Infow(
+                               cc.logger.Info(
                                        "Field does not meet minLen",
                                        "RequestType", handler.Name, "FieldID", reqField.ID,
                                )
@@ -77,7 +77,7 @@ func (cc *ClientConn) handleTransaction(transaction Transaction) error {
                        }
                }
 
-               cc.logger.Debugw("Received Transaction", "RequestType", handler.Name)
+               cc.logger.Debug("Received Transaction", "RequestType", handler.Name)
 
                transactions, err := handler.Handler(cc, &transaction)
                if err != nil {
@@ -87,7 +87,7 @@ func (cc *ClientConn) handleTransaction(transaction Transaction) error {
                        cc.Server.outbox <- t
                }
        } else {
-               cc.logger.Errorw(
+               cc.logger.Error(
                        "Unimplemented transaction type received", "RequestID", requestNum)
        }
 
@@ -149,7 +149,7 @@ func (cc *ClientConn) Disconnect() {
        }
 
        if err := cc.Connection.Close(); err != nil {
-               cc.Server.Logger.Errorw("error closing client connection", "RemoteAddr", cc.RemoteAddr)
+               cc.Server.Logger.Error("error closing client connection", "RemoteAddr", cc.RemoteAddr)
        }
 }
 
index e7c97dbe1fa4502af81de2efb624742b3d02cb10..d7376dbf5e5f22bba26c659c41479b07077b92c8 100644 (file)
@@ -2,14 +2,14 @@ package hotline
 
 import (
        "fmt"
-       "go.uber.org/zap"
+       "log/slog"
        "runtime/debug"
 )
 
 // dontPanic logs panics instead of crashing
-func dontPanic(logger *zap.SugaredLogger) {
+func dontPanic(logger *slog.Logger) {
        if r := recover(); r != nil {
                fmt.Println("stacktrace from panic: \n" + string(debug.Stack()))
-               logger.Errorw("PANIC", "err", r, "trace", string(debug.Stack()))
+               logger.Error("PANIC", "err", r, "trace", string(debug.Stack()))
        }
 }
index b5bb0d515cde11cf2bc6cb013bbc6a04b7ba3aa1..f2a69ad735b31c4bcd0884b13ca49c99dd3bd525 100644 (file)
@@ -8,11 +8,12 @@ import (
        "errors"
        "fmt"
        "github.com/go-playground/validator/v10"
-       "go.uber.org/zap"
        "golang.org/x/text/encoding/charmap"
        "gopkg.in/yaml.v3"
        "io"
        "io/fs"
+       "log"
+       "log/slog"
        "math/big"
        "math/rand"
        "net"
@@ -48,7 +49,7 @@ type Server struct {
 
        Config    *Config
        ConfigDir string
-       Logger    *zap.SugaredLogger
+       Logger    *slog.Logger
        banner    []byte
 
        PrivateChatsMu sync.Mutex
@@ -91,7 +92,7 @@ type PrivateChat struct {
 }
 
 func (s *Server) ListenAndServe(ctx context.Context, cancelRoot context.CancelFunc) error {
-       s.Logger.Infow("Hotline server started",
+       s.Logger.Info("Hotline server started",
                "version", VERSION,
                "API port", fmt.Sprintf("%s:%v", s.NetInterface, s.Port),
                "Transfer port", fmt.Sprintf("%s:%v", s.NetInterface, s.Port+1),
@@ -103,20 +104,20 @@ func (s *Server) ListenAndServe(ctx context.Context, cancelRoot context.CancelFu
        go func() {
                ln, err := net.Listen("tcp", fmt.Sprintf("%s:%v", s.NetInterface, s.Port))
                if err != nil {
-                       s.Logger.Fatal(err)
+                       log.Fatal(err)
                }
 
-               s.Logger.Fatal(s.Serve(ctx, ln))
+               log.Fatal(s.Serve(ctx, ln))
        }()
 
        wg.Add(1)
        go func() {
                ln, err := net.Listen("tcp", fmt.Sprintf("%s:%v", s.NetInterface, s.Port+1))
                if err != nil {
-                       s.Logger.Fatal(err)
+                       log.Fatal(err)
                }
 
-               s.Logger.Fatal(s.ServeFileTransfers(ctx, ln))
+               log.Fatal(s.ServeFileTransfers(ctx, ln))
        }()
 
        wg.Wait()
@@ -142,7 +143,7 @@ func (s *Server) ServeFileTransfers(ctx context.Context, ln net.Listener) error
                        )
 
                        if err != nil {
-                               s.Logger.Errorw("file transfer error", "reason", err)
+                               s.Logger.Error("file transfer error", "reason", err)
                        }
                }()
        }
@@ -179,7 +180,7 @@ func (s *Server) processOutbox() {
                t := <-s.outbox
                go func() {
                        if err := s.sendTransaction(t); err != nil {
-                               s.Logger.Errorw("error sending transaction", "err", err)
+                               s.Logger.Error("error sending transaction", "err", err)
                        }
                }()
        }
@@ -191,21 +192,21 @@ func (s *Server) Serve(ctx context.Context, ln net.Listener) error {
        for {
                conn, err := ln.Accept()
                if err != nil {
-                       s.Logger.Errorw("error accepting connection", "err", err)
+                       s.Logger.Error("error accepting connection", "err", err)
                }
                connCtx := context.WithValue(ctx, contextKeyReq, requestCtx{
                        remoteAddr: conn.RemoteAddr().String(),
                })
 
                go func() {
-                       s.Logger.Infow("Connection established", "RemoteAddr", conn.RemoteAddr())
+                       s.Logger.Info("Connection established", "RemoteAddr", conn.RemoteAddr())
 
                        defer conn.Close()
                        if err := s.handleNewConnection(connCtx, conn, conn.RemoteAddr().String()); err != nil {
                                if err == io.EOF {
-                                       s.Logger.Infow("Client disconnected", "RemoteAddr", conn.RemoteAddr())
+                                       s.Logger.Info("Client disconnected", "RemoteAddr", conn.RemoteAddr())
                                } else {
-                                       s.Logger.Errorw("error serving request", "RemoteAddr", conn.RemoteAddr(), "err", err)
+                                       s.Logger.Error("error serving request", "RemoteAddr", conn.RemoteAddr(), "err", err)
                                }
                        }
                }()
@@ -217,7 +218,7 @@ const (
 )
 
 // NewServer constructs a new Server from a config dir
-func NewServer(configDir, netInterface string, netPort int, logger *zap.SugaredLogger, fs FileStore) (*Server, error) {
+func NewServer(configDir, netInterface string, netPort int, logger *slog.Logger, fs FileStore) (*Server, error) {
        server := Server{
                NetInterface:  netInterface,
                Port:          netPort,
@@ -280,7 +281,7 @@ func NewServer(configDir, netInterface string, netPort int, logger *zap.SugaredL
        *server.NextGuestID = 1
 
        if server.Config.EnableTrackerRegistration {
-               server.Logger.Infow(
+               server.Logger.Info(
                        "Tracker registration enabled",
                        "frequency", fmt.Sprintf("%vs", trackerUpdateFrequency),
                        "trackers", server.Config.Trackers,
@@ -297,9 +298,9 @@ func NewServer(configDir, netInterface string, netPort int, logger *zap.SugaredL
                                binary.BigEndian.PutUint16(tr.Port[:], uint16(server.Port))
                                for _, t := range server.Config.Trackers {
                                        if err := register(t, tr); err != nil {
-                                               server.Logger.Errorw("unable to register with tracker %v", "error", err)
+                                               server.Logger.Error("unable to register with tracker %v", "error", err)
                                        }
-                                       server.Logger.Debugw("Sent Tracker registration", "addr", t)
+                                       server.Logger.Debug("Sent Tracker registration", "addr", t)
                                }
 
                                time.Sleep(trackerUpdateFrequency * time.Second)
@@ -684,7 +685,7 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
                        return err
                }
 
-               c.logger.Infow("Login failed", "clientVersion", fmt.Sprintf("%x", c.Version))
+               c.logger.Info("Login failed", "clientVersion", fmt.Sprintf("%x", c.Version))
 
                return nil
        }
@@ -735,7 +736,7 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
                // part of TranAgreed
                c.logger = c.logger.With("name", string(c.UserName))
 
-               c.logger.Infow("Login successful", "clientVersion", "Not sent (probably 1.2.3)")
+               c.logger.Info("Login successful", "clientVersion", "Not sent (probably 1.2.3)")
 
                // Notify other clients on the server that the new user has logged in.  For 1.5+ clients we don't have this
                // information yet, so we do it in TranAgreed instead
@@ -770,7 +771,7 @@ func (s *Server) handleNewConnection(ctx context.Context, rwc io.ReadWriteCloser
                }
 
                if err := c.handleTransaction(t); err != nil {
-                       c.logger.Errorw("Error handling transaction", "err", err)
+                       c.logger.Error("Error handling transaction", "err", err)
                }
        }
        return nil
@@ -867,7 +868,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                        return err
                }
 
-               rLogger.Infow("File download started", "filePath", fullPath)
+               rLogger.Info("File download started", "filePath", fullPath)
 
                // if file transfer options are included, that means this is a "quick preview" request from a 1.5+ client
                if fileTransfer.options == nil {
@@ -939,7 +940,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                        return err
                }
 
-               rLogger.Infow("File upload started", "dstFile", fullPath)
+               rLogger.Info("File upload started", "dstFile", fullPath)
 
                rForkWriter := io.Discard
                iForkWriter := io.Discard
@@ -956,7 +957,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                }
 
                if err := receiveFile(rwc, file, rForkWriter, iForkWriter, fileTransfer.bytesSentCounter); err != nil {
-                       s.Logger.Error(err)
+                       s.Logger.Error(err.Error())
                }
 
                if err := file.Close(); err != nil {
@@ -967,7 +968,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                        return err
                }
 
-               rLogger.Infow("File upload complete", "dstFile", fullPath)
+               rLogger.Info("File upload complete", "dstFile", fullPath)
 
        case FolderDownload:
                s.Stats.DownloadCounter += 1
@@ -1003,7 +1004,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
 
                basePathLen := len(fullPath)
 
-               rLogger.Infow("Start folder download", "path", fullPath)
+               rLogger.Info("Start folder download", "path", fullPath)
 
                nextAction := make([]byte, 2)
                if _, err := io.ReadFull(rwc, nextAction); err != nil {
@@ -1030,7 +1031,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                        }
 
                        subPath := path[basePathLen+1:]
-                       rLogger.Debugw("Sending fileheader", "i", i, "path", path, "fullFilePath", fullPath, "subPath", subPath, "IsDir", info.IsDir())
+                       rLogger.Debug("Sending fileheader", "i", i, "path", path, "fullFilePath", fullPath, "subPath", subPath, "IsDir", info.IsDir())
 
                        if i == 1 {
                                return nil
@@ -1046,7 +1047,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                return err
                        }
 
-                       rLogger.Debugw("Client folder download action", "action", fmt.Sprintf("%X", nextAction[0:2]))
+                       rLogger.Debug("Client folder download action", "action", fmt.Sprintf("%X", nextAction[0:2]))
 
                        var dataOffset int64
 
@@ -1078,14 +1079,14 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                return nil
                        }
 
-                       rLogger.Infow("File download started",
+                       rLogger.Info("File download started",
                                "fileName", info.Name(),
                                "TransferSize", fmt.Sprintf("%x", hlFile.ffo.TransferSize(dataOffset)),
                        )
 
                        // Send file size to client
                        if _, err := rwc.Write(hlFile.ffo.TransferSize(dataOffset)); err != nil {
-                               s.Logger.Error(err)
+                               s.Logger.Error(err.Error())
                                return err
                        }
 
@@ -1137,7 +1138,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                s.Stats.UploadCounter += 1
                s.Stats.UploadsInProgress += 1
                defer func() { s.Stats.UploadsInProgress -= 1 }()
-               rLogger.Infow(
+               rLogger.Info(
                        "Folder upload started",
                        "dstPath", fullPath,
                        "TransferSize", binary.BigEndian.Uint32(fileTransfer.TransferSize),
@@ -1178,7 +1179,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                return err
                        }
 
-                       rLogger.Infow(
+                       rLogger.Info(
                                "Folder upload continued",
                                "FormattedPath", fu.FormattedPath(),
                                "IsFolder", fmt.Sprintf("%x", fu.IsFolder),
@@ -1249,7 +1250,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                        }
 
                                        if err := receiveFile(rwc, file, io.Discard, io.Discard, fileTransfer.bytesSentCounter); err != nil {
-                                               s.Logger.Error(err)
+                                               s.Logger.Error(err.Error())
                                        }
 
                                        err = os.Rename(fullPath+"/"+fu.FormattedPath()+".incomplete", fullPath+"/"+fu.FormattedPath())
@@ -1269,7 +1270,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                                return err
                                        }
 
-                                       rLogger.Infow("Starting file transfer", "path", filePath, "fileNum", i+1, "fileSize", binary.BigEndian.Uint32(fileSize))
+                                       rLogger.Info("Starting file transfer", "path", filePath, "fileNum", i+1, "fileSize", binary.BigEndian.Uint32(fileSize))
 
                                        incWriter, err := hlFile.incFileWriter()
                                        if err != nil {
@@ -1304,7 +1305,7 @@ func (s *Server) handleFileTransfer(ctx context.Context, rwc io.ReadWriter) erro
                                }
                        }
                }
-               rLogger.Infof("Folder upload complete")
+               rLogger.Info("Folder upload complete")
        }
 
        return nil
index 138a17f285ca782e64c8c2c79811c893ef9789e4..27ac4a7a313ae8108c38bba238efcd206d9a6e81 100644 (file)
@@ -4,27 +4,13 @@ import (
        "bytes"
        "encoding/hex"
        "github.com/stretchr/testify/assert"
-       "go.uber.org/zap"
-       "go.uber.org/zap/zapcore"
+       "log/slog"
        "os"
        "testing"
 )
 
-func NewTestLogger() *zap.SugaredLogger {
-       encoderCfg := zap.NewProductionEncoderConfig()
-       encoderCfg.TimeKey = "timestamp"
-       encoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder
-
-       core := zapcore.NewCore(
-               zapcore.NewConsoleEncoder(encoderCfg),
-               zapcore.Lock(os.Stdout),
-               zap.DebugLevel,
-       )
-
-       cores := []zapcore.Core{core}
-       l := zap.New(zapcore.NewTee(cores...))
-       defer func() { _ = l.Sync() }()
-       return l.Sugar()
+func NewTestLogger() *slog.Logger {
+       return slog.New(slog.NewTextHandler(os.Stdout, nil))
 }
 
 // assertTransferBytesEqual takes a string with a hexdump in the same format that `hexdump -C` produces and compares with
index 7e2608ed603f46f098feaf233d418ba2a0d17880..3a368e0315786ebf0969c5b02fa5c974f38601e1 100644 (file)
@@ -5,8 +5,8 @@ import (
        "context"
        "fmt"
        "github.com/stretchr/testify/assert"
-       "go.uber.org/zap"
        "io"
+       "log/slog"
        "os"
        "sync"
        "testing"
@@ -35,7 +35,7 @@ func TestServer_handleFileTransfer(t *testing.T) {
                fileTransfers map[[4]byte]*FileTransfer
                Config        *Config
                ConfigDir     string
-               Logger        *zap.SugaredLogger
+               Logger        *slog.Logger
                PrivateChats  map[uint32]*PrivateChat
                NextGuestID   *uint16
                TrackerPassID [4]byte
index ff23684b21eda1c678e37148a81faa5869b33f0a..3accf2c647dad26c9f16ecb8eae486d524cbb85c 100644 (file)
@@ -574,7 +574,7 @@ func HandleMoveFile(cc *ClientConn, t *Transaction) (res []Transaction, err erro
                return res, err
        }
 
-       cc.logger.Infow("Move file", "src", filePath+"/"+fileName, "dst", fileNewPath+"/"+fileName)
+       cc.logger.Info("Move file", "src", filePath+"/"+fileName, "dst", fileNewPath+"/"+fileName)
 
        hlFile, err := newFileWrapper(cc.Server.FS, filePath, 0)
        if err != nil {
@@ -784,7 +784,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                        }
 
                        login := string(encodeString(getField(FieldData, &subFields).Data))
-                       cc.logger.Infow("DeleteUser", "login", login)
+                       cc.logger.Info("DeleteUser", "login", login)
 
                        if err := cc.Server.DeleteUser(login); err != nil {
                                return res, err
@@ -810,9 +810,9 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                // Check if accountToUpdate has an existing account.  If so, we know we are updating an existing user.
                if acc, ok := cc.Server.Accounts[accountToUpdate]; ok {
                        if loginToRename != "" {
-                               cc.logger.Infow("RenameUser", "prevLogin", accountToUpdate, "newLogin", userLogin)
+                               cc.logger.Info("RenameUser", "prevLogin", accountToUpdate, "newLogin", userLogin)
                        } else {
-                               cc.logger.Infow("UpdateUser", "login", accountToUpdate)
+                               cc.logger.Info("UpdateUser", "login", accountToUpdate)
                        }
 
                        // account exists, so this is an update action
@@ -857,7 +857,7 @@ func HandleUpdateUser(cc *ClientConn, t *Transaction) (res []Transaction, err er
                                return res, nil
                        }
 
-                       cc.logger.Infow("CreateUser", "login", userLogin)
+                       cc.logger.Info("CreateUser", "login", userLogin)
 
                        newAccess := accessBitmap{}
                        copy(newAccess[:], getField(FieldUserAccess, &subFields).Data)
@@ -998,7 +998,7 @@ func HandleTranAgreed(cc *ClientConn, t *Transaction) (res []Transaction, err er
        cc.Icon = t.GetField(FieldUserIconID).Data
 
        cc.logger = cc.logger.With("name", string(cc.UserName))
-       cc.logger.Infow("Login successful", "clientVersion", fmt.Sprintf("%v", func() int { i, _ := byteToInt(cc.Version); return i }()))
+       cc.logger.Info("Login successful", "clientVersion", fmt.Sprintf("%v", func() int { i, _ := byteToInt(cc.Version); return i }()))
 
        options := t.GetField(FieldOptions).Data
        optBitmap := big.NewInt(int64(binary.BigEndian.Uint16(options)))
@@ -1107,7 +1107,7 @@ func HandleDisconnectUser(cc *ClientConn, t *Transaction) (res []Transaction, er
                switch t.GetField(FieldOptions).Data[1] {
                case 1:
                        // send message: "You are temporarily banned on this server"
-                       cc.logger.Infow("Disconnect & temporarily ban " + string(clientConn.UserName))
+                       cc.logger.Info("Disconnect & temporarily ban " + string(clientConn.UserName))
 
                        res = append(res, *NewTransaction(
                                TranServerMsg,
@@ -1120,7 +1120,7 @@ func HandleDisconnectUser(cc *ClientConn, t *Transaction) (res []Transaction, er
                        cc.Server.banList[strings.Split(clientConn.RemoteAddr, ":")[0]] = &banUntil
                case 2:
                        // send message: "You are permanently banned on this server"
-                       cc.logger.Infow("Disconnect & ban " + string(clientConn.UserName))
+                       cc.logger.Info("Disconnect & ban " + string(clientConn.UserName))
 
                        res = append(res, *NewTransaction(
                                TranServerMsg,
@@ -1218,8 +1218,6 @@ func HandleNewNewsFldr(cc *ClientConn, t *Transaction) (res []Transaction, err e
        name := string(t.GetField(FieldFileName).Data)
        pathStrs := ReadNewsPath(t.GetField(FieldNewsPath).Data)
 
-       cc.logger.Infof("Creating new news folder %s", name)
-
        cats := cc.Server.GetNewsCatByPath(pathStrs)
        cats[name] = NewsCategoryListData15{
                Name:     name,
@@ -2024,7 +2022,7 @@ func HandleMakeAlias(cc *ClientConn, t *Transaction) (res []Transaction, err err
                return res, err
        }
 
-       cc.logger.Debugw("Make alias", "src", fullFilePath, "dst", fullNewFilePath)
+       cc.logger.Debug("Make alias", "src", fullFilePath, "dst", fullNewFilePath)
 
        if err := cc.Server.FS.Symlink(fullFilePath, fullNewFilePath); err != nil {
                res = append(res, cc.NewErrReply(t, "Error creating alias"))