diff --git a/go.mod b/go.mod index 45ee502e702387f4db673088847e745da2cb4856..b6ce699aec8a7b6956946de718cc49201cd74310 100644 --- a/go.mod +++ b/go.mod @@ -4,7 +4,6 @@ go 1.20 require ( gfx.cafe/ghalliday1/scram v0.0.2 - gfx.cafe/util/go/gun v0.0.0-20230721185457-c559e86c829c github.com/caddyserver/caddy/v2 v2.7.4 github.com/digitalocean/godo v1.102.1 github.com/google/uuid v1.3.0 @@ -12,7 +11,6 @@ require ( google.golang.org/api v0.126.0 k8s.io/apimachinery v0.27.4 k8s.io/client-go v0.27.4 - tuxpa.in/a/zlog v1.61.0 ) require ( diff --git a/lib/gat/app.go b/lib/gat/app.go index eafd6e4128a65b8ea505c4b285216d7c309c6c65..b92ddac70e9e7d57d462c062928f881edc3f7603 100644 --- a/lib/gat/app.go +++ b/lib/gat/app.go @@ -4,10 +4,11 @@ import ( "crypto/tls" "errors" "fmt" + "io" "net" "github.com/caddyserver/caddy/v2" - "tuxpa.in/a/zlog/log" + "go.uber.org/zap" "gfx.cafe/gfx/pggat/lib/bouncer/frontends/v0" "gfx.cafe/gfx/pggat/lib/fed" @@ -37,6 +38,8 @@ type App struct { servers []*Server keys maps.RWLocked[[8]byte, *Pool] + + log *zap.Logger } func (T *App) CaddyModule() caddy.ModuleInfo { @@ -49,6 +52,8 @@ func (T *App) CaddyModule() caddy.ModuleInfo { } func (T *App) Provision(ctx caddy.Context) error { + T.log = ctx.Logger() + T.listen = make([]*Listener, 0, len(T.Listen)) for _, config := range T.Listen { listener := &Listener{ @@ -101,21 +106,21 @@ func (T *App) serve(server *Server, conn fed.Conn) { p := server.lookup(conn) if p == nil { - log.Printf("pool not found for client: user=%s database=%s", conn.User(), conn.Database()) + T.log.Warn("database not found", zap.String("user", conn.User()), zap.String("database", conn.Database())) return } backendKey, err := frontends.Authenticate(conn, p.Credentials()) if err != nil { - log.Printf("error authenticating client: %v", err) + T.log.Warn("error authenticating client", zap.Error(err)) return } T.keys.Store(backendKey, p) defer T.keys.Delete(backendKey) - if err2 := p.Serve(conn, backendKey); err2 != nil { - log.Printf("error serving client: %v", err2) + if err2 := p.Serve(conn, backendKey); err2 != nil && !errors.Is(err2, io.EOF) { + T.log.Warn("error serving client", zap.Error(err2)) return } } @@ -132,7 +137,7 @@ func (T *App) accept(listener *Listener, conn *fed.NetConn) { cancelKey, isCanceling, _, user, database, initialParameters, err := frontends.Accept(conn, tlsConfig) if err != nil { - log.Printf("error accepting client: %v", err) + T.log.Warn("error accepting client", zap.Error(err)) return } @@ -152,7 +157,7 @@ func (T *App) accept(listener *Listener, conn *fed.NetConn) { } } - log.Printf("server not found for client: user=%s database=%s", conn.User(), conn.Database()) + T.log.Warn("server not found", zap.String("user", conn.User()), zap.String("database", conn.Database())) errResp := packets.ErrorResponse{ Error: perror.New( @@ -170,7 +175,7 @@ func (T *App) acceptFrom(listener *Listener) bool { if errors.Is(err, net.ErrClosed) { return false } - log.Printf("error accepting client: %v", err) + T.log.Warn("error accepting client", zap.Error(err)) return true } diff --git a/lib/gat/listen.go b/lib/gat/listen.go index 1a92f4ae563b58c15c847bcf4d75fa13f4e3182f..dd0f28661af7d9ee259a9d87631968b1129d1ee7 100644 --- a/lib/gat/listen.go +++ b/lib/gat/listen.go @@ -6,7 +6,7 @@ import ( "net" "github.com/caddyserver/caddy/v2" - "tuxpa.in/a/zlog/log" + "go.uber.org/zap" "gfx.cafe/gfx/pggat/lib/fed" ) @@ -23,6 +23,8 @@ type Listener struct { ssl SSLServer listener net.Listener + + log *zap.Logger } func (T *Listener) accept() (*fed.NetConn, error) { @@ -34,6 +36,8 @@ func (T *Listener) accept() (*fed.NetConn, error) { } func (T *Listener) Provision(ctx caddy.Context) error { + T.log = ctx.Logger() + if T.SSL != nil { val, err := ctx.LoadModule(T, "SSL") if err != nil { @@ -52,7 +56,7 @@ func (T *Listener) Start() error { return err } - log.Printf("listening on %v", T.listener.Addr()) + T.log.Info("listening", zap.String("address", T.listener.Addr().String())) return nil } diff --git a/lib/gat/pool/options.go b/lib/gat/pool/options.go index fa54ff71ff50331835835a1a6de3b25da893a108..00ee3a49a03bfc6c3ed9b2f1a502f318485f3cb1 100644 --- a/lib/gat/pool/options.go +++ b/lib/gat/pool/options.go @@ -1,6 +1,8 @@ package pool import ( + "go.uber.org/zap" + "gfx.cafe/gfx/pggat/lib/auth" "gfx.cafe/gfx/pggat/lib/util/dur" "gfx.cafe/gfx/pggat/lib/util/strutil" @@ -57,4 +59,6 @@ type Options struct { PoolingOptions ManagementOptions + + Logger *zap.Logger } diff --git a/lib/gat/pool/pool.go b/lib/gat/pool/pool.go index 3dd2e3fc1e9c7ce2738afecd10dbae0a1bf758bc..4bd0cd4a954beaa2cd128533cbd6962f2456aff8 100644 --- a/lib/gat/pool/pool.go +++ b/lib/gat/pool/pool.go @@ -7,7 +7,7 @@ import ( "time" "github.com/google/uuid" - "tuxpa.in/a/zlog/log" + "go.uber.org/zap" "gfx.cafe/gfx/pggat/lib/auth" "gfx.cafe/gfx/pggat/lib/bouncer/backends/v0" @@ -103,7 +103,7 @@ func (T *Pool) AddRecipe(name string, r *Recipe) { count := r.AllocateInitial() for i := 0; i < count; i++ { if err := T.scaleUpL1(name, r); err != nil { - log.Printf("failed to dial server: %v", err) + T.options.Logger.Warn("failed to dial server", zap.Error(err)) for j := i; j < count; j++ { r.Free() } @@ -208,7 +208,7 @@ func (T *Pool) scaleUp() bool { err := T.scaleUpL1(name, r) if err != nil { - log.Printf("failed to dial server: %v", err) + T.options.Logger.Warn("failed to dial server", zap.Error(err)) return false } @@ -230,9 +230,12 @@ func (T *Pool) removeServerL1(server *pooledServer) { name := server.GetRecipe() T.serversByRecipe[name] = slices.Delete(T.serversByRecipe[name], server) // update order - T.recipeScaleOrder.Update(slices.Index(T.recipeScaleOrder, name), func(n string) int { - return len(T.serversByRecipe[n]) - }) + index := slices.Index(T.recipeScaleOrder, name) + if index != -1 { + T.recipeScaleOrder.Update(index, func(n string) int { + return len(T.serversByRecipe[n]) + }) + } } } diff --git a/lib/gat/pool/scaler.go b/lib/gat/pool/scaler.go index ecf238ab6a221ccd7ca9203db049886d701a5f3d..b758de618e3de98ff1a325115ef5dfcbe1ae192a 100644 --- a/lib/gat/pool/scaler.go +++ b/lib/gat/pool/scaler.go @@ -3,7 +3,7 @@ package pool import ( "time" - "tuxpa.in/a/zlog/log" + "go.uber.org/zap" ) type scaler struct { @@ -80,7 +80,7 @@ func (T *scaler) pendingTimeout() { T.pending.Reset(T.backoff) } - log.Printf("failed to dial server. trying again in %v", T.backoff) + T.pool.options.Logger.Warn("failed to dial server", zap.Duration("backoff", T.backoff)) return } diff --git a/lib/gat/poolers/session/pool.go b/lib/gat/poolers/session/pool.go index 0e0f44dfa4d2e86b487d5e1c95a7a16b904d6b89..5e807022d22fe2d3a2f438b8774e4d50e73c92ec 100644 --- a/lib/gat/poolers/session/pool.go +++ b/lib/gat/poolers/session/pool.go @@ -2,6 +2,7 @@ package session import ( "github.com/caddyserver/caddy/v2" + "go.uber.org/zap" "gfx.cafe/gfx/pggat/lib/auth" "gfx.cafe/gfx/pggat/lib/gat" @@ -21,6 +22,8 @@ func init() { type Pool struct { pool.ManagementOptions + + log *zap.Logger } func (T *Pool) CaddyModule() caddy.ModuleInfo { @@ -32,6 +35,11 @@ func (T *Pool) CaddyModule() caddy.ModuleInfo { } } +func (T *Pool) Provision(ctx caddy.Context) error { + T.log = ctx.Logger() + return nil +} + func (T *Pool) NewPool(creds auth.Credentials) *gat.Pool { return pool.NewPool(pool.Options{ Credentials: creds, @@ -39,8 +47,11 @@ func (T *Pool) NewPool(creds auth.Credentials) *gat.Pool { PoolingOptions: PoolingOptions, ManagementOptions: T.ManagementOptions, + + Logger: T.log, }) } var _ gat.Pooler = (*Pool)(nil) var _ caddy.Module = (*Pool)(nil) +var _ caddy.Provisioner = (*Pool)(nil) diff --git a/lib/gat/poolers/transaction/pool.go b/lib/gat/poolers/transaction/pool.go index 46e26ecd5902db6e1f13b42eda722c7d2e0b29f6..e8915cd78dbdab1a9f7b45dc27cef748922b21fb 100644 --- a/lib/gat/poolers/transaction/pool.go +++ b/lib/gat/poolers/transaction/pool.go @@ -2,6 +2,7 @@ package transaction import ( "github.com/caddyserver/caddy/v2" + "go.uber.org/zap" "gfx.cafe/gfx/pggat/lib/auth" "gfx.cafe/gfx/pggat/lib/gat" @@ -21,6 +22,8 @@ func init() { type Pool struct { pool.ManagementOptions + + log *zap.Logger } func (T *Pool) CaddyModule() caddy.ModuleInfo { @@ -32,6 +35,11 @@ func (T *Pool) CaddyModule() caddy.ModuleInfo { } } +func (T *Pool) Provision(ctx caddy.Context) error { + T.log = ctx.Logger() + return nil +} + func (T *Pool) NewPool(creds auth.Credentials) *gat.Pool { return pool.NewPool(pool.Options{ Credentials: creds, @@ -39,6 +47,8 @@ func (T *Pool) NewPool(creds auth.Credentials) *gat.Pool { PoolingOptions: PoolingOptions, ManagementOptions: T.ManagementOptions, + + Logger: T.log, }) } diff --git a/lib/gat/providers/discovery/module.go b/lib/gat/providers/discovery/module.go index b3c351b1e52cd41312e14385468e2d517e90113c..5a84ae5cfe253bca3c6c8cefa83faabacb9b99a3 100644 --- a/lib/gat/providers/discovery/module.go +++ b/lib/gat/providers/discovery/module.go @@ -6,7 +6,7 @@ import ( "time" "github.com/caddyserver/caddy/v2" - "tuxpa.in/a/zlog/log" + "go.uber.org/zap" "gfx.cafe/gfx/pggat/lib/auth" "gfx.cafe/gfx/pggat/lib/auth/credentials" @@ -41,6 +41,8 @@ type Module struct { pools maps.TwoKey[string, string, *pool.Pool] mu sync.RWMutex + + log *zap.Logger } func (*Module) CaddyModule() caddy.ModuleInfo { @@ -53,6 +55,8 @@ func (*Module) CaddyModule() caddy.ModuleInfo { } func (T *Module) Provision(ctx caddy.Context) error { + T.log = ctx.Logger() + if T.Discoverer != nil { val, err := ctx.LoadModule(T, "Discoverer") if err != nil { @@ -471,7 +475,7 @@ func (T *Module) discoverLoop() { case <-reconcile: err := T.reconcile() if err != nil { - log.Printf("failed to reconcile: %v", err) + T.log.Warn("failed to reconcile", zap.Error(err)) } } } @@ -480,7 +484,7 @@ func (T *Module) discoverLoop() { func (T *Module) addPool(user, database string, p *pool.Pool) { T.mu.Lock() defer T.mu.Unlock() - log.Printf("added pool user=%s database=%s", user, database) + T.log.Info("added pool", zap.String("user", user), zap.String("database", database)) if old, ok := T.pools.Load(user, database); ok { // shouldn't normally get here old.Close() @@ -496,7 +500,7 @@ func (T *Module) removePool(user, database string) { return } p.Close() - log.Printf("removed pool user=%s database=%s", user, database) + T.log.Info("removed pool", zap.String("user", user), zap.String("database", database)) T.pools.Delete(user, database) } diff --git a/lib/gat/providers/pgbouncer/module.go b/lib/gat/providers/pgbouncer/module.go index eae73261a948cacd05a269cbbecab7036734ef87..e7ee8b49c0c6e3e7eaed78d8e1a1937a608d3020 100644 --- a/lib/gat/providers/pgbouncer/module.go +++ b/lib/gat/providers/pgbouncer/module.go @@ -11,7 +11,7 @@ import ( "time" "github.com/caddyserver/caddy/v2" - "tuxpa.in/a/zlog/log" + "go.uber.org/zap" "gfx.cafe/gfx/pggat/lib/fed" "gfx.cafe/gfx/pggat/lib/gat/poolers/session" @@ -44,6 +44,8 @@ type Module struct { pools maps.TwoKey[string, string, *gat.Pool] mu sync.RWMutex + + log *zap.Logger } func (*Module) CaddyModule() caddy.ModuleInfo { @@ -56,6 +58,8 @@ func (*Module) CaddyModule() caddy.ModuleInfo { } func (T *Module) Provision(ctx caddy.Context) error { + T.log = ctx.Logger() + var err error T.Config, err = Load(T.ConfigFile) return err @@ -100,17 +104,17 @@ func (T *Module) getPassword(user, database string) (string, bool) { client := new(gsql.Client) err := gsql.ExtendedQuery(client, &result, T.Config.PgBouncer.AuthQuery, user) if err != nil { - log.Println("auth query failed:", err) + T.log.Warn("auth query failed", zap.Error(err)) return "", false } err = client.Close() if err != nil { - log.Println("auth query failed:", err) + T.log.Warn("auth query failed", zap.Error(err)) return "", false } err = authPool.ServeBot(client) if err != nil && !errors.Is(err, io.EOF) { - log.Println("auth query failed:", err) + T.log.Warn("auth query failed", zap.Error(err)) return "", false } @@ -176,6 +180,7 @@ func (T *Module) tryCreate(user, database string) *gat.Pool { ServerIdleTimeout: dur.Duration(T.Config.PgBouncer.ServerIdleTimeout * float64(time.Second)), ServerReconnectInitialTime: serverLoginRetry, }, + Logger: T.log, } switch poolMode { diff --git a/lib/gsql/query_test.go b/lib/gsql/query_test.go index 71ef6af29144e047ab26c7f349847c6a226d2b21..2272fce3117d6ec9df1e2b895d3736f8f56f98d4 100644 --- a/lib/gsql/query_test.go +++ b/lib/gsql/query_test.go @@ -1,11 +1,10 @@ package gsql import ( + "log" "net" "testing" - "tuxpa.in/a/zlog/log" - "gfx.cafe/gfx/pggat/lib/auth/credentials" "gfx.cafe/gfx/pggat/lib/bouncer/backends/v0" "gfx.cafe/gfx/pggat/lib/bouncer/bouncers/v2" diff --git a/lib/util/slices/sorted_test.go b/lib/util/slices/sorted_test.go index 49e19e073bf939cd94dfaaed2f793cfde6936b31..bb8dd923b163bc59e0b42eb5ae9e271900a793ec 100644 --- a/lib/util/slices/sorted_test.go +++ b/lib/util/slices/sorted_test.go @@ -1,10 +1,9 @@ package slices import ( + "log" "sort" "testing" - - "tuxpa.in/a/zlog/log" ) func TestSorted_Insert(t *testing.T) {