diff --git a/apps/agent/cmd/agent/main.go b/apps/agent/cmd/agent/main.go index 3ff9dddfb7..dfe1b1ed8a 100644 --- a/apps/agent/cmd/agent/main.go +++ b/apps/agent/cmd/agent/main.go @@ -29,7 +29,6 @@ import ( "github.com/unkeyed/unkey/apps/agent/pkg/server" "github.com/unkeyed/unkey/apps/agent/pkg/tracing" "github.com/unkeyed/unkey/apps/agent/pkg/version" - "go.uber.org/zap" ) type features struct { @@ -37,6 +36,7 @@ type features struct { analytics string eventBus string prewarm bool + verbose bool } var runtimeConfig features @@ -46,6 +46,7 @@ func init() { AgentCmd.Flags().StringVar(&runtimeConfig.analytics, "analytics", "", "Send analytics to a backend, available: ['tinybird']") AgentCmd.Flags().StringVar(&runtimeConfig.eventBus, "event-bus", "", "Use a message bus for communication between nodes, available: ['kafka']") AgentCmd.Flags().BoolVar(&runtimeConfig.prewarm, "prewarm", false, "Load all keys from the db to memory on boot") + AgentCmd.Flags().BoolVarP(&runtimeConfig.verbose, "verbose", "v", false, "Print debug logs") } // AgentCmd represents the agent command @@ -55,24 +56,20 @@ var AgentCmd = &cobra.Command{ Long: ``, Run: func(cmd *cobra.Command, args []string) { - logger := logging.New().With( - zap.String("version", version.Version), - ) + logger := logging.New(runtimeConfig.verbose).With().Str("version", version.Version).Logger() - defer func() { - // this is best effort and can error quite frequently - _ = logger.Sync() - }() - logger.Info("Starting Unkey Agent", zap.Any("runtimeConfig", runtimeConfig)) + logger.Info().Any("runtimeConfig", runtimeConfig).Msg("Starting Unkey Agent") e := env.Env{ - ErrorHandler: func(err error) { logger.Fatal("unable to load environment variable", zap.Error(err)) }, + ErrorHandler: func(err error) { + logger.Fatal().Err(err).Msg("unable to load environment variable") + }, } region := e.String("FLY_REGION", "local") allocId := e.String("FLY_ALLOC_ID", "") - logger = logger.With(zap.String("region", region)) + logger = logger.With().Str("region", region).Logger() if allocId != "" { - logger = logger.With(zap.String("allocId", allocId)) + logger = logger.With().Str("allocId", allocId).Logger() } metrics := metricsPkg.NewNoop() @@ -80,11 +77,11 @@ var AgentCmd = &cobra.Command{ realMetrics, err := metricsPkg.New(metricsPkg.Config{ AxiomOrgId: e.String("AXIOM_ORG_ID"), AxiomToken: e.String("AXIOM_TOKEN"), - Logger: logger.With(zap.String("pkg", "metrics")), + Logger: logger.With().Str("pkg", "metrics").Logger(), Region: region, }) if err != nil { - logger.Fatal("unable to start metrics", zap.Error(err)) + logger.Fatal().Err(err).Msg("unable to start metrics") } metrics = realMetrics } @@ -103,16 +100,16 @@ var AgentCmd = &cobra.Command{ AxiomToken: e.String("AXIOM_TOKEN"), }) if err != nil { - logger.Fatal("unable to start tracer", zap.Error(err)) + logger.Fatal().Err(err).Msg("unable to start tracer") } defer func() { err := closeTracer() if err != nil { - logger.Fatal("unable to close tracer", zap.Error(err)) + logger.Fatal().Err(err).Msg("unable to close tracer") } }() tracer = t - logger.Info("Axiom tracing enabled") + logger.Info().Msg("Axiom tracing enabled") } } @@ -128,7 +125,7 @@ var AgentCmd = &cobra.Command{ database.WithTracing(tracer), ) if err != nil { - logger.Fatal("Failed to connect to database", zap.Error(err)) + logger.Fatal().Err(err).Msg("Failed to connect to database") } defer db.Close() // Setup Analytics @@ -160,7 +157,7 @@ var AgentCmd = &cobra.Command{ Password: e.String("KAFKA_PASSWORD"), }) if err != nil { - logger.Fatal("unable to start kafka", zap.Error(err)) + logger.Fatal().Err(err).Msg("unable to start kafka") } k.Start() @@ -177,7 +174,7 @@ var AgentCmd = &cobra.Command{ RedisUrl: redisUrl, }) if err != nil { - logger.Fatal("unable to start redis ratelimiting", zap.Error(err)) + logger.Fatal().Err(err).Msg("unable to start redis ratelimiting") } } @@ -188,12 +185,12 @@ var AgentCmd = &cobra.Command{ RefreshFromOrigin: func(ctx context.Context, keyHash string) (entities.Key, bool) { key, found, err := db.FindKeyByHash(ctx, keyHash) if err != nil { - logger.Error("unable to refresh key by hash", zap.Error(err)) + logger.Err(err).Msg("unable to refresh key by hash") return entities.Key{}, false } return key, found }, - Logger: logger.With(zap.String("cacheType", "key")), + Logger: logger.With().Str("cacheType", "key").Logger(), Metrics: metrics, Resource: "key", }) @@ -207,12 +204,12 @@ var AgentCmd = &cobra.Command{ RefreshFromOrigin: func(ctx context.Context, apiId string) (entities.Api, bool) { key, found, err := db.FindApi(ctx, apiId) if err != nil { - logger.Error("unable to refresh api by id", zap.Error(err)) + logger.Err(err).Msg("unable to refresh api by id") return entities.Api{}, false } return key, found }, - Logger: logger.With(zap.String("cacheType", "api")), + Logger: logger.With().Str("cacheType", "api").Logger(), Metrics: metrics, Resource: "api", }) @@ -222,12 +219,12 @@ var AgentCmd = &cobra.Command{ eventBus.OnKeyEvent(func(ctx context.Context, e events.KeyEvent) error { if e.Type == events.KeyDeleted { - logger.Info("evicting from cache", zap.String("keyId", e.Key.Id), zap.String("keyHash", e.Key.Hash)) + logger.Debug().Str("keyId", e.Key.Id).Str("keyHash", e.Key.Hash).Msg("evicting from cache") keyCache.Remove(context.Background(), e.Key.Hash) return nil } - logger.Info("precaching key", zap.String("keyId", e.Key.Id), zap.String("keyHash", e.Key.Hash)) + logger.Debug().Str("keyId", e.Key.Id).Str("keyHash", e.Key.Hash).Msg("precaching key") key, found, err := db.FindKeyById(ctx, e.Key.Id) if err != nil { return fmt.Errorf("unable to get key by id: %s: %w", e.Key.Id, err) @@ -236,7 +233,7 @@ var AgentCmd = &cobra.Command{ return nil } keyCache.Set(ctx, key.Hash, key) - logger.Info("precaching api", zap.String("keyAuthId", key.KeyAuthId)) + logger.Debug().Str("keyAuthId", key.KeyAuthId).Msg("precaching api") api, found, err := db.FindApiByKeyAuthId(ctx, key.KeyAuthId) if err != nil { return fmt.Errorf("unable to find api by keyAuthId: %s: %w", key.KeyAuthId, err) @@ -262,7 +259,7 @@ var AgentCmd = &cobra.Command{ go func() { err := cacheWarmer.Run(context.Background()) if err != nil { - logger.Error("unable to warm cache", zap.Error(err)) + logger.Err(err).Msg("unable to warm cache") } }() } @@ -292,12 +289,13 @@ var AgentCmd = &cobra.Command{ EventBus: eventBus, Version: version.Version, WorkspaceService: workspaceService, + Metrics: metrics, }) go func() { err = srv.Start(fmt.Sprintf("0.0.0.0:%s", e.String("PORT", "8080"))) if err != nil { - logger.Fatal("Failed to run service", zap.Error(err)) + logger.Fatal().Err(err).Msg("Failed to run service") } }() defer srv.Close() @@ -307,6 +305,6 @@ var AgentCmd = &cobra.Command{ // wait for signal sig := <-cShutdown - logger.Info("Caught signal, shutting down", zap.Any("sig", sig)) + logger.Info().Any("sig", sig).Msg("Caught signal, shutting down") }, } diff --git a/apps/agent/go.mod b/apps/agent/go.mod index 7cccf9e03f..4aedebbb2e 100644 --- a/apps/agent/go.mod +++ b/apps/agent/go.mod @@ -11,10 +11,11 @@ require ( github.com/gofiber/fiber/v2 v2.47.0 github.com/google/uuid v1.3.0 github.com/joho/godotenv v1.5.1 + github.com/rs/zerolog v1.30.0 github.com/segmentio/kafka-go v0.4.40 github.com/spf13/cobra v1.6.1 github.com/stretchr/testify v1.8.4 - github.com/testcontainers/testcontainers-go v0.22.0 + github.com/testcontainers/testcontainers-go/modules/mysql v0.22.0 go.opentelemetry.io/otel v1.14.0 go.opentelemetry.io/otel/trace v1.14.0 go.uber.org/zap v1.24.0 @@ -70,7 +71,7 @@ require ( github.com/savsgio/gotils v0.0.0-20230208104028-c358bd845dee // indirect github.com/sirupsen/logrus v1.9.0 // indirect github.com/spf13/pflag v1.0.5 // indirect - github.com/testcontainers/testcontainers-go/modules/mysql v0.22.0 // indirect + github.com/testcontainers/testcontainers-go v0.22.0 // indirect github.com/tinylib/msgp v1.1.8 // indirect github.com/valyala/bytebufferpool v1.0.0 // indirect github.com/valyala/fasthttp v1.47.0 // indirect diff --git a/apps/agent/go.sum b/apps/agent/go.sum index ef6a4ce239..fe59fcca58 100644 --- a/apps/agent/go.sum +++ b/apps/agent/go.sum @@ -93,6 +93,7 @@ github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkX github.com/containerd/containerd v1.7.3 h1:cKwYKkP1eTj54bP3wCdXXBymmKRQMrWjkLSWZZJDa8o= github.com/containerd/containerd v1.7.3/go.mod h1:32FOM4/O0RkNg7AjQj3hDzN9cUGtu+HMvaKUNiqCZB8= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/go-systemd/v22 v22.5.0/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= github.com/cpuguy83/dockercfg v0.3.1 h1:/FpZ+JaygUR/lZP2NlFI2DVfrOEMAIKP5wWEJdoYe9E= github.com/cpuguy83/dockercfg v0.3.1/go.mod h1:sugsbF4//dDlL/i+S+rtpIWp+5h0BHJHfjj5/jFyUJc= github.com/cpuguy83/go-md2man/v2 v2.0.0-20190314233015-f79a8a8ca69d/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= @@ -257,8 +258,10 @@ github.com/leodido/go-urn v1.2.4 h1:XlAE/cm/ms7TE/VMVoduSpNBoyc2dOxHs5MZSwAN63Q= github.com/leodido/go-urn v1.2.4/go.mod h1:7ZrI8mTSeBSHl/UaRyKQW1qZeMgak41ANeCNaVckg+4= github.com/magiconair/properties v1.8.7 h1:IeQXZAiQcpL9mgcAe1Nu6cX9LLw6ExEHKjN0VQdvPDY= github.com/magiconair/properties v1.8.7/go.mod h1:Dhd985XPs7jluiymwWYZ0G4Z61jb3vdS329zhj2hYo0= +github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= +github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= 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= @@ -311,6 +314,9 @@ github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6L github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= +github.com/rs/xid v1.5.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= +github.com/rs/zerolog v1.30.0 h1:SymVODrcRsaRaSInD9yQtKbtWqwsfoPcRff/oRXLj4c= +github.com/rs/zerolog v1.30.0/go.mod h1:/tk+P47gFdPXq4QYjvCmT5/Gsug2nagsFWBWhAiSi1w= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/savsgio/dictpool v0.0.0-20221023140959-7bf2e61cea94 h1:rmMl4fXJhKMNWl+K+r/fq4FbbKI+Ia2m9hYBLm2h4G4= @@ -550,7 +556,9 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210906170528-6f6e22806c34/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211025201205-69cdffdb9359/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20211116061358-0a5406a5449c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= diff --git a/apps/agent/pkg/analytics/tinybird/tinybird.go b/apps/agent/pkg/analytics/tinybird/tinybird.go index 5bfa7d22c5..36ab49bc7f 100644 --- a/apps/agent/pkg/analytics/tinybird/tinybird.go +++ b/apps/agent/pkg/analytics/tinybird/tinybird.go @@ -10,7 +10,7 @@ import ( "time" "github.com/unkeyed/unkey/apps/agent/pkg/analytics" - "go.uber.org/zap" + "github.com/unkeyed/unkey/apps/agent/pkg/logging" ) type Tinybird struct { @@ -21,7 +21,7 @@ type Tinybird struct { keyVerificationsC chan analytics.KeyVerificationEvent closeC chan struct{} - logger *zap.Logger + logger logging.Logger } var _ analytics.Analytics = &Tinybird{} @@ -30,7 +30,7 @@ type Config struct { // Token is the Tinybird token Token string - Logger *zap.Logger + Logger logging.Logger } func New(config Config) *Tinybird { @@ -62,12 +62,12 @@ func (t *Tinybird) consume() { Time: e.Time, }) if err != nil { - t.logger.Error("unable to publish v1 event to tinybird", zap.Error(err)) + t.logger.Err(err).Msg("unable to publish v1 event to tinybird") } err = t.publishEvent("key_verifications__v2", e) if err != nil { - t.logger.Error("unable to publish event to tinybird", zap.Error(err)) + t.logger.Err(err).Msg("unable to publish event to tinybird") } } } @@ -79,7 +79,7 @@ func (t *Tinybird) Close() { } func (t *Tinybird) PublishKeyVerificationEvent(ctx context.Context, event analytics.KeyVerificationEvent) { - t.logger.Info("publishing event", zap.Any("event", event)) + t.logger.Debug().Any("event", event).Msg("publishing event") t.keyVerificationsC <- event } diff --git a/apps/agent/pkg/boot/cache_warmer.go b/apps/agent/pkg/boot/cache_warmer.go index 191e7c0b52..8082234549 100644 --- a/apps/agent/pkg/boot/cache_warmer.go +++ b/apps/agent/pkg/boot/cache_warmer.go @@ -8,7 +8,6 @@ import ( "github.com/unkeyed/unkey/apps/agent/pkg/database" "github.com/unkeyed/unkey/apps/agent/pkg/entities" "github.com/unkeyed/unkey/apps/agent/pkg/logging" - "go.uber.org/zap" ) type CacheWarmer struct { @@ -31,7 +30,7 @@ func NewCacheWarmer(config Config) *CacheWarmer { apiCache: config.ApiCache, keyCache: config.KeyCache, db: config.DB, - logger: config.Logger.With(zap.String("pkg", "cacheWarmer")), + logger: config.Logger.With().Str("pkg", "cacheWarmer").Logger(), stopped: false, } } @@ -56,8 +55,8 @@ func (c *CacheWarmer) Run(ctx context.Context) error { return fmt.Errorf("unable to list apis: %w", err) } for _, api := range apis { - logger := c.logger.With(zap.String("apiId", api.Id)) - logger.Info("seeding api") + logger := c.logger.With().Str("apiId", api.Id).Logger() + logger.Info().Msg("seeding api") c.apiCache.Set(ctx, api.KeyAuthId, api) keyOffset := 0 diff --git a/apps/agent/pkg/cache/cache.go b/apps/agent/pkg/cache/cache.go index 3128484a4f..b06e173a65 100644 --- a/apps/agent/pkg/cache/cache.go +++ b/apps/agent/pkg/cache/cache.go @@ -7,8 +7,8 @@ import ( "sync" "time" + "github.com/unkeyed/unkey/apps/agent/pkg/logging" "github.com/unkeyed/unkey/apps/agent/pkg/metrics" - "go.uber.org/zap" ) type swrEntry[T any] struct { @@ -31,7 +31,7 @@ type cache[T any] struct { // If a key is stale, its identifier will be put into this channel and a goroutine refreshes it in the background refreshC chan string - logger *zap.Logger + logger logging.Logger maxSize int lru *list.List metrics metrics.Metrics @@ -50,7 +50,7 @@ type Config[T any] struct { // A handler that will be called to refetch data from the origin when necessary RefreshFromOrigin func(ctx context.Context, identifier string) (entry T, ok bool) - Logger *zap.Logger + Logger logging.Logger // Start evicting the least recently used entry when the cache grows to MaxSize MaxSize int @@ -67,7 +67,7 @@ func New[T any](config Config[T]) Cache[T] { stale: config.Stale, refreshFromOrigin: config.RefreshFromOrigin, refreshC: make(chan string), - logger: config.Logger.With(zap.String("pkg", "cache")), + logger: config.Logger.With().Str("pkg", "cache").Logger(), maxSize: config.MaxSize, lru: list.New(), metrics: config.Metrics, @@ -98,11 +98,8 @@ func (c *cache[T]) runReporting() { }) if size != c.lru.Len() { - c.logger.Error( - "cache skew detected", - zap.Int("cacheSize", size), - zap.Int("lruSize", c.lru.Len()), - ) + c.logger.Error().Int("cacheSize", size).Int("lruSize", c.lru.Len()).Msg("cache skew detected") + } c.RUnlock() } @@ -114,7 +111,7 @@ func (c *cache[T]) runEviction() { c.Lock() for key, val := range c.data { if now.After(val.Stale) { - c.logger.Info("evicting from cache", zap.Time("stale", val.Stale), zap.Time("now", now), zap.String("key", key)) + c.logger.Info().Time("stale", val.Stale).Time("now", now).Str("key", key).Msg("evicting from cache") c.lru.Remove(val.LruElement) delete(c.data, key) } @@ -131,7 +128,7 @@ func (c *cache[T]) runRefreshing() { ctx := context.Background() t, ok := c.refreshFromOrigin(ctx, identifier) if !ok { - c.logger.Info("origin couldn't find", zap.String("identifier", identifier)) + c.logger.Warn().Str("identifier", identifier).Msg("origin couldn't find") continue } c.Set(ctx, identifier, t) @@ -178,7 +175,7 @@ func (c *cache[T]) Set(ctx context.Context, key string, value T) { if !exists { // If the cache is already full, we evict first if c.maxSize > 0 && len(c.data) >= c.maxSize { - c.logger.Info("evicting from cache", zap.String("key", key)) + c.logger.Info().Str("key", key).Msg("evicting from cache") last := c.lru.Back() c.lru.Remove(last) delete(c.data, last.Value.(string)) diff --git a/apps/agent/pkg/database/decrement_key_remaining.go b/apps/agent/pkg/database/decrement_key_remaining.go index 66241e4836..c3fe5dbff7 100644 --- a/apps/agent/pkg/database/decrement_key_remaining.go +++ b/apps/agent/pkg/database/decrement_key_remaining.go @@ -7,7 +7,6 @@ import ( "fmt" "github.com/unkeyed/unkey/apps/agent/pkg/entities" - "go.uber.org/zap" ) func (db *database) DecrementRemainingKeyUsage(ctx context.Context, keyId string) (entities.Key, error) { @@ -19,7 +18,7 @@ func (db *database) DecrementRemainingKeyUsage(ctx context.Context, keyId string defer func() { err := tx.Rollback() if err != nil && !errors.Is(err, sql.ErrTxDone) { - db.logger.Error("unable to rollback transaction", zap.Error(err)) + db.logger.Err(err).Msg("unable to rollback transaction") } }() q := db.write().WithTx(tx) diff --git a/apps/agent/pkg/database/planetscale.go b/apps/agent/pkg/database/planetscale.go index f2dfac5c8e..2ca1ec2f4a 100644 --- a/apps/agent/pkg/database/planetscale.go +++ b/apps/agent/pkg/database/planetscale.go @@ -6,7 +6,7 @@ import ( _ "github.com/go-sql-driver/mysql" gen "github.com/unkeyed/unkey/apps/agent/gen/database" - "go.uber.org/zap" + "github.com/unkeyed/unkey/apps/agent/pkg/logging" ) type replica struct { @@ -17,7 +17,7 @@ type replica struct { type database struct { writeReplica *replica readReplica *replica - logger *zap.Logger + logger logging.Logger } type Config struct { @@ -25,13 +25,13 @@ type Config struct { ReplicaEu string ReplicaAsia string FlyRegion string - Logger *zap.Logger + Logger logging.Logger } type Middleware func(Database) Database func New(config Config, middlewares ...Middleware) (Database, error) { - logger := config.Logger.With(zap.String("pkg", "database")) + logger := config.Logger.With().Str("pkg", "database").Logger() primary, err := connect(config.PrimaryUs) if err != nil { return nil, fmt.Errorf("unable to connect to primary, %w", err) @@ -39,7 +39,7 @@ func New(config Config, middlewares ...Middleware) (Database, error) { var readDB *sql.DB c := getClosestContinent(config.FlyRegion) if c == continentEu && config.ReplicaEu != "" { - logger.Info("Adding database read replica", zap.String("continent", "europe")) + logger.Info().Str("continent", "europe").Msg("Adding database read replica") readDB, err = connect(config.ReplicaEu) if err != nil { if err != nil { @@ -47,13 +47,13 @@ func New(config Config, middlewares ...Middleware) (Database, error) { } } } else if c == continentAsia && config.ReplicaAsia != "" { - logger.Info("Adding database read replica", zap.String("continent", "asia")) + logger.Info().Str("continent", "asia").Msg("Adding database read replica") readDB, err = connect(config.ReplicaAsia) if err != nil { return nil, fmt.Errorf("unable to connect to asia replica") } } else { - logger.Info("Adding database read replica", zap.String("continent", "us")) + logger.Info().Str("continent", "us").Msg("Adding database read replica") readDB, err = connect(config.PrimaryUs) if err != nil { return nil, fmt.Errorf("unable to connect to us replica") @@ -86,7 +86,7 @@ func (d *database) read() *gen.Queries { if d.readReplica != nil && d.readReplica.query != nil { return d.readReplica.query } - d.logger.Warn("falling back to primary ") + d.logger.Warn().Msg("falling back to primary ") return d.writeReplica.query } diff --git a/apps/agent/pkg/events/kafka/kafka.go b/apps/agent/pkg/events/kafka/kafka.go index 673e51fd82..bd8dc2b1dc 100644 --- a/apps/agent/pkg/events/kafka/kafka.go +++ b/apps/agent/pkg/events/kafka/kafka.go @@ -13,7 +13,7 @@ import ( "github.com/segmentio/kafka-go" "github.com/segmentio/kafka-go/sasl/scram" "github.com/unkeyed/unkey/apps/agent/pkg/events" - "go.uber.org/zap" + "github.com/unkeyed/unkey/apps/agent/pkg/logging" ) const topic = "key.changed" @@ -27,7 +27,7 @@ type Kafka struct { onKeyEvent []func(ctx context.Context, e events.KeyEvent) error stopC chan struct{} - logger *zap.Logger + logger logging.Logger // Events are first written to this channel and then flushed to kafka // This allows much cleaner code for users of this package @@ -42,12 +42,12 @@ type Config struct { Broker string Username string Password string - Logger *zap.Logger + Logger logging.Logger } func New(config Config) (*Kafka, error) { - logger := config.Logger.With(zap.String("pkg", "kafka")) - logger.Info("starting kafka") + logger := config.Logger.With().Str("pkg", "kafka").Logger() + logger.Info().Msg("starting kafka") mechanism, err := scram.Mechanism(scram.SHA256, config.Username, config.Password) if err != nil { return nil, fmt.Errorf("unable to create scram mechanism: %w", err) @@ -96,19 +96,19 @@ func (k *Kafka) EmitKeyEvent(ctx context.Context, e events.KeyEvent) { } func (k *Kafka) Close() error { - k.logger.Info("stopping..") - defer k.logger.Info("stopped") + k.logger.Info().Msg("stopping..") + defer k.logger.Info().Msg("stopped") k.Lock() defer k.Unlock() close(k.stopC) - k.logger.Info("stopping reader") + k.logger.Info().Msg("stopping reader") err := k.keyChangedReader.Close() if err != nil { return err } - k.logger.Info("stopping writer") + k.logger.Info().Msg("stopping writer") err = k.keyChangedWriter.Close() if err != nil { return err @@ -127,13 +127,13 @@ func (k *Kafka) Start() { case e := <-k.keyEventBuffer: value, err := json.Marshal(e) if err != nil { - k.logger.Error("unable to marshal KeyEvent", zap.Error(err), zap.String("type", string(e.Type)), zap.String("keyId", e.Key.Id)) + k.logger.Err(err).Str("type", string(e.Type)).Str("keyId", e.Key.Id).Msg("unable to marshal KeyEvent") continue } err = k.keyChangedWriter.WriteMessages(context.Background(), kafka.Message{Value: value}) if err != nil { - k.logger.Error("unable write messages to kafka", zap.Error(err), zap.String("type", string(e.Type)), zap.String("keyId", e.Key.Id)) + k.logger.Err(err).Str("type", string(e.Type)).Str("keyId", e.Key.Id).Msg("unable write messages to kafka") continue } } @@ -162,18 +162,18 @@ func (k *Kafka) handleNextMessage(ctx context.Context) { return } - k.logger.Error("unable to fetch message", zap.Error(err)) + k.logger.Err(err).Msg("unable to fetch message") return } if len(m.Value) == 0 { - k.logger.Warn("message is empty", zap.String("topic", m.Topic)) + k.logger.Warn().Str("topic", m.Topic).Msg("message is empty") return } e := events.KeyEvent{} err = json.Unmarshal(m.Value, &e) if err != nil { - k.logger.Error("unable to unmarshal message", zap.Error(err), zap.String("value", string(m.Value))) + k.logger.Err(err).Str("value", string(m.Value)).Msg("unable to unmarshal message") return } k.callbackLock.RLock() @@ -181,14 +181,14 @@ func (k *Kafka) handleNextMessage(ctx context.Context) { for _, handler := range k.onKeyEvent { err := handler(ctx, e) if err != nil { - k.logger.Error("unable to handle message", zap.Error(err)) + k.logger.Err(err).Msg("unable to handle message") continue } } err = k.keyChangedReader.CommitMessages(ctx, m) if err != nil { - k.logger.Error("unable to commit message", zap.Error(err)) + k.logger.Err(err).Msg("unable to commit message") return } diff --git a/apps/agent/pkg/logging/logger.go b/apps/agent/pkg/logging/logger.go index f04c4b381b..bdaa63a96c 100644 --- a/apps/agent/pkg/logging/logger.go +++ b/apps/agent/pkg/logging/logger.go @@ -1,55 +1,47 @@ package logging import ( - adapter "github.com/axiomhq/axiom-go/adapters/zap" - "go.uber.org/zap" - "go.uber.org/zap/zapcore" - "log" + "fmt" + "github.com/rs/zerolog" + "github.com/rs/zerolog/log" "os" - "time" + "path/filepath" + "runtime" + "strconv" + "strings" ) -type Logger = *zap.Logger +type Logger = zerolog.Logger -func New() Logger { +const timeFormat = "2006-01-02T15:04:05.000MST" - axiomCore, err := adapter.New(adapter.SetDataset("api")) - if err != nil { +func init() { + _, file, _, _ := runtime.Caller(0) - config := zap.NewDevelopmentConfig() - config.EncoderConfig.EncodeLevel = zapcore.CapitalColorLevelEncoder - logger, zapErr := config.Build() - if zapErr != nil { - log.Fatalf("can't initialize logger: %s", err.Error()) - } - logger.Info("new development logger created") - return logger + dir := file + for i := 0; i < 3; i++ { + dir = filepath.Dir(dir) } - go func() { - for range time.NewTicker(time.Second * 5).C { + prefixPath := fmt.Sprintf("%s/", filepath.ToSlash(dir)) - err = axiomCore.Sync() - if err != nil { - log.Printf("can't sync to axiom: %s\n", err.Error()) - } - } - - }() - - consoleCore := zapcore.NewCore( - zapcore.NewConsoleEncoder(zap.NewDevelopmentEncoderConfig()), - os.Stdout, - zapcore.DebugLevel, - ) - - logger := zap.New(zapcore.NewTee(consoleCore, axiomCore)) + zerolog.CallerMarshalFunc = func(pc uintptr, file string, line int) string { + return fmt.Sprintf("%s:%s", strings.TrimPrefix(file, prefixPath), strconv.Itoa(line)) + } - logger.Info("logging set up with axiom") + zerolog.TimeFieldFormat = timeFormat - return logger + log.Logger = log.Output(zerolog.ConsoleWriter{Out: os.Stdout, TimeFormat: timeFormat}) +} +func New(debug ...bool) Logger { + isDebug := len(debug) > 0 && debug[0] + if isDebug { + return log.Level(zerolog.DebugLevel).With().Timestamp().Caller().Logger() + } else { + return log.Level(zerolog.InfoLevel).With().Timestamp().Caller().Logger() + } } func NewNoopLogger() Logger { - return zap.NewNop() + return zerolog.Nop() } diff --git a/apps/agent/pkg/metrics/axiom.go b/apps/agent/pkg/metrics/axiom.go index d986eca400..86462d16a9 100644 --- a/apps/agent/pkg/metrics/axiom.go +++ b/apps/agent/pkg/metrics/axiom.go @@ -7,7 +7,6 @@ import ( ax "github.com/axiomhq/axiom-go/axiom" "github.com/unkeyed/unkey/apps/agent/pkg/logging" - "go.uber.org/zap" ) type axiom struct { @@ -38,7 +37,7 @@ func New(config Config) (Metrics, error) { go func() { _, err := client.IngestChannel(context.Background(), "metrics", a.eventsC) if err != nil { - config.Logger.Error("unable to ingest to axiom", zap.Error(err)) + config.Logger.Err(err).Msg("unable to ingest to axiom") } }() diff --git a/apps/agent/pkg/metrics/interface.go b/apps/agent/pkg/metrics/interface.go index 3bff7824cc..4ca3a9b803 100644 --- a/apps/agent/pkg/metrics/interface.go +++ b/apps/agent/pkg/metrics/interface.go @@ -34,8 +34,6 @@ type KeyVerificationReport struct { ApiId string `json:"apiId"` KeyAuthId string `json:"keyAuthId"` WorkspaceId string `json:"workspaceId"` - - TraceId string `json:"traceId"` } type CacheHitReport struct { diff --git a/apps/agent/pkg/server/key_update.go b/apps/agent/pkg/server/key_update.go index 0d9f062fff..06352de147 100644 --- a/apps/agent/pkg/server/key_update.go +++ b/apps/agent/pkg/server/key_update.go @@ -9,7 +9,6 @@ import ( "github.com/unkeyed/unkey/apps/agent/pkg/entities" "github.com/unkeyed/unkey/apps/agent/pkg/errors" "github.com/unkeyed/unkey/apps/agent/pkg/events" - "go.uber.org/zap" ) // nullish is a wrapper to allow a value to be optional or null @@ -55,8 +54,6 @@ func (s *Server) updateKey(c *fiber.Ctx) error { return errors.NewHttpError(c, errors.BAD_REQUEST, fmt.Sprintf("unable to parse body: %s", err.Error())) } - s.logger.Info("req", zap.Any("req", req)) - err = c.BodyParser(&req) if err != nil { return errors.NewHttpError(c, errors.BAD_REQUEST, fmt.Sprintf("unable to parse body: %s", err.Error())) @@ -67,7 +64,6 @@ func (s *Server) updateKey(c *fiber.Ctx) error { return errors.NewHttpError(c, errors.BAD_REQUEST, fmt.Sprintf("unable to validate body: %s", err.Error())) } - s.logger.Info("updating key", zap.Any("req", req)) if req.Expires.Defined && req.Expires.Value != nil && *req.Expires.Value > 0 && *req.Expires.Value < time.Now().UnixMilli() { return errors.NewHttpError(c, errors.BAD_REQUEST, "'expires' must be in the future, did you pass in a timestamp in seconds instead of milliseconds?") } @@ -90,8 +86,6 @@ func (s *Server) updateKey(c *fiber.Ctx) error { return errors.NewHttpError(c, errors.FORBIDDEN, "access to workspace denied") } - s.logger.Info("found key", zap.Any("key", key)) - if req.Name.Defined { if req.Name.Value != nil { key.Name = *req.Name.Value diff --git a/apps/agent/pkg/server/key_verify.go b/apps/agent/pkg/server/key_verify.go index 76583ab8a1..1539142e8e 100644 --- a/apps/agent/pkg/server/key_verify.go +++ b/apps/agent/pkg/server/key_verify.go @@ -7,9 +7,9 @@ import ( "github.com/gofiber/fiber/v2" "github.com/unkeyed/unkey/apps/agent/pkg/analytics" "github.com/unkeyed/unkey/apps/agent/pkg/errors" + "github.com/unkeyed/unkey/apps/agent/pkg/metrics" "github.com/unkeyed/unkey/apps/agent/pkg/ratelimit" "github.com/unkeyed/unkey/apps/agent/pkg/whitelist" - "go.uber.org/zap" ) type VerifyKeyRequest struct { @@ -110,10 +110,10 @@ func (s *Server) verifyKey(c *fiber.Ctx) error { if len(api.IpWhitelist) > 0 { sourceIp := c.Get("Fly-Client-IP") - s.logger.Info("checking ip whitelist", zap.String("sourceIp", sourceIp), zap.Strings("whitelist", api.IpWhitelist)) + s.logger.Debug().Str("sourceIp", sourceIp).Strs("whitelist", api.IpWhitelist).Msg("checking ip whitelist") if !whitelist.Ip(sourceIp, api.IpWhitelist) { - s.logger.Info("ip denied", zap.String("workspaceId", api.WorkspaceId), zap.String("apiId", api.Id), zap.String("keyId", key.Id), zap.String("sourceIp", sourceIp), zap.Strings("whitelist", api.IpWhitelist)) + s.logger.Info().Str("workspaceId", api.WorkspaceId).Str("apiId", api.Id).Str("keyId", key.Id).Str("sourceIp", sourceIp).Strs("whitelist", api.IpWhitelist).Msg("ip denied") return c.JSON(VerifyKeyResponse{ Valid: false, Code: errors.FORBIDDEN, @@ -125,14 +125,15 @@ func (s *Server) verifyKey(c *fiber.Ctx) error { // --------------------------------------------------------------------------------------------- // Start validation // --------------------------------------------------------------------------------------------- - logger := s.logger.With( - zap.String("keyId", key.Id), - zap.String("apiId", api.Id), - zap.String("keyAuthId", key.KeyAuthId), - zap.String("workspaceId", key.WorkspaceId), - ) - - logger.Info("report.key.verifying") + + if s.metrics != nil { + s.metrics.ReportKeyVerification(metrics.KeyVerificationReport{ + WorkspaceId: key.WorkspaceId, + ApiId: api.Id, + KeyId: key.Id, + KeyAuthId: key.KeyAuthId, + }) + } res := VerifyKeyResponse{ Valid: true, diff --git a/apps/agent/pkg/server/key_verify_test.go b/apps/agent/pkg/server/key_verify_test.go index aba88ff67f..e7209e41df 100644 --- a/apps/agent/pkg/server/key_verify_test.go +++ b/apps/agent/pkg/server/key_verify_test.go @@ -455,7 +455,7 @@ func TestVerifyKey_WithRemaining(t *testing.T) { require.NoError(t, err) srv := New(Config{ - Logger: logging.NewNoopLogger(), + Logger: logging.New(), KeyCache: cache.NewNoopCache[entities.Key](), ApiCache: cache.NewNoopCache[entities.Api](), Database: resources.Database, diff --git a/apps/agent/pkg/server/server.go b/apps/agent/pkg/server/server.go index acc85d54a6..0b2b8cbd64 100644 --- a/apps/agent/pkg/server/server.go +++ b/apps/agent/pkg/server/server.go @@ -9,7 +9,6 @@ import ( "time" "github.com/gofiber/fiber/v2/middleware/recover" - "go.uber.org/zap" "github.com/gofiber/fiber/v2" @@ -20,6 +19,7 @@ import ( "github.com/unkeyed/unkey/apps/agent/pkg/entities" "github.com/unkeyed/unkey/apps/agent/pkg/events" "github.com/unkeyed/unkey/apps/agent/pkg/logging" + "github.com/unkeyed/unkey/apps/agent/pkg/metrics" "github.com/unkeyed/unkey/apps/agent/pkg/ratelimit" "github.com/unkeyed/unkey/apps/agent/pkg/services/workspaces" "go.opentelemetry.io/otel/attribute" @@ -44,6 +44,7 @@ type Config struct { EventBus events.EventBus Version string WorkspaceService workspaces.WorkspaceService + Metrics metrics.Metrics } type Server struct { @@ -65,6 +66,7 @@ type Server struct { unkeyApiId string unkeyKeyAuthId string region string + metrics metrics.Metrics // Used for communication with other pods // Not guaranteed to be available, always do a nil check first! @@ -99,6 +101,7 @@ func New(config Config) *Server { region: config.Region, version: config.Version, workspaceService: config.WorkspaceService, + metrics: config.Metrics, } if s.events == nil { s.events = events.NewNoop() @@ -110,7 +113,7 @@ func New(config Config) *Server { s.app.Use(recover.New(recover.Config{EnableStackTrace: true, StackTraceHandler: func(c *fiber.Ctx, err interface{}) { buf := make([]byte, 2048) buf = buf[:runtime.Stack(buf, false)] - config.Logger.Error("recovered from panic", zap.Any("err", err), zap.ByteString("stacktrace", buf)) + config.Logger.Error().Any("err", err).Bytes("stacktrace", buf).Msg("recovered from panic") }})) s.app.Use(func(c *fiber.Ctx) error { @@ -137,23 +140,38 @@ func New(config Config) *Server { err := c.Next() latency := time.Since(start) - log := config.Logger.With( - zap.String("method", c.Route().Method), - zap.Int("status", c.Response().StatusCode()), - zap.String("path", c.Path()), - zap.Error(err), - zap.Int64("serviceLatency", latency.Milliseconds()), - zap.String("edgeRegion", edgeRegion), - zap.String("traceId", traceId), - ) + error := "" + if err != nil { + error = err.Error() + } + if s.metrics != nil { + s.metrics.ReportHttpRequest(metrics.HttpRequestReport{ + Method: c.Route().Method, + Status: c.Response().StatusCode(), + Path: c.Path(), + EdgeRegion: edgeRegion, + TraceId: traceId, + ServiceLatency: latency.Milliseconds(), + Error: error, + }) + } + + log := config.Logger.With(). + Str("body", string(c.Response().Body())). + Str("method", c.Route().Method). + Int("status", c.Response().StatusCode()). + Str("path", c.Path()). + Int64("serviceLatency", latency.Milliseconds()). + Str("edgeRegion", edgeRegion). + Str("traceId", traceId). + Logger() if c.Response().StatusCode() >= 500 || (err != nil && !errors.Is(err, fiber.ErrMethodNotAllowed)) { - log.Error("request failed", zap.String("body", string(c.Response().Body())), zap.Error(err)) + log.Err(err).Msg("request failed") span.RecordError(err) } else { - log.Info("request completed") + log.Debug().Msg("request completed") } - return err }) @@ -180,7 +198,7 @@ func New(config Config) *Server { } func (s *Server) Start(addr string) error { - s.logger.Info("listening", zap.String("addr", addr)) + s.logger.Info().Str("addr", addr).Msg("listening") err := s.app.Listen(addr) if err != nil && !errors.Is(err, http.ErrServerClosed) { return fmt.Errorf("api server error: %s", err.Error()) @@ -191,7 +209,7 @@ func (s *Server) Start(addr string) error { func (s *Server) Close() error { ctx, cancel := context.WithTimeout(context.Background(), time.Second*15) defer cancel() - s.logger.Info("stopping..") - defer s.logger.Info("stopped") + s.logger.Info().Msg("stopping..") + defer s.logger.Info().Msg("stopped") return s.app.Server().ShutdownWithContext(ctx) } diff --git a/apps/agent/pkg/server/workspace_create.go b/apps/agent/pkg/server/workspace_create.go index a2b45a4993..6e7057b7b3 100644 --- a/apps/agent/pkg/server/workspace_create.go +++ b/apps/agent/pkg/server/workspace_create.go @@ -8,7 +8,6 @@ import ( "github.com/unkeyed/unkey/apps/agent/pkg/entities" httpErrors "github.com/unkeyed/unkey/apps/agent/pkg/errors" "github.com/unkeyed/unkey/apps/agent/pkg/services/workspaces" - "go.uber.org/zap" ) type CreateWorkspaceRequest struct { @@ -40,7 +39,6 @@ func (s *Server) createWorkspace(c *fiber.Ctx) error { return httpErrors.NewHttpError(c, httpErrors.UNAUTHORIZED, err.Error()) } - s.logger.Info("req", zap.Any("req", req), zap.Any("ws", s.workspaceService)) ws, err := s.workspaceService.CreateWorkspace(ctx, workspaces.CreateWorkspaceRequest{ Name: req.Name, TenantId: req.TenantId, diff --git a/apps/agent/pkg/services/workspaces/middleware_logging.go b/apps/agent/pkg/services/workspaces/middleware_logging.go index d4436dcc46..1d625ce4fb 100644 --- a/apps/agent/pkg/services/workspaces/middleware_logging.go +++ b/apps/agent/pkg/services/workspaces/middleware_logging.go @@ -5,7 +5,6 @@ import ( "time" "github.com/unkeyed/unkey/apps/agent/pkg/logging" - "go.uber.org/zap" ) type loggingMiddleware struct { @@ -26,13 +25,13 @@ func (mw *loggingMiddleware) CreateWorkspace(ctx context.Context, req CreateWork start := time.Now() res, err := mw.next.CreateWorkspace(ctx, req) - mw.logger.Info("mw.CreateWorkspace", zap.String("method", "CreateWorkspace"), zap.Error(err), zap.Int64("latency", time.Since(start).Milliseconds())) + mw.logger.Info().Str("method", "CreateWorkspace").Err(err).Int64("latency", time.Since(start).Milliseconds()).Msg("mw.workspaceService") return res, err } func (mw *loggingMiddleware) ChangePlan(ctx context.Context, req ChangePlanRequest) (ChangePlanResponse, error) { start := time.Now() res, err := mw.next.ChangePlan(ctx, req) - mw.logger.Info("mw.workspaceService", zap.String("method", "ChangePlan"), zap.Error(err), zap.Int64("latency", time.Since(start).Milliseconds())) + mw.logger.Info().Str("method", "ChangePlan").Err(err).Int64("latency", time.Since(start).Milliseconds()).Msg("mw.workspaceService") return res, err } diff --git a/apps/agent/tools/bootstrap/main.go b/apps/agent/tools/bootstrap/main.go index c1eeab4f5e..b81f20722f 100644 --- a/apps/agent/tools/bootstrap/main.go +++ b/apps/agent/tools/bootstrap/main.go @@ -10,29 +10,28 @@ import ( "github.com/unkeyed/unkey/apps/agent/pkg/env" "github.com/unkeyed/unkey/apps/agent/pkg/logging" "github.com/unkeyed/unkey/apps/agent/pkg/uid" - "go.uber.org/zap" ) func main() { ctx := context.Background() logger := logging.New() - e := env.Env{ErrorHandler: func(err error) { logger.Error("unable to load env", zap.Error(err)) }} + e := env.Env{ErrorHandler: func(err error) { logger.Err(err).Msg("unable to load env") }} seedDb, err := sql.Open("mysql", e.String("DATABASE_DSN")) if err != nil { - logger.Fatal("error opening database", zap.Error(err)) + logger.Fatal().Err(err).Msg("error opening database") } schema, err := os.ReadFile("../../pkg/database/schema.sql") if err != nil { - logger.Fatal("error reading schema", zap.Error(err)) + logger.Fatal().Err(err).Msg("error reading schema") } _, err = seedDb.Exec(string(schema)) if err != nil { - logger.Fatal("error pushing schema", zap.Error(err)) + logger.Fatal().Err(err).Msg("error pushing schema") } err = seedDb.Close() if err != nil { - logger.Fatal("uanble to close seed db", zap.Error(err)) + logger.Fatal().Err(err).Msg("uanble to close seed db") } db, err := database.New(database.Config{ @@ -41,7 +40,7 @@ func main() { }) if err != nil { - logger.Fatal("unable to connect to databae", zap.Error(err)) + logger.Fatal().Err(err).Msg("unable to connect to databae") } workspace := entities.Workspace{ @@ -65,16 +64,16 @@ func main() { err = db.InsertWorkspace(ctx, workspace) if err != nil { - logger.Fatal("unable to create workspace", zap.Error(err)) + logger.Fatal().Err(err).Msg("unable to create workspace") } err = db.CreateKeyAuth(ctx, keyAuth) if err != nil { - logger.Fatal("unable to create keyAuth", zap.Error(err)) + logger.Fatal().Err(err).Msg("unable to create keyAuth") } err = db.InsertApi(ctx, api) if err != nil { - logger.Fatal("unable to create api", zap.Error(err)) + logger.Fatal().Err(err).Msg("unable to create api") } } diff --git a/apps/logshipper/fly.toml b/apps/logshipper/fly.toml new file mode 100644 index 0000000000..bf42ec7b97 --- /dev/null +++ b/apps/logshipper/fly.toml @@ -0,0 +1,19 @@ +# fly.toml app configuration file generated for unkey-agent-log-shipper on 2023-09-16T10:15:31+02:00 +# +# See https://fly.io/docs/reference/configuration/ for information about how to use this file. +# + +app = "unkey-agent-log-shipper" +primary_region = "fra" + +[build] + image = "ghcr.io/superfly/fly-log-shipper:latest" + + +[[services]] + http_checks = [] + internal_port = 8686 + +[env] + SUBJECT = "logs.unkey-api-production.>" + QUEUE = "org-logs" \ No newline at end of file diff --git a/apps/web/pages/api/v1/stripe/webhooks.ts b/apps/web/pages/api/v1/stripe/webhooks.ts index a41544916b..cb9bb9b90b 100644 --- a/apps/web/pages/api/v1/stripe/webhooks.ts +++ b/apps/web/pages/api/v1/stripe/webhooks.ts @@ -64,7 +64,8 @@ export default async function webhookHandler(req: NextApiRequest, res: NextApiRe plan: "pro", billingPeriodStart: new Date(sub.current_period_start * 1000), billingPeriodEnd: new Date(sub.current_period_end * 1000), - trialEnds: sub.status === "trialing" && sub.trial_end ? new Date(sub.trial_end * 1000) : null, + trialEnds: + sub.status === "trialing" && sub.trial_end ? new Date(sub.trial_end * 1000) : null, maxActiveKeys: QUOTA.pro.maxActiveKeys, maxVerifications: QUOTA.pro.maxVerifications, }) @@ -130,10 +131,10 @@ export default async function webhookHandler(req: NextApiRequest, res: NextApiRe break; } case "invoice.payment_failed": { - const invoice = event.data.object as Stripe.Invoice + const invoice = event.data.object as Stripe.Invoice; console.log("invoice failed", invoice); - if (!loops){ - break + if (!loops) { + break; } const ws = await db.query.workspaces.findFirst({ where: eq(schema.workspaces.stripeCustomerId, invoice.customer!.toString()), @@ -146,11 +147,10 @@ export default async function webhookHandler(req: NextApiRequest, res: NextApiRe await loops.sendTrialEnds({ email: user.email, name: user.name, - date: invoice.effective_at ? new Date(invoice.effective_at*1000) : new Date(), + date: invoice.effective_at ? new Date(invoice.effective_at * 1000) : new Date(), }); } - break - + break; } default: