diff --git a/automod/consumer/firehose.go b/automod/consumer/firehose.go index f210b3055..91470cc43 100644 --- a/automod/consumer/firehose.go +++ b/automod/consumer/firehose.go @@ -116,7 +116,7 @@ func (fc *FirehoseConsumer) Run(ctx context.Context) error { fc.Logger.Info("hepa scheduler configured", "scheduler", "autoscaling", "initial", scaleSettings.Concurrency, "max", scaleSettings.MaxConcurrency) } - return events.HandleRepoStream(ctx, con, scheduler) + return events.HandleRepoStream(ctx, con, scheduler, fc.Logger) } // NOTE: for now, this function basically never errors, just logs and returns nil. Should think through error processing better. diff --git a/bgs/admin.go b/bgs/admin.go index b2f385cd5..44b07cd8f 100644 --- a/bgs/admin.go +++ b/bgs/admin.go @@ -484,7 +484,7 @@ func (bgs *BGS) handleAdminPostResyncPDS(e echo.Context) error { ctx := context.Background() err := bgs.ResyncPDS(ctx, pds) if err != nil { - log.Errorw("failed to resync PDS", "err", err, "pds", pds.Host) + log.Error("failed to resync PDS", "err", err, "pds", pds.Host) } }() diff --git a/bgs/bgs.go b/bgs/bgs.go index a0e8e7cdb..9daa761fc 100644 --- a/bgs/bgs.go +++ b/bgs/bgs.go @@ -6,10 +6,12 @@ import ( "encoding/json" "errors" "fmt" + "log/slog" "net" "net/http" _ "net/http/pprof" "net/url" + "reflect" "strconv" "strings" "sync" @@ -34,7 +36,6 @@ import ( "github.com/gorilla/websocket" "github.com/ipfs/go-cid" ipld "github.com/ipfs/go-ipld-format" - logging "github.com/ipfs/go-log" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" promclient "github.com/prometheus/client_golang/prometheus" @@ -45,7 +46,6 @@ import ( "gorm.io/gorm" ) -var log = logging.Logger("bgs") var tracer = otel.Tracer("bgs") // serverListenerBootTimeout is how long to wait for the requested server socket @@ -95,6 +95,8 @@ type BGS struct { // nextCrawlers gets forwarded POST /xrpc/com.atproto.sync.requestCrawl nextCrawlers []*url.URL httpClient http.Client + + log *slog.Logger } type PDSResync struct { @@ -166,6 +168,8 @@ func NewBGS(db *gorm.DB, ix *indexer.Indexer, repoman *repomgr.RepoManager, evtm pdsResyncs: make(map[uint]*PDSResync), userCache: uc, + + log: slog.Default().With("system", "bgs"), } ix.CreateExternalUser = bgs.createExternalUser @@ -244,13 +248,13 @@ func (bgs *BGS) StartDebug(listen string) error { act, err := bgs.Index.GetUserOrMissing(ctx, did) if err != nil { w.WriteHeader(500) - log.Errorf("failed to get user: %s", err) + bgs.log.Error("failed to get user", "err", err) return } if err := bgs.Index.Crawler.Crawl(ctx, act); err != nil { w.WriteHeader(500) - log.Errorf("failed to add user to crawler: %s", err) + bgs.log.Error("failed to add user to crawler", "err", err) return } }) @@ -335,7 +339,7 @@ func (bgs *BGS) StartWithListener(listen net.Listener) error { if err2 := ctx.JSON(err.Code, map[string]any{ "error": err.Message, }); err2 != nil { - log.Errorf("Failed to write http error: %s", err2) + bgs.log.Error("Failed to write http error", "err", err2) } default: sendHeader := true @@ -343,7 +347,7 @@ func (bgs *BGS) StartWithListener(listen net.Listener) error { sendHeader = false } - log.Warnf("HANDLER ERROR: (%s) %s", ctx.Path(), err) + bgs.log.Warn("HANDLER ERROR: (%s) %s", ctx.Path(), err) if strings.HasPrefix(ctx.Path(), "/admin/") { ctx.JSON(500, map[string]any{ @@ -436,7 +440,7 @@ type HealthStatus struct { func (bgs *BGS) HandleHealthCheck(c echo.Context) error { if err := bgs.db.Exec("SELECT 1").Error; err != nil { - log.Errorf("healthcheck can't connect to database: %v", err) + bgs.log.Error("healthcheck can't connect to database", "err", err) return c.JSON(500, HealthStatus{Status: "error", Message: "can't connect to database"}) } else { return c.JSON(200, HealthStatus{Status: "ok"}) @@ -603,10 +607,10 @@ func (bgs *BGS) cleanupConsumer(id uint64) { var m = &dto.Metric{} if err := c.EventsSent.Write(m); err != nil { - log.Errorf("failed to get sent counter: %s", err) + bgs.log.Error("failed to get sent counter", "err", err) } - log.Infow("consumer disconnected", + bgs.log.Info("consumer disconnected", "consumer_id", id, "remote_addr", c.RemoteAddr, "user_agent", c.UserAgent, @@ -658,7 +662,7 @@ func (bgs *BGS) EventsHandler(c echo.Context) error { } if err := conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(5*time.Second)); err != nil { - log.Warnf("failed to ping client: %s", err) + bgs.log.Warn("failed to ping client: %s", err) cancel() return } @@ -683,7 +687,7 @@ func (bgs *BGS) EventsHandler(c echo.Context) error { for { _, _, err := conn.ReadMessage() if err != nil { - log.Warnf("failed to read message from client: %s", err) + bgs.log.Warn("failed to read message from client: %s", err) cancel() return } @@ -710,13 +714,13 @@ func (bgs *BGS) EventsHandler(c echo.Context) error { consumerID := bgs.registerConsumer(&consumer) defer bgs.cleanupConsumer(consumerID) - logger := log.With( + logger := bgs.log.With( "consumer_id", consumerID, "remote_addr", consumer.RemoteAddr, "user_agent", consumer.UserAgent, ) - logger.Infow("new consumer", "cursor", since) + logger.Info("new consumer", "cursor", since) for { select { @@ -728,7 +732,7 @@ func (bgs *BGS) EventsHandler(c echo.Context) error { wc, err := conn.NextWriter(websocket.BinaryMessage) if err != nil { - logger.Errorf("failed to get next writer: %s", err) + logger.Error("failed to get next writer", "err", err) return err } @@ -742,7 +746,7 @@ func (bgs *BGS) EventsHandler(c echo.Context) error { } if err := wc.Close(); err != nil { - logger.Warnf("failed to flush-close our event write: %s", err) + logger.Warn("failed to flush-close our event write", "err", err) return nil } @@ -763,14 +767,14 @@ func prometheusHandler() http.Handler { // defensive in case things change under the hood. registry, ok := promclient.DefaultRegisterer.(*promclient.Registry) if !ok { - log.Warnf("failed to export default prometheus registry; some metrics will be unavailable; unexpected type: %T", promclient.DefaultRegisterer) + slog.Warn("failed to export default prometheus registry; some metrics will be unavailable; unexpected type", "type", reflect.TypeOf(promclient.DefaultRegisterer)) } exporter, err := prometheus.NewExporter(prometheus.Options{ Registry: registry, Namespace: "bigsky", }) if err != nil { - log.Errorf("could not create the prometheus stats exporter: %v", err) + slog.Error("could not create the prometheus stats exporter", "err", err, "system", "bgs") } return exporter @@ -885,7 +889,7 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event case env.RepoCommit != nil: repoCommitsReceivedCounter.WithLabelValues(host.Host).Add(1) evt := env.RepoCommit - log.Debugw("bgs got repo append event", "seq", evt.Seq, "pdsHost", host.Host, "repo", evt.Repo) + bgs.log.Debug("bgs got repo append event", "seq", evt.Seq, "pdsHost", host.Host, "repo", evt.Repo) s := time.Now() u, err := bgs.lookupUserByDid(ctx, evt.Repo) @@ -915,19 +919,19 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event if u.GetTakenDown() || ustatus == events.AccountStatusTakendown { span.SetAttributes(attribute.Bool("taken_down_by_relay_admin", u.GetTakenDown())) - log.Debugw("dropping commit event from taken down user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host) + bgs.log.Debug("dropping commit event from taken down user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host) repoCommitsResultCounter.WithLabelValues(host.Host, "tdu").Inc() return nil } if ustatus == events.AccountStatusSuspended { - log.Debugw("dropping commit event from suspended user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host) + bgs.log.Debug("dropping commit event from suspended user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host) repoCommitsResultCounter.WithLabelValues(host.Host, "susu").Inc() return nil } if ustatus == events.AccountStatusDeactivated { - log.Debugw("dropping commit event from deactivated user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host) + bgs.log.Debug("dropping commit event from deactivated user", "did", evt.Repo, "seq", evt.Seq, "pdsHost", host.Host) repoCommitsResultCounter.WithLabelValues(host.Host, "du").Inc() return nil } @@ -938,7 +942,7 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event } if host.ID != u.PDS && u.PDS != 0 { - log.Warnw("received event for repo from different pds than expected", "repo", evt.Repo, "expPds", u.PDS, "gotPds", host.Host) + bgs.log.Warn("received event for repo from different pds than expected", "repo", evt.Repo, "expPds", u.PDS, "gotPds", host.Host) // Flush any cached DID documents for this user bgs.didr.FlushCacheFor(env.RepoCommit.Repo) @@ -1000,19 +1004,19 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event if errors.Is(err, carstore.ErrRepoBaseMismatch) || ipld.IsNotFound(err) { ai, lerr := bgs.Index.LookupUser(ctx, u.ID) if lerr != nil { - log.Warnw("failed handling event, no user", "err", err, "pdsHost", host.Host, "seq", evt.Seq, "repo", u.Did, "prev", stringLink(evt.Prev), "commit", evt.Commit.String()) + bgs.log.Warn("failed handling event, no user", "err", err, "pdsHost", host.Host, "seq", evt.Seq, "repo", u.Did, "prev", stringLink(evt.Prev), "commit", evt.Commit.String()) repoCommitsResultCounter.WithLabelValues(host.Host, "nou4").Inc() return fmt.Errorf("failed to look up user %s (%d) (err case: %s): %w", u.Did, u.ID, err, lerr) } span.SetAttributes(attribute.Bool("catchup_queue", true)) - log.Infow("failed handling event, catchup", "err", err, "pdsHost", host.Host, "seq", evt.Seq, "repo", u.Did, "prev", stringLink(evt.Prev), "commit", evt.Commit.String()) + bgs.log.Info("failed handling event, catchup", "err", err, "pdsHost", host.Host, "seq", evt.Seq, "repo", u.Did, "prev", stringLink(evt.Prev), "commit", evt.Commit.String()) repoCommitsResultCounter.WithLabelValues(host.Host, "catchup2").Inc() return bgs.Index.Crawler.AddToCatchupQueue(ctx, host, ai, evt) } - log.Warnw("failed handling event", "err", err, "pdsHost", host.Host, "seq", evt.Seq, "repo", u.Did, "prev", stringLink(evt.Prev), "commit", evt.Commit.String()) + bgs.log.Warn("failed handling event", "err", err, "pdsHost", host.Host, "seq", evt.Seq, "repo", u.Did, "prev", stringLink(evt.Prev), "commit", evt.Commit.String()) repoCommitsResultCounter.WithLabelValues(host.Host, "err").Inc() return fmt.Errorf("handle user event failed: %w", err) } @@ -1020,7 +1024,7 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event repoCommitsResultCounter.WithLabelValues(host.Host, "ok").Inc() return nil case env.RepoHandle != nil: - log.Infow("bgs got repo handle event", "did", env.RepoHandle.Did, "handle", env.RepoHandle.Handle) + bgs.log.Info("bgs got repo handle event", "did", env.RepoHandle.Did, "handle", env.RepoHandle.Handle) // Flush any cached DID documents for this user bgs.didr.FlushCacheFor(env.RepoHandle.Did) @@ -1031,7 +1035,7 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event } if act.Handle.String != env.RepoHandle.Handle { - log.Warnw("handle update did not update handle to asserted value", "did", env.RepoHandle.Did, "expected", env.RepoHandle.Handle, "actual", act.Handle) + bgs.log.Warn("handle update did not update handle to asserted value", "did", env.RepoHandle.Did, "expected", env.RepoHandle.Handle, "actual", act.Handle) } // TODO: Update the ReposHandle event type to include "verified" or something @@ -1045,13 +1049,13 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event }, }) if err != nil { - log.Errorw("failed to broadcast RepoHandle event", "error", err, "did", env.RepoHandle.Did, "handle", env.RepoHandle.Handle) + bgs.log.Error("failed to broadcast RepoHandle event", "error", err, "did", env.RepoHandle.Did, "handle", env.RepoHandle.Handle) return fmt.Errorf("failed to broadcast RepoHandle event: %w", err) } return nil case env.RepoIdentity != nil: - log.Infow("bgs got identity event", "did", env.RepoIdentity.Did) + bgs.log.Info("bgs got identity event", "did", env.RepoIdentity.Did) // Flush any cached DID documents for this user bgs.didr.FlushCacheFor(env.RepoIdentity.Did) @@ -1071,7 +1075,7 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event }, }) if err != nil { - log.Errorw("failed to broadcast Identity event", "error", err, "did", env.RepoIdentity.Did) + bgs.log.Error("failed to broadcast Identity event", "error", err, "did", env.RepoIdentity.Did) return fmt.Errorf("failed to broadcast Identity event: %w", err) } @@ -1087,7 +1091,7 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event span.SetAttributes(attribute.String("repo_status", *env.RepoAccount.Status)) } - log.Infow("bgs got account event", "did", env.RepoAccount.Did) + bgs.log.Info("bgs got account event", "did", env.RepoAccount.Did) // Flush any cached DID documents for this user bgs.didr.FlushCacheFor(env.RepoAccount.Did) @@ -1101,7 +1105,7 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event // Check if the PDS is still authoritative // if not we don't want to be propagating this account event if ai.PDS != host.ID { - log.Errorw("account event from non-authoritative pds", + bgs.log.Error("account event from non-authoritative pds", "seq", env.RepoAccount.Seq, "did", env.RepoAccount.Did, "event_from", host.Host, @@ -1146,7 +1150,7 @@ func (bgs *BGS) handleFedEvent(ctx context.Context, host *models.PDS, env *event }, }) if err != nil { - log.Errorw("failed to broadcast Account event", "error", err, "did", env.RepoAccount.Did) + bgs.log.Error("failed to broadcast Account event", "error", err, "did", env.RepoAccount.Did) return fmt.Errorf("failed to broadcast Account event: %w", err) } @@ -1194,7 +1198,7 @@ func (bgs *BGS) handleRepoTombstone(ctx context.Context, pds *models.PDS, evt *a // delete data from carstore if err := bgs.repoman.TakeDownRepo(ctx, u.ID); err != nil { // don't let a failure here prevent us from propagating this event - log.Errorf("failed to delete user data from carstore: %s", err) + bgs.log.Error("failed to delete user data from carstore", "err", err) } return bgs.events.AddEvent(ctx, &events.XRPCStreamEvent{ @@ -1209,7 +1213,7 @@ func (s *BGS) createExternalUser(ctx context.Context, did string) (*models.Actor externalUserCreationAttempts.Inc() - log.Debugf("create external user: %s", did) + s.log.Debug("create external user", "did", did) doc, err := s.didr.GetDocument(ctx, did) if err != nil { return nil, fmt.Errorf("could not locate DID document for followed user (%s): %w", did, err) @@ -1232,7 +1236,7 @@ func (s *BGS) createExternalUser(ctx context.Context, did string) (*models.Actor // TODO: the PDS's DID should also be in the service, we could use that to look up? var peering models.PDS if err := s.db.Find(&peering, "host = ?", durl.Host).Error; err != nil { - log.Error("failed to find pds", durl.Host) + s.log.Error("failed to find pds", "host", durl.Host) return nil, err } @@ -1305,7 +1309,7 @@ func (s *BGS) createExternalUser(ctx context.Context, did string) (*models.Actor defer func() { if !successfullyCreated { if err := s.db.Model(&models.PDS{}).Where("id = ?", peering.ID).Update("repo_count", gorm.Expr("repo_count - 1")).Error; err != nil { - log.Errorf("failed to decrement repo count for pds: %s", err) + s.log.Error("failed to decrement repo count for pds", "err", err) } } }() @@ -1319,7 +1323,7 @@ func (s *BGS) createExternalUser(ctx context.Context, did string) (*models.Actor return nil, err } - log.Debugw("creating external user", "did", did, "handle", hurl.Host, "pds", peering.ID) + s.log.Debug("creating external user", "did", did, "handle", hurl.Host, "pds", peering.ID) handle := hurl.Host @@ -1327,12 +1331,12 @@ func (s *BGS) createExternalUser(ctx context.Context, did string) (*models.Actor resdid, err := s.hr.ResolveHandleToDid(ctx, handle) if err != nil { - log.Errorf("failed to resolve users claimed handle (%q) on pds: %s", handle, err) + s.log.Error("failed to resolve users claimed handle on pds", "handle", handle, "err", err) validHandle = false } if resdid != did { - log.Errorf("claimed handle did not match servers response (%s != %s)", resdid, did) + s.log.Error("claimed handle did not match servers response", "resdid", resdid, "did", did) validHandle = false } @@ -1341,7 +1345,7 @@ func (s *BGS) createExternalUser(ctx context.Context, did string) (*models.Actor exu, err := s.Index.LookupUserByDid(ctx, did) if err == nil { - log.Debugw("lost the race to create a new user", "did", did, "handle", handle, "existing_hand", exu.Handle) + s.log.Debug("lost the race to create a new user", "did", did, "handle", handle, "existing_hand", exu.Handle) if exu.PDS != peering.ID { // User is now on a different PDS, update if err := s.db.Model(User{}).Where("id = ?", exu.Uid).Update("pds", peering.ID).Error; err != nil { @@ -1500,7 +1504,7 @@ func (bgs *BGS) UpdateAccountStatus(ctx context.Context, did string, status stri // delete data from carstore if err := bgs.repoman.TakeDownRepo(ctx, u.ID); err != nil { // don't let a failure here prevent us from propagating this event - log.Errorf("failed to delete user data from carstore: %s", err) + bgs.log.Error("failed to delete user data from carstore", "err", err) } } @@ -1607,7 +1611,7 @@ func (bgs *BGS) CompleteResync(resync PDSResync) { func (bgs *BGS) ResyncPDS(ctx context.Context, pds models.PDS) error { ctx, span := tracer.Start(ctx, "ResyncPDS") defer span.End() - log := log.With("pds", pds.Host, "source", "resync_pds") + log := bgs.log.With("pds", pds.Host, "source", "resync_pds") resync, found := bgs.LoadOrStoreResync(pds) if found { return fmt.Errorf("resync already in progress") @@ -1639,18 +1643,18 @@ func (bgs *BGS) ResyncPDS(ctx context.Context, pds models.PDS) error { for { pages++ if pages%10 == 0 { - log.Warnw("fetching PDS page during resync", "pages", pages, "total_repos", len(repos)) + log.Warn("fetching PDS page during resync", "pages", pages, "total_repos", len(repos)) resync.NumRepoPages = pages resync.NumRepos = len(repos) bgs.UpdateResync(resync) } if err := limiter.Wait(ctx); err != nil { - log.Errorw("failed to wait for rate limiter", "error", err) + log.Error("failed to wait for rate limiter", "error", err) return fmt.Errorf("failed to wait for rate limiter: %w", err) } repoList, err := comatproto.SyncListRepos(ctx, &xrpcc, cursor, limit) if err != nil { - log.Errorw("failed to list repos", "error", err) + log.Error("failed to list repos", "error", err) return fmt.Errorf("failed to list repos: %w", err) } @@ -1672,7 +1676,7 @@ func (bgs *BGS) ResyncPDS(ctx context.Context, pds models.PDS) error { repolistDone := time.Now() - log.Warnw("listed all repos, checking roots", "num_repos", len(repos), "took", repolistDone.Sub(start)) + log.Warn("listed all repos, checking roots", "num_repos", len(repos), "took", repolistDone.Sub(start)) resync = bgs.SetResyncStatus(pds.ID, "checking revs") // run loop over repos with some concurrency @@ -1681,41 +1685,41 @@ func (bgs *BGS) ResyncPDS(ctx context.Context, pds models.PDS) error { // Check repo revs against our local copy and enqueue crawls for any that are out of date for i, r := range repos { if err := sem.Acquire(ctx, 1); err != nil { - log.Errorw("failed to acquire semaphore", "error", err) + log.Error("failed to acquire semaphore", "error", err) continue } go func(r comatproto.SyncListRepos_Repo) { defer sem.Release(1) - log := log.With("did", r.Did, "remote_rev", r.Rev) + log := bgs.log.With("did", r.Did, "remote_rev", r.Rev) // Fetches the user if we have it, otherwise automatically enqueues it for crawling ai, err := bgs.Index.GetUserOrMissing(ctx, r.Did) if err != nil { - log.Errorw("failed to get user while resyncing PDS, we can't recrawl it", "error", err) + log.Error("failed to get user while resyncing PDS, we can't recrawl it", "error", err) return } rev, err := bgs.repoman.GetRepoRev(ctx, ai.Uid) if err != nil { - log.Warnw("recrawling because we failed to get the local repo root", "err", err, "uid", ai.Uid) + log.Warn("recrawling because we failed to get the local repo root", "err", err, "uid", ai.Uid) err := bgs.Index.Crawler.Crawl(ctx, ai) if err != nil { - log.Errorw("failed to enqueue crawl for repo during resync", "error", err, "uid", ai.Uid, "did", ai.Did) + log.Error("failed to enqueue crawl for repo during resync", "error", err, "uid", ai.Uid, "did", ai.Did) } return } if rev == "" || rev < r.Rev { - log.Warnw("recrawling because the repo rev from the PDS is newer than our local repo rev", "local_rev", rev) + log.Warn("recrawling because the repo rev from the PDS is newer than our local repo rev", "local_rev", rev) err := bgs.Index.Crawler.Crawl(ctx, ai) if err != nil { - log.Errorw("failed to enqueue crawl for repo during resync", "error", err, "uid", ai.Uid, "did", ai.Did) + log.Error("failed to enqueue crawl for repo during resync", "error", err, "uid", ai.Uid, "did", ai.Did) } return } }(r) if i%100 == 0 { if i%10_000 == 0 { - log.Warnw("checked revs during resync", "num_repos_checked", i, "num_repos_to_crawl", -1, "took", time.Now().Sub(resync.StatusChangedAt)) + log.Warn("checked revs during resync", "num_repos_checked", i, "num_repos_to_crawl", -1, "took", time.Now().Sub(resync.StatusChangedAt)) } resync.NumReposChecked = i bgs.UpdateResync(resync) @@ -1725,7 +1729,7 @@ func (bgs *BGS) ResyncPDS(ctx context.Context, pds models.PDS) error { resync.NumReposChecked = len(repos) bgs.UpdateResync(resync) - log.Warnw("enqueued all crawls, exiting resync", "took", time.Now().Sub(start), "num_repos_to_crawl", -1) + bgs.log.Warn("enqueued all crawls, exiting resync", "took", time.Now().Sub(start), "num_repos_to_crawl", -1) return nil } diff --git a/bgs/compactor.go b/bgs/compactor.go index dd4ec4211..6339d76b0 100644 --- a/bgs/compactor.go +++ b/bgs/compactor.go @@ -210,7 +210,7 @@ func (c *Compactor) Start(bgs *BGS) { } if c.requeueInterval > 0 { go func() { - log.Infow("starting compactor requeue routine", + log.Info("starting compactor requeue routine", "interval", c.requeueInterval, "limit", c.requeueLimit, "shardCount", c.requeueShardCount, @@ -226,7 +226,7 @@ func (c *Compactor) Start(bgs *BGS) { ctx := context.Background() ctx, span := otel.Tracer("compactor").Start(ctx, "RequeueRoutine") if err := c.EnqueueAllRepos(ctx, bgs, c.requeueLimit, c.requeueShardCount, c.requeueFast); err != nil { - log.Errorw("failed to enqueue all repos", "err", err) + log.Error("failed to enqueue all repos", "err", err) } span.End() } @@ -262,7 +262,7 @@ func (c *Compactor) doWork(bgs *BGS, strategy NextStrategy) { time.Sleep(time.Second * 5) continue } - log.Errorw("failed to compact repo", + log.Error("failed to compact repo", "err", err, "uid", state.latestUID, "repo", state.latestDID, @@ -273,7 +273,7 @@ func (c *Compactor) doWork(bgs *BGS, strategy NextStrategy) { // Pause for a bit to avoid spamming failed compactions time.Sleep(time.Millisecond * 100) } else { - log.Infow("compacted repo", + log.Info("compacted repo", "uid", state.latestUID, "repo", state.latestDID, "status", state.status, @@ -352,7 +352,7 @@ func (c *Compactor) compactNext(ctx context.Context, bgs *BGS, strategy NextStra func (c *Compactor) EnqueueRepo(ctx context.Context, user *User, fast bool) { ctx, span := otel.Tracer("compactor").Start(ctx, "EnqueueRepo") defer span.End() - log.Infow("enqueueing compaction for repo", "repo", user.Did, "uid", user.ID, "fast", fast) + log.Info("enqueueing compaction for repo", "repo", user.Did, "uid", user.ID, "fast", fast) c.q.Append(user.ID, fast) } @@ -396,7 +396,7 @@ func (c *Compactor) EnqueueAllRepos(ctx context.Context, bgs *BGS, lim int, shar c.q.Append(r.Usr, fast) } - log.Infow("done enqueueing all repos", "repos_enqueued", len(repos)) + log.Info("done enqueueing all repos", "repos_enqueued", len(repos)) return nil } diff --git a/bgs/fedmgr.go b/bgs/fedmgr.go index d84c5e816..c68759d91 100644 --- a/bgs/fedmgr.go +++ b/bgs/fedmgr.go @@ -4,6 +4,7 @@ import ( "context" "errors" "fmt" + "log/slog" "math/rand" "strings" "sync" @@ -22,6 +23,8 @@ import ( "gorm.io/gorm" ) +var log = slog.Default().With("system", "bgs") + type IndexCallback func(context.Context, *models.PDS, *events.XRPCStreamEvent) error // TODO: rename me @@ -129,7 +132,7 @@ func NewSlurper(db *gorm.DB, cb IndexCallback, opts *SlurperOptions) (*Slurper, var errs []error if errs = s.flushCursors(ctx); len(errs) > 0 { for _, err := range errs { - log.Errorf("failed to flush cursors on shutdown: %s", err) + log.Error("failed to flush cursors on shutdown", "err", err) } } log.Info("done flushing PDS cursors on shutdown") @@ -142,7 +145,7 @@ func NewSlurper(db *gorm.DB, cb IndexCallback, opts *SlurperOptions) (*Slurper, defer span.End() if errs := s.flushCursors(ctx); len(errs) > 0 { for _, err := range errs { - log.Errorf("failed to flush cursors: %s", err) + log.Error("failed to flush cursors", "err", err) } } log.Debug("done flushing PDS cursors") @@ -210,7 +213,7 @@ func (s *Slurper) Shutdown() []error { errs := <-s.shutdownResult if len(errs) > 0 { for _, err := range errs { - log.Errorf("shutdown error: %s", err) + log.Error("shutdown error", "err", err) } } log.Info("slurper shutdown complete") @@ -490,14 +493,14 @@ func (s *Slurper) subscribeWithRedialer(ctx context.Context, host *models.PDS, s url := fmt.Sprintf("%s://%s/xrpc/com.atproto.sync.subscribeRepos?cursor=%d", protocol, host.Host, cursor) con, res, err := d.DialContext(ctx, url, nil) if err != nil { - log.Warnw("dialing failed", "pdsHost", host.Host, "err", err, "backoff", backoff) + log.Warn("dialing failed", "pdsHost", host.Host, "err", err, "backoff", backoff) time.Sleep(sleepForBackoff(backoff)) backoff++ if backoff > 15 { - log.Warnw("pds does not appear to be online, disabling for now", "pdsHost", host.Host) + log.Warn("pds does not appear to be online, disabling for now", "pdsHost", host.Host) if err := s.db.Model(&models.PDS{}).Where("id = ?", host.ID).Update("registered", false).Error; err != nil { - log.Errorf("failed to unregister failing pds: %w", err) + log.Error("failed to unregister failing pds", "err", err) } return @@ -506,15 +509,15 @@ func (s *Slurper) subscribeWithRedialer(ctx context.Context, host *models.PDS, s continue } - log.Info("event subscription response code: ", res.StatusCode) + log.Info("event subscription response", "code", res.StatusCode) curCursor := cursor if err := s.handleConnection(ctx, host, con, &cursor, sub); err != nil { if errors.Is(err, ErrTimeoutShutdown) { - log.Infof("shutting down pds subscription to %s, no activity after %s", host.Host, EventsTimeout) + log.Info("shutting down pds subscription after timeout", "host", host.Host, "time", EventsTimeout) return } - log.Warnf("connection to %q failed: %s", host.Host, err) + log.Warn("connection to failed", "host", host.Host, "err", err) } if cursor > curCursor { @@ -545,11 +548,11 @@ func (s *Slurper) handleConnection(ctx context.Context, host *models.PDS, con *w rsc := &events.RepoStreamCallbacks{ RepoCommit: func(evt *comatproto.SyncSubscribeRepos_Commit) error { - log.Debugw("got remote repo event", "pdsHost", host.Host, "repo", evt.Repo, "seq", evt.Seq) + log.Debug("got remote repo event", "pdsHost", host.Host, "repo", evt.Repo, "seq", evt.Seq) if err := s.cb(context.TODO(), host, &events.XRPCStreamEvent{ RepoCommit: evt, }); err != nil { - log.Errorf("failed handling event from %q (%d): %s", host.Host, evt.Seq, err) + log.Error("failed handling event", "host", host.Host, "seq", evt.Seq, "err", err) } *lastCursor = evt.Seq @@ -560,11 +563,11 @@ func (s *Slurper) handleConnection(ctx context.Context, host *models.PDS, con *w return nil }, RepoHandle: func(evt *comatproto.SyncSubscribeRepos_Handle) error { - log.Infow("got remote handle update event", "pdsHost", host.Host, "did", evt.Did, "handle", evt.Handle) + log.Info("got remote handle update event", "pdsHost", host.Host, "did", evt.Did, "handle", evt.Handle) if err := s.cb(context.TODO(), host, &events.XRPCStreamEvent{ RepoHandle: evt, }); err != nil { - log.Errorf("failed handling event from %q (%d): %s", host.Host, evt.Seq, err) + log.Error("failed handling event", "host", host.Host, "seq", evt.Seq, "err", err) } *lastCursor = evt.Seq @@ -575,11 +578,11 @@ func (s *Slurper) handleConnection(ctx context.Context, host *models.PDS, con *w return nil }, RepoMigrate: func(evt *comatproto.SyncSubscribeRepos_Migrate) error { - log.Infow("got remote repo migrate event", "pdsHost", host.Host, "did", evt.Did, "migrateTo", evt.MigrateTo) + log.Info("got remote repo migrate event", "pdsHost", host.Host, "did", evt.Did, "migrateTo", evt.MigrateTo) if err := s.cb(context.TODO(), host, &events.XRPCStreamEvent{ RepoMigrate: evt, }); err != nil { - log.Errorf("failed handling event from %q (%d): %s", host.Host, evt.Seq, err) + log.Error("failed handling event", "host", host.Host, "seq", evt.Seq, "err", err) } *lastCursor = evt.Seq @@ -590,11 +593,11 @@ func (s *Slurper) handleConnection(ctx context.Context, host *models.PDS, con *w return nil }, RepoTombstone: func(evt *comatproto.SyncSubscribeRepos_Tombstone) error { - log.Infow("got remote repo tombstone event", "pdsHost", host.Host, "did", evt.Did) + log.Info("got remote repo tombstone event", "pdsHost", host.Host, "did", evt.Did) if err := s.cb(context.TODO(), host, &events.XRPCStreamEvent{ RepoTombstone: evt, }); err != nil { - log.Errorf("failed handling event from %q (%d): %s", host.Host, evt.Seq, err) + log.Error("failed handling event", "host", host.Host, "seq", evt.Seq, "err", err) } *lastCursor = evt.Seq @@ -605,15 +608,15 @@ func (s *Slurper) handleConnection(ctx context.Context, host *models.PDS, con *w return nil }, RepoInfo: func(info *comatproto.SyncSubscribeRepos_Info) error { - log.Infow("info event", "name", info.Name, "message", info.Message, "pdsHost", host.Host) + log.Info("info event", "name", info.Name, "message", info.Message, "pdsHost", host.Host) return nil }, RepoIdentity: func(ident *comatproto.SyncSubscribeRepos_Identity) error { - log.Infow("identity event", "did", ident.Did) + log.Info("identity event", "did", ident.Did) if err := s.cb(context.TODO(), host, &events.XRPCStreamEvent{ RepoIdentity: ident, }); err != nil { - log.Errorf("failed handling event from %q (%d): %s", host.Host, ident.Seq, err) + log.Error("failed handling event", "host", host.Host, "seq", ident.Seq, "err", err) } *lastCursor = ident.Seq @@ -624,11 +627,11 @@ func (s *Slurper) handleConnection(ctx context.Context, host *models.PDS, con *w return nil }, RepoAccount: func(acct *comatproto.SyncSubscribeRepos_Account) error { - log.Infow("account event", "did", acct.Did, "status", acct.Status) + log.Info("account event", "did", acct.Did, "status", acct.Status) if err := s.cb(context.TODO(), host, &events.XRPCStreamEvent{ RepoAccount: acct, }); err != nil { - log.Errorf("failed handling event from %q (%d): %s", host.Host, acct.Seq, err) + log.Error("failed handling event", "host", host.Host, "seq", acct.Seq, "err", err) } *lastCursor = acct.Seq @@ -671,7 +674,7 @@ func (s *Slurper) handleConnection(ctx context.Context, host *models.PDS, con *w con.RemoteAddr().String(), instrumentedRSC.EventHandler, ) - return events.HandleRepoStream(ctx, con, pool) + return events.HandleRepoStream(ctx, con, pool, nil) } func (s *Slurper) updateCursor(sub *activeSub, curs int64) error { diff --git a/bgs/handlers.go b/bgs/handlers.go index 4fe55fb1c..0e46f0043 100644 --- a/bgs/handlers.go +++ b/bgs/handlers.go @@ -31,7 +31,7 @@ func (s *BGS) handleComAtprotoSyncGetRecord(ctx context.Context, collection stri if errors.Is(err, gorm.ErrRecordNotFound) { return nil, echo.NewHTTPError(http.StatusNotFound, "user not found") } - log.Errorw("failed to lookup user", "err", err, "did", did) + log.Error("failed to lookup user", "err", err, "did", did) return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to lookup user") } @@ -61,7 +61,7 @@ func (s *BGS) handleComAtprotoSyncGetRecord(ctx context.Context, collection stri if errors.Is(err, mst.ErrNotFound) { return nil, echo.NewHTTPError(http.StatusNotFound, "record not found in repo") } - log.Errorw("failed to get record from repo", "err", err, "did", did, "collection", collection, "rkey", rkey) + log.Error("failed to get record from repo", "err", err, "did", did, "collection", collection, "rkey", rkey) return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to get record from repo") } @@ -89,7 +89,7 @@ func (s *BGS) handleComAtprotoSyncGetRepo(ctx context.Context, did string, since if errors.Is(err, gorm.ErrRecordNotFound) { return nil, echo.NewHTTPError(http.StatusNotFound, "user not found") } - log.Errorw("failed to lookup user", "err", err, "did", did) + log.Error("failed to lookup user", "err", err, "did", did) return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to lookup user") } @@ -117,7 +117,7 @@ func (s *BGS) handleComAtprotoSyncGetRepo(ctx context.Context, did string, since // TODO: stream the response buf := new(bytes.Buffer) if err := s.repoman.ReadRepo(ctx, u.ID, since, buf); err != nil { - log.Errorw("failed to read repo into buffer", "err", err, "did", did) + log.Error("failed to read repo into buffer", "err", err, "did", did) return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to read repo into buffer") } @@ -170,7 +170,7 @@ func (s *BGS) handleComAtprotoSyncRequestCrawl(ctx context.Context, body *comatp return echo.NewHTTPError(http.StatusUnauthorized, "domain is banned") } - log.Warnf("TODO: better host validation for crawl requests") + log.Warn("TODO: better host validation for crawl requests") clientHost := fmt.Sprintf("%s://%s", u.Scheme, host) @@ -191,7 +191,7 @@ func (s *BGS) handleComAtprotoSyncRequestCrawl(ctx context.Context, body *comatp if len(s.nextCrawlers) != 0 { blob, err := json.Marshal(body) if err != nil { - log.Warnw("could not forward requestCrawl, json err", "err", err) + log.Warn("could not forward requestCrawl, json err", "err", err) } else { go func(bodyBlob []byte) { for _, rpu := range s.nextCrawlers { @@ -201,11 +201,11 @@ func (s *BGS) handleComAtprotoSyncRequestCrawl(ctx context.Context, body *comatp response.Body.Close() } if err != nil || response == nil { - log.Warnw("requestCrawl forward failed", "host", rpu, "err", err) + log.Warn("requestCrawl forward failed", "host", rpu, "err", err) } else if response.StatusCode != http.StatusOK { - log.Warnw("requestCrawl forward failed", "host", rpu, "status", response.Status) + log.Warn("requestCrawl forward failed", "host", rpu, "status", response.Status) } else { - log.Infow("requestCrawl forward successful", "host", rpu) + log.Info("requestCrawl forward successful", "host", rpu) } } }(blob) @@ -231,7 +231,7 @@ func (s *BGS) handleComAtprotoSyncListRepos(ctx context.Context, cursor int64, l if err == gorm.ErrRecordNotFound { return &comatprototypes.SyncListRepos_Output{}, nil } - log.Errorw("failed to query users", "err", err) + log.Error("failed to query users", "err", err) return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to query users") } @@ -252,7 +252,7 @@ func (s *BGS) handleComAtprotoSyncListRepos(ctx context.Context, cursor int64, l root, err := s.repoman.GetRepoRoot(ctx, user.ID) if err != nil { - log.Errorw("failed to get repo root", "err", err, "did", user.Did) + log.Error("failed to get repo root", "err", err, "did", user.Did) return nil, echo.NewHTTPError(http.StatusInternalServerError, fmt.Sprintf("failed to get repo root for (%s): %v", user.Did, err.Error())) } @@ -303,13 +303,13 @@ func (s *BGS) handleComAtprotoSyncGetLatestCommit(ctx context.Context, did strin root, err := s.repoman.GetRepoRoot(ctx, u.ID) if err != nil { - log.Errorw("failed to get repo root", "err", err, "did", u.Did) + log.Error("failed to get repo root", "err", err, "did", u.Did) return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to get repo root") } rev, err := s.repoman.GetRepoRev(ctx, u.ID) if err != nil { - log.Errorw("failed to get repo rev", "err", err, "did", u.Did) + log.Error("failed to get repo rev", "err", err, "did", u.Did) return nil, echo.NewHTTPError(http.StatusInternalServerError, "failed to get repo rev") } diff --git a/carstore/bs.go b/carstore/bs.go index 2cf0a5093..4e25b8c4e 100644 --- a/carstore/bs.go +++ b/carstore/bs.go @@ -6,6 +6,7 @@ import ( "context" "fmt" "io" + "log/slog" "os" "path/filepath" "sort" @@ -17,14 +18,13 @@ import ( "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" + "github.com/ipfs/boxo/blockstore" blockformat "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" cbor "github.com/ipfs/go-ipld-cbor" ipld "github.com/ipfs/go-ipld-format" "github.com/ipfs/go-libipfs/blocks" - logging "github.com/ipfs/go-log" car "github.com/ipld/go-car" carutil "github.com/ipld/go-car/util" cbg "github.com/whyrusleeping/cbor-gen" @@ -42,8 +42,6 @@ var blockGetTotalCounterUsrskip = blockGetTotalCounter.WithLabelValues("true", " var blockGetTotalCounterCached = blockGetTotalCounter.WithLabelValues("false", "hit") var blockGetTotalCounterNormal = blockGetTotalCounter.WithLabelValues("false", "miss") -var log = logging.Logger("carstore") - const MaxSliceLength = 2 << 20 const BigShardThreshold = 2 << 20 @@ -67,6 +65,8 @@ type FileCarStore struct { lscLk sync.Mutex lastShardCache map[models.Uid]*CarShard + + log *slog.Logger } func NewCarStore(meta *gorm.DB, roots []string) (CarStore, error) { @@ -92,6 +92,7 @@ func NewCarStore(meta *gorm.DB, roots []string) (CarStore, error) { meta: &CarStoreGormMeta{meta: meta}, rootDirs: roots, lastShardCache: make(map[models.Uid]*CarShard), + log: slog.Default().With("system", "carstore"), }, nil } @@ -883,7 +884,7 @@ func (cs *FileCarStore) deleteShards(ctx context.Context, shs []CarShard) error if !os.IsNotExist(err) { return err } - log.Warnw("shard file we tried to delete did not exist", "shard", sh.ID, "path", sh.Path) + cs.log.Warn("shard file we tried to delete did not exist", "shard", sh.ID, "path", sh.Path) } } @@ -1034,7 +1035,7 @@ func shardSize(sh *CarShard) (int64, error) { st, err := os.Stat(sh.Path) if err != nil { if os.IsNotExist(err) { - log.Warnw("missing shard, return size of zero", "path", sh.Path, "shard", sh.ID) + slog.Warn("missing shard, return size of zero", "path", sh.Path, "shard", sh.ID, "system", "carstore") return 0, nil } return 0, fmt.Errorf("stat %q: %w", sh.Path, err) @@ -1155,7 +1156,7 @@ func (cs *FileCarStore) CompactUserShards(ctx context.Context, user models.Uid, // still around but we're doing that anyways since compaction isn't a // perfect process - log.Debugw("repo has dirty dupes", "count", len(dupes), "uid", user, "staleRefs", len(staleRefs), "blockRefs", len(brefs)) + cs.log.Debug("repo has dirty dupes", "count", len(dupes), "uid", user, "staleRefs", len(staleRefs), "blockRefs", len(brefs)) //return nil, fmt.Errorf("WIP: not currently handling this case") } @@ -1350,7 +1351,7 @@ func (cs *FileCarStore) compactBucket(ctx context.Context, user models.Uid, b *c }); err != nil { // If we ever fail to iterate a shard file because its // corrupted, just log an error and skip the shard - log.Errorw("iterating blocks in shard", "shard", s.ID, "err", err, "uid", user) + cs.log.Error("iterating blocks in shard", "shard", s.ID, "err", err, "uid", user) } } @@ -1368,7 +1369,7 @@ func (cs *FileCarStore) compactBucket(ctx context.Context, user models.Uid, b *c _ = fi.Close() if err2 := os.Remove(fi.Name()); err2 != nil { - log.Errorf("failed to remove shard file (%s) after failed db transaction: %w", fi.Name(), err2) + cs.log.Error("failed to remove shard file after failed db transaction", "path", fi.Name(), "err", err2) } return err diff --git a/carstore/repo_test.go b/carstore/repo_test.go index 8366cab95..aa15f3a7c 100644 --- a/carstore/repo_test.go +++ b/carstore/repo_test.go @@ -15,10 +15,10 @@ import ( appbsky "github.com/bluesky-social/indigo/api/bsky" "github.com/bluesky-social/indigo/repo" "github.com/bluesky-social/indigo/util" + "github.com/ipfs/boxo/blockstore" sqlbs "github.com/ipfs/go-bs-sqlite3" "github.com/ipfs/go-cid" flatfs "github.com/ipfs/go-ds-flatfs" - blockstore "github.com/ipfs/go-ipfs-blockstore" ipld "github.com/ipfs/go-ipld-format" "gorm.io/driver/sqlite" "gorm.io/gorm" diff --git a/cmd/beemo/firehose_consumer.go b/cmd/beemo/firehose_consumer.go index 55f2edc87..4f96026a6 100644 --- a/cmd/beemo/firehose_consumer.go +++ b/cmd/beemo/firehose_consumer.go @@ -57,7 +57,7 @@ func RunFirehoseConsumer(ctx context.Context, logger *slog.Logger, relayHost str ) logger.Info("beemo firehose scheduler configured", "scheduler", "parallel", "workers", parallelism) - return events.HandleRepoStream(ctx, con, scheduler) + return events.HandleRepoStream(ctx, con, scheduler, logger) } // TODO: move this to a "ParsePath" helper in syntax package? diff --git a/cmd/bigsky/main.go b/cmd/bigsky/main.go index aa4bc1f6c..a2d1de1a6 100644 --- a/cmd/bigsky/main.go +++ b/cmd/bigsky/main.go @@ -3,6 +3,7 @@ package main import ( "context" "fmt" + "log/slog" "net/http" _ "net/http/pprof" "net/url" @@ -30,7 +31,6 @@ import ( _ "go.uber.org/automaxprocs" "github.com/carlmjohnson/versioninfo" - logging "github.com/ipfs/go-log" "github.com/urfave/cli/v2" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -42,7 +42,7 @@ import ( "gorm.io/plugin/opentelemetry/tracing" ) -var log = logging.Logger("bigsky") +var log = slog.Default().With("system", "bigsky") func init() { // control log level using, eg, GOLOG_LOG_LEVEL=debug @@ -51,7 +51,8 @@ func init() { func main() { if err := run(os.Args); err != nil { - log.Fatal(err) + slog.Error(err.Error()) + os.Exit(1) } } @@ -228,8 +229,8 @@ func setupOTEL(cctx *cli.Context) error { env = "dev" } if cctx.Bool("jaeger") { - url := "http://localhost:14268/api/traces" - exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(url))) + jaegerUrl := "http://localhost:14268/api/traces" + exp, err := jaeger.New(jaeger.WithCollectorEndpoint(jaeger.WithEndpoint(jaegerUrl))) if err != nil { return err } @@ -255,19 +256,20 @@ func setupOTEL(cctx *cli.Context) error { // At a minimum, you need to set // OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 if ep := cctx.String("otel-exporter-otlp-endpoint"); ep != "" { - log.Infow("setting up trace exporter", "endpoint", ep) + slog.Info("setting up trace exporter", "endpoint", ep) ctx, cancel := context.WithCancel(context.Background()) defer cancel() exp, err := otlptracehttp.New(ctx) if err != nil { - log.Fatalw("failed to create trace exporter", "error", err) + slog.Error("failed to create trace exporter", "error", err) + os.Exit(1) } defer func() { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() if err := exp.Shutdown(ctx); err != nil { - log.Errorw("failed to shutdown trace exporter", "error", err) + slog.Error("failed to shutdown trace exporter", "error", err) } }() @@ -292,6 +294,11 @@ func runBigsky(cctx *cli.Context) error { signals := make(chan os.Signal, 1) signal.Notify(signals, syscall.SIGINT, syscall.SIGTERM) + _, err := cliutil.SetupSlog(cliutil.LogOptions{}) + if err != nil { + return err + } + // start observability/tracing (OTEL and jaeger) if err := setupOTEL(cctx); err != nil { return err @@ -304,14 +311,14 @@ func runBigsky(cctx *cli.Context) error { return err } - log.Infow("setting up main database") + slog.Info("setting up main database") dburl := cctx.String("db-url") db, err := cliutil.SetupDatabase(dburl, cctx.Int("max-metadb-connections")) if err != nil { return err } - log.Infow("setting up carstore database") + slog.Info("setting up carstore database") csdburl := cctx.String("carstore-db-url") csdb, err := cliutil.SetupDatabase(csdburl, cctx.Int("max-carstore-connections")) if err != nil { @@ -378,7 +385,7 @@ func runBigsky(cctx *cli.Context) error { var persister events.EventPersistence if dpd := cctx.String("disk-persister-dir"); dpd != "" { - log.Infow("setting up disk persister") + slog.Info("setting up disk persister") pOpts := events.DefaultDiskPersistOptions() pOpts.Retention = cctx.Duration("event-playback-ttl") @@ -428,7 +435,7 @@ func runBigsky(cctx *cli.Context) error { repoman.SetEventHandler(func(ctx context.Context, evt *repomgr.RepoEvent) { if err := ix.HandleRepoEvent(ctx, evt); err != nil { - log.Errorw("failed to handle repo event", "err", err) + slog.Error("failed to handle repo event", "err", err) } }, false) @@ -452,7 +459,7 @@ func runBigsky(cctx *cli.Context) error { } } - log.Infow("constructing bgs") + slog.Info("constructing bgs") bgsConfig := libbgs.DefaultBGSConfig() bgsConfig.SSL = !cctx.Bool("crawl-insecure-ws") bgsConfig.CompactInterval = cctx.Duration("compact-interval") @@ -469,7 +476,7 @@ func runBigsky(cctx *cli.Context) error { if err != nil { return fmt.Errorf("failed to parse next-crawler url: %w", err) } - log.Infow("configuring relay for requestCrawl", "host", nextCrawlerUrls[i]) + slog.Info("configuring relay for requestCrawl", "host", nextCrawlerUrls[i]) } bgsConfig.NextCrawlers = nextCrawlerUrls } @@ -487,7 +494,8 @@ func runBigsky(cctx *cli.Context) error { // set up metrics endpoint go func() { if err := bgs.StartMetrics(cctx.String("metrics-listen")); err != nil { - log.Fatalf("failed to start metrics endpoint: %s", err) + log.Error("failed to start metrics endpoint", "err", err) + os.Exit(1) } }() @@ -498,22 +506,22 @@ func runBigsky(cctx *cli.Context) error { bgsErr <- err }() - log.Infow("startup complete") + slog.Info("startup complete") select { case <-signals: log.Info("received shutdown signal") errs := bgs.Shutdown() for err := range errs { - log.Errorw("error during BGS shutdown", "err", err) + slog.Error("error during BGS shutdown", "err", err) } case err := <-bgsErr: if err != nil { - log.Errorw("error during BGS startup", "err", err) + slog.Error("error during BGS startup", "err", err) } log.Info("shutting down") errs := bgs.Shutdown() for err := range errs { - log.Errorw("error during BGS shutdown", "err", err) + slog.Error("error during BGS shutdown", "err", err) } } diff --git a/cmd/bigsky/resync_pdses.py b/cmd/bigsky/resync_pdses.py index 710aeb7d9..bdb5cb548 100644 --- a/cmd/bigsky/resync_pdses.py +++ b/cmd/bigsky/resync_pdses.py @@ -4,6 +4,7 @@ # # python3 resync_pdses.py --admin-key hunter2 --url http://myrelay:2470 host_per_line.txt +import csv import json import sys import urllib.parse @@ -49,6 +50,7 @@ def crawlAndSetLimits(self, host, limits): return if limits is None: sys.stderr.write(f"requestCrawl {host} OK\n") + return url = urllib.parse.urljoin(self.rooturl, '/admin/pds/changeLimits') plimits = dict(limits) plimits["host"] = host @@ -58,10 +60,38 @@ def crawlAndSetLimits(self, host, limits): return sys.stderr.write(f"requestCrawl + changeLimits {host} OK\n") + +def fromtext(args, relaySession, fin, limits): + for line in fin: + if not line: + continue + line = line.strip() + if not line: + continue + if line[0] == '#': + continue + host = line + if args.crawl: + relaySession.crawlAndSetLimits(host, limits) + elif args.resync: + relaySession.resync(host) + +def fromcsv(args, relaySession, fin, limits): + reader = csv.DictReader(fin) + for row in reader: + host = row.get('host') or row.get('hostname') + if not host: + raise Exception("no host in: " + repr(list(keys(row)))) + if args.crawl: + relaySession.crawlAndSetLimits(host, limits) + elif args.resync: + relaySession.resync(host) + def main(): import argparse ap = argparse.ArgumentParser() - ap.add_argument('input', default='-', help='host per line text file to read, - for stdin') + ap.add_argument('input', default='-', help='host per line text file to read, - for stdin (default), detects .csv in filename') + ap.add_argument('--csv', action='store_true', default=False, help='treat stdin as csv') ap.add_argument('--admin-key', default=None, help='relay auth bearer token', required=True) ap.add_argument('--url', default=None, help='base url to POST /admin/pds/resync', required=True) ap.add_argument('--resync', default=False, action='store_true', help='resync selected PDSes') @@ -92,24 +122,11 @@ def main(): fin = sys.stdin else: fin = open(args.input, 'rt') - for line in fin: - if not line: - continue - line = line.strip() - if not line: - continue - if line[0] == '#': - continue - host = line - if args.crawl: - relaySession.crawlAndSetLimits(host, limits) - elif args.resync: - relaySession.resync(host) - # response = sess.post(url, params={"host": line}, headers=headers) - # if response.status_code != 200: - # sys.stderr.write(f"{url}?host={line} : ({response.status_code}) ({response.text!r})\n") - # else: - # sys.stderr.write(f"{url}?host={line} : OK\n") + if args.csv or args.input.endswith('.csv'): + fromcsv(args, relaySession, fin, limits) + else: + fromtext(args, relaySession, fin, limits) + if __name__ == '__main__': main() diff --git a/cmd/goat/firehose.go b/cmd/goat/firehose.go index ab305a16e..d106c62ff 100644 --- a/cmd/goat/firehose.go +++ b/cmd/goat/firehose.go @@ -130,7 +130,7 @@ func runFirehose(cctx *cli.Context) error { rsc.EventHandler, ) slog.Info("starting firehose consumer", "relayHost", relayHost) - return events.HandleRepoStream(ctx, con, scheduler) + return events.HandleRepoStream(ctx, con, scheduler, nil) } // TODO: move this to a "ParsePath" helper in syntax package? diff --git a/cmd/gosky/car.go b/cmd/gosky/car.go index 54eb7f50c..288a4640f 100644 --- a/cmd/gosky/car.go +++ b/cmd/gosky/car.go @@ -64,7 +64,7 @@ var carUnpackCmd = &cli.Command{ if topDir == "" { topDir = did.String() } - log.Infof("writing output to: %s", topDir) + log.Info("writing output", "topDir", topDir) commitPath := topDir + "/_commit" os.MkdirAll(filepath.Dir(commitPath), os.ModePerm) @@ -90,7 +90,7 @@ var carUnpackCmd = &cli.Command{ if err != nil { return err } - log.Debugf("processing record: %s", k) + log.Debug("processing record", "rec", k) // TODO: check if path is safe more carefully recPath := topDir + "/" + k diff --git a/cmd/gosky/debug.go b/cmd/gosky/debug.go index 75d231cfc..2037c328c 100644 --- a/cmd/gosky/debug.go +++ b/cmd/gosky/debug.go @@ -106,7 +106,7 @@ var inspectEventCmd = &cli.Command{ } seqScheduler := sequential.NewScheduler("debug-inspect-event", rsc.EventHandler) - err = events.HandleRepoStream(ctx, con, seqScheduler) + err = events.HandleRepoStream(ctx, con, seqScheduler, nil) if err != errFoundIt { return err } @@ -284,7 +284,7 @@ var debugStreamCmd = &cli.Command{ }, } seqScheduler := sequential.NewScheduler("debug-stream", rsc.EventHandler) - err = events.HandleRepoStream(ctx, con, seqScheduler) + err = events.HandleRepoStream(ctx, con, seqScheduler, nil) if err != nil { return err } @@ -390,7 +390,8 @@ var compareStreamsCmd = &cli.Command{ go func(i int, url string) { con, _, err := d.Dial(url, http.Header{}) if err != nil { - log.Fatalf("Dial failure on url%d: %s", i+1, err) + log.Error("Dial failure", "i", i, "url", url, "err", err) + os.Exit(1) } ctx := context.TODO() @@ -405,8 +406,9 @@ var compareStreamsCmd = &cli.Command{ }, } seqScheduler := sequential.NewScheduler(fmt.Sprintf("debug-stream-%d", i+1), rsc.EventHandler) - if err := events.HandleRepoStream(ctx, con, seqScheduler); err != nil { - log.Fatalf("HandleRepoStream failure on url%d: %s", i+1, err) + if err := events.HandleRepoStream(ctx, con, seqScheduler, nil); err != nil { + log.Error("HandleRepoStream failure", "i", i, "url", url, "err", err) + os.Exit(1) } }(i, url) } @@ -876,13 +878,15 @@ var debugCompareReposCmd = &cli.Command{ logger := log.With("host", cctx.String("host-1")) repo1bytes, err := comatproto.SyncGetRepo(ctx, &xrpc1, did.String(), "") if err != nil { - logger.Fatalf("getting repo: %s", err) + logger.Error("getting repo", "err", err) + os.Exit(1) return } rep1, err = repo.ReadRepoFromCar(ctx, bytes.NewReader(repo1bytes)) if err != nil { - logger.Fatalf("reading repo: %s", err) + logger.Error("reading repo", "err", err) + os.Exit(1) return } }() @@ -893,13 +897,15 @@ var debugCompareReposCmd = &cli.Command{ logger := log.With("host", cctx.String("host-2")) repo2bytes, err := comatproto.SyncGetRepo(ctx, &xrpc2, did.String(), "") if err != nil { - logger.Fatalf("getting repo: %s", err) + logger.Error("getting repo", "err", err) + os.Exit(1) return } rep2, err = repo.ReadRepoFromCar(ctx, bytes.NewReader(repo2bytes)) if err != nil { - logger.Fatalf("reading repo: %s", err) + logger.Error("reading repo", "err", err) + os.Exit(1) return } }() diff --git a/cmd/gosky/main.go b/cmd/gosky/main.go index 6a3cfabd4..074b0b999 100644 --- a/cmd/gosky/main.go +++ b/cmd/gosky/main.go @@ -7,6 +7,7 @@ import ( "encoding/json" "fmt" "io" + "log/slog" "net/http" "os" "os/signal" @@ -30,22 +31,21 @@ import ( "github.com/gorilla/websocket" lru "github.com/hashicorp/golang-lru/v2" + "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" "github.com/ipld/go-car" _ "github.com/joho/godotenv/autoload" "github.com/carlmjohnson/versioninfo" - logging "github.com/ipfs/go-log" "github.com/polydawn/refmt/cbor" rejson "github.com/polydawn/refmt/json" "github.com/polydawn/refmt/shared" cli "github.com/urfave/cli/v2" ) -var log = logging.Logger("gosky") +var log = slog.Default().With("system", "gosky") func main() { run(os.Args) @@ -79,6 +79,14 @@ func run(args []string) { EnvVars: []string{"ATP_PLC_HOST"}, }, } + + _, err := cliutil.SetupSlog(cliutil.LogOptions{}) + if err != nil { + fmt.Fprintf(os.Stderr, "logging setup error: %s\n", err.Error()) + os.Exit(1) + return + } + app.Commands = []*cli.Command{ accountCmd, adminCmd, @@ -338,7 +346,7 @@ var readRepoStreamCmd = &cli.Command{ }, } seqScheduler := sequential.NewScheduler(con.RemoteAddr().String(), rsc.EventHandler) - return events.HandleRepoStream(ctx, con, seqScheduler) + return events.HandleRepoStream(ctx, con, seqScheduler, log) }, } diff --git a/cmd/gosky/streamdiff.go b/cmd/gosky/streamdiff.go index 2f8d8b0c2..230bfc1da 100644 --- a/cmd/gosky/streamdiff.go +++ b/cmd/gosky/streamdiff.go @@ -58,9 +58,9 @@ var streamCompareCmd = &cli.Command{ }, } seqScheduler := sequential.NewScheduler("streamA", rsc.EventHandler) - err = events.HandleRepoStream(ctx, cona, seqScheduler) + err = events.HandleRepoStream(ctx, cona, seqScheduler, log) if err != nil { - log.Errorf("stream A failed: %s", err) + log.Error("stream A failed", "err", err) } }() @@ -82,9 +82,9 @@ var streamCompareCmd = &cli.Command{ } seqScheduler := sequential.NewScheduler("streamB", rsc.EventHandler) - err = events.HandleRepoStream(ctx, conb, seqScheduler) + err = events.HandleRepoStream(ctx, conb, seqScheduler, log) if err != nil { - log.Errorf("stream B failed: %s", err) + log.Error("stream B failed", "err", err) } }() diff --git a/cmd/gosky/sync.go b/cmd/gosky/sync.go index 9e88466b0..357131a10 100644 --- a/cmd/gosky/sync.go +++ b/cmd/gosky/sync.go @@ -66,7 +66,7 @@ var syncGetRepoCmd = &cli.Command{ xrpcc.Host = h } - log.Infof("downloading from %s to: %s", xrpcc.Host, carPath) + log.Info("downloading", "from", xrpcc.Host, "to", carPath) repoBytes, err := comatproto.SyncGetRepo(ctx, xrpcc, ident.DID.String(), "") if err != nil { return err diff --git a/cmd/laputa/main.go b/cmd/laputa/main.go index d91edfc62..54da0a429 100644 --- a/cmd/laputa/main.go +++ b/cmd/laputa/main.go @@ -14,7 +14,6 @@ import ( _ "go.uber.org/automaxprocs" "github.com/carlmjohnson/versioninfo" - logging "github.com/ipfs/go-log" "github.com/urfave/cli/v2" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -25,8 +24,6 @@ import ( "gorm.io/plugin/opentelemetry/tracing" ) -var log = logging.Logger("laputa") - func main() { run(os.Args) } diff --git a/cmd/rainbow/main.go b/cmd/rainbow/main.go index fb6642c5c..cbb5a1131 100644 --- a/cmd/rainbow/main.go +++ b/cmd/rainbow/main.go @@ -3,6 +3,7 @@ package main import ( "context" "github.com/bluesky-social/indigo/events" + "log/slog" _ "net/http/pprof" "os" "os/signal" @@ -15,7 +16,6 @@ import ( _ "go.uber.org/automaxprocs" "github.com/carlmjohnson/versioninfo" - logging "github.com/ipfs/go-log" "github.com/urfave/cli/v2" "go.opentelemetry.io/otel" "go.opentelemetry.io/otel/attribute" @@ -25,11 +25,11 @@ import ( semconv "go.opentelemetry.io/otel/semconv/v1.4.0" ) -var log = logging.Logger("rainbow") +var log = slog.Default().With("system", "rainbow") func init() { // control log level using, eg, GOLOG_LOG_LEVEL=debug - logging.SetAllLoggers(logging.LevelDebug) + //logging.SetAllLoggers(logging.LevelDebug) } func main() { @@ -90,10 +90,13 @@ func run(args []string) { }, } + // TODO: slog.SetDefault and set module `var log *slog.Logger` based on flags and env + app.Action = Splitter err := app.Run(os.Args) if err != nil { - log.Fatal(err) + log.Error(err.Error()) + os.Exit(1) } } @@ -108,19 +111,20 @@ func Splitter(cctx *cli.Context) error { // At a minimum, you need to set // OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318 if ep := os.Getenv("OTEL_EXPORTER_OTLP_ENDPOINT"); ep != "" { - log.Infow("setting up trace exporter", "endpoint", ep) + log.Info("setting up trace exporter", "endpoint", ep) ctx, cancel := context.WithCancel(context.Background()) defer cancel() exp, err := otlptracehttp.New(ctx) if err != nil { - log.Fatalw("failed to create trace exporter", "error", err) + log.Error("failed to create trace exporter", "error", err) + os.Exit(1) } defer func() { ctx, cancel := context.WithTimeout(context.Background(), time.Second) defer cancel() if err := exp.Shutdown(ctx); err != nil { - log.Errorw("failed to shutdown trace exporter", "error", err) + log.Error("failed to shutdown trace exporter", "error", err) } }() @@ -142,7 +146,7 @@ func Splitter(cctx *cli.Context) error { var spl *splitter.Splitter var err error if persistPath != "" { - log.Infof("building splitter with storage at: %s", persistPath) + log.Info("building splitter with storage at", "path", persistPath) ppopts := events.PebblePersistOptions{ DbPath: persistPath, PersistDuration: time.Duration(float64(time.Hour) * cctx.Float64("persist-hours")), @@ -164,14 +168,16 @@ func Splitter(cctx *cli.Context) error { spl, err = splitter.NewSplitter(conf) } if err != nil { - log.Fatalw("failed to create splitter", "path", persistPath, "error", err) + log.Error("failed to create splitter", "path", persistPath, "error", err) + os.Exit(1) return err } // set up metrics endpoint go func() { if err := spl.StartMetrics(cctx.String("metrics-listen")); err != nil { - log.Fatalf("failed to start metrics endpoint: %s", err) + log.Error("failed to start metrics endpoint", "err", err) + os.Exit(1) } }() @@ -182,20 +188,20 @@ func Splitter(cctx *cli.Context) error { runErr <- err }() - log.Infow("startup complete") + log.Info("startup complete") select { case <-signals: log.Info("received shutdown signal") if err := spl.Shutdown(); err != nil { - log.Errorw("error during Splitter shutdown", "err", err) + log.Error("error during Splitter shutdown", "err", err) } case err := <-runErr: if err != nil { - log.Errorw("error during Splitter startup", "err", err) + log.Error("error during Splitter startup", "err", err) } log.Info("shutting down") if err := spl.Shutdown(); err != nil { - log.Errorw("error during Splitter shutdown", "err", err) + log.Error("error during Splitter shutdown", "err", err) } } diff --git a/cmd/sonar/main.go b/cmd/sonar/main.go index a867646fe..434d9be00 100644 --- a/cmd/sonar/main.go +++ b/cmd/sonar/main.go @@ -197,7 +197,7 @@ func Sonar(cctx *cli.Context) error { go func() { wg.Add(1) defer wg.Done() - err = events.HandleRepoStream(ctx, c, pool) + err = events.HandleRepoStream(ctx, c, pool, logger) logger.Info("HandleRepoStream returned unexpectedly", "err", err) cancel() }() diff --git a/cmd/stress/main.go b/cmd/stress/main.go index 0aa103e43..73d792fe9 100644 --- a/cmd/stress/main.go +++ b/cmd/stress/main.go @@ -18,21 +18,18 @@ import ( "github.com/bluesky-social/indigo/util/cliutil" "github.com/bluesky-social/indigo/xrpc" + "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" cbor "github.com/ipfs/go-ipld-cbor" _ "github.com/joho/godotenv/autoload" "github.com/carlmjohnson/versioninfo" - logging "github.com/ipfs/go-log" "github.com/ipld/go-car" cli "github.com/urfave/cli/v2" ) -var log = logging.Logger("stress") - func main() { run(os.Args) } diff --git a/events/consumer.go b/events/consumer.go index 5d373f30e..f00cd79c7 100644 --- a/events/consumer.go +++ b/events/consumer.go @@ -4,6 +4,7 @@ import ( "context" "fmt" "io" + "log/slog" "net" "time" @@ -108,7 +109,14 @@ func (sr *instrumentedReader) Read(p []byte) (int, error) { return n, err } -func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) error { +// HandleRepoStream +// con is source of events +// sched gets AddWork for each event +// log may be nil for default logger +func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler, log *slog.Logger) error { + if log == nil { + log = slog.Default().With("system", "events") + } ctx, cancel := context.WithCancel(ctx) defer cancel() defer sched.Shutdown() @@ -124,7 +132,7 @@ func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) select { case <-t.C: if err := con.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(time.Second*10)); err != nil { - log.Warnf("failed to ping: %s", err) + log.Warn("failed to ping", "err", err) } case <-ctx.Done(): con.Close() @@ -145,7 +153,7 @@ func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) con.SetPongHandler(func(_ string) error { if err := con.SetReadDeadline(time.Now().Add(time.Minute)); err != nil { - log.Errorf("failed to set read deadline: %s", err) + log.Error("failed to set read deadline", "err", err) } return nil @@ -194,7 +202,7 @@ func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) } if evt.Seq < lastSeq { - log.Errorf("Got events out of order from stream (seq = %d, prev = %d)", evt.Seq, lastSeq) + log.Error("Got events out of order from stream", "seq", evt.Seq, "prev", lastSeq) } lastSeq = evt.Seq @@ -211,7 +219,7 @@ func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) } if evt.Seq < lastSeq { - log.Errorf("Got events out of order from stream (seq = %d, prev = %d)", evt.Seq, lastSeq) + log.Error("Got events out of order from stream", "seq", evt.Seq, "prev", lastSeq) } lastSeq = evt.Seq @@ -227,7 +235,7 @@ func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) } if evt.Seq < lastSeq { - log.Errorf("Got events out of order from stream (seq = %d, prev = %d)", evt.Seq, lastSeq) + log.Error("Got events out of order from stream", "seq", evt.Seq, "prev", lastSeq) } lastSeq = evt.Seq @@ -243,7 +251,7 @@ func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) } if evt.Seq < lastSeq { - log.Errorf("Got events out of order from stream (seq = %d, prev = %d)", evt.Seq, lastSeq) + log.Error("Got events out of order from stream", "seq", evt.Seq, "prev", lastSeq) } lastSeq = evt.Seq @@ -271,7 +279,7 @@ func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) } if evt.Seq < lastSeq { - log.Errorf("Got events out of order from stream (seq = %d, prev = %d)", evt.Seq, lastSeq) + log.Error("Got events out of order from stream", "seq", evt.Seq, "prev", lastSeq) } lastSeq = evt.Seq @@ -287,7 +295,7 @@ func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) } if evt.Seq < lastSeq { - log.Errorf("Got events out of order from stream (seq = %d, prev = %d)", evt.Seq, lastSeq) + log.Error("Got events out of order from stream", "seq", evt.Seq, "prev", lastSeq) } lastSeq = evt.Seq @@ -303,7 +311,7 @@ func HandleRepoStream(ctx context.Context, con *websocket.Conn, sched Scheduler) } if evt.Seq < lastSeq { - log.Errorf("Got events out of order from stream (seq = %d, prev = %d)", evt.Seq, lastSeq) + log.Error("Got events out of order from stream", "seq", evt.Seq, "prev", lastSeq) } lastSeq = evt.Seq diff --git a/events/dbpersist.go b/events/dbpersist.go index a9d6288f2..ab3b1e466 100644 --- a/events/dbpersist.go +++ b/events/dbpersist.go @@ -131,7 +131,7 @@ func (p *DbPersistence) batchFlusher() { if needsFlush { if err := p.Flush(context.Background()); err != nil { - log.Errorf("failed to flush batch: %s", err) + log.Error("failed to flush batch", "err", err) } } } @@ -323,7 +323,7 @@ func (p *DbPersistence) RecordFromTombstone(ctx context.Context, evt *comatproto func (p *DbPersistence) RecordFromRepoCommit(ctx context.Context, evt *comatproto.SyncSubscribeRepos_Commit) (*RepoEventRecord, error) { // TODO: hack hack hack if len(evt.Ops) > 8192 { - log.Errorf("(VERY BAD) truncating ops field in outgoing event (len = %d)", len(evt.Ops)) + log.Error("(VERY BAD) truncating ops field in outgoing event", "len", len(evt.Ops)) evt.Ops = evt.Ops[:8192] } diff --git a/events/dbpersist_test.go b/events/dbpersist_test.go index 4e7ecdc74..c6c2161af 100644 --- a/events/dbpersist_test.go +++ b/events/dbpersist_test.go @@ -16,15 +16,10 @@ import ( pds "github.com/bluesky-social/indigo/pds/data" "github.com/bluesky-social/indigo/repomgr" "github.com/bluesky-social/indigo/util" - logging "github.com/ipfs/go-log/v2" "gorm.io/driver/sqlite" "gorm.io/gorm" ) -func init() { - logging.SetAllLoggers(logging.LevelDebug) -} - func BenchmarkDBPersist(b *testing.B) { ctx := context.Background() diff --git a/events/diskpersist.go b/events/diskpersist.go index 25eb989af..43778fe45 100644 --- a/events/diskpersist.go +++ b/events/diskpersist.go @@ -312,7 +312,7 @@ func (dp *DiskPersistence) flushRoutine() { dp.lk.Lock() if err := dp.flushLog(ctx); err != nil { // TODO: this happening is quite bad. Need a recovery strategy - log.Errorf("failed to flush disk log: %s", err) + log.Error("failed to flush disk log", "err", err) } dp.lk.Unlock() } @@ -354,7 +354,7 @@ func (dp *DiskPersistence) garbageCollectRoutine() { case <-t.C: if errs := dp.garbageCollect(ctx); len(errs) > 0 { for _, err := range errs { - log.Errorf("garbage collection error: %s", err) + log.Error("garbage collection error", "err", err) } } } @@ -430,7 +430,7 @@ func (dp *DiskPersistence) garbageCollect(ctx context.Context) []error { refsGarbageCollected.WithLabelValues().Add(float64(refsDeleted)) filesGarbageCollected.WithLabelValues().Add(float64(filesDeleted)) - log.Infow("garbage collection complete", + log.Info("garbage collection complete", "filesDeleted", filesDeleted, "refsDeleted", refsDeleted, "oldRefsFound", oldRefsFound, @@ -696,7 +696,7 @@ func (dp *DiskPersistence) readEventsFrom(ctx context.Context, since int64, fn s return nil, err } if since > lastSeq { - log.Errorw("playback cursor is greater than last seq of file checked", + log.Error("playback cursor is greater than last seq of file checked", "since", since, "lastSeq", lastSeq, "filename", fn, @@ -778,7 +778,7 @@ func (dp *DiskPersistence) readEventsFrom(ctx context.Context, since int64, fn s return nil, err } default: - log.Warnw("unrecognized event kind coming from log file", "seq", h.Seq, "kind", h.Kind) + log.Warn("unrecognized event kind coming from log file", "seq", h.Seq, "kind", h.Kind) return nil, fmt.Errorf("halting on unrecognized event kind") } } diff --git a/events/events.go b/events/events.go index 168d6d6dd..5619fc20e 100644 --- a/events/events.go +++ b/events/events.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "log/slog" "sync" "time" @@ -14,12 +15,11 @@ import ( "github.com/bluesky-social/indigo/models" "github.com/prometheus/client_golang/prometheus" - logging "github.com/ipfs/go-log" cbg "github.com/whyrusleeping/cbor-gen" "go.opentelemetry.io/otel" ) -var log = logging.Logger("events") +var log = slog.Default().With("system", "events") type Scheduler interface { AddWork(ctx context.Context, repo string, val *XRPCStreamEvent) error @@ -34,6 +34,8 @@ type EventManager struct { crossoverBufferSize int persister EventPersistence + + log *slog.Logger } func NewEventManager(persister EventPersistence) *EventManager { @@ -41,6 +43,7 @@ func NewEventManager(persister EventPersistence) *EventManager { bufferSize: 16 << 10, crossoverBufferSize: 512, persister: persister, + log: slog.Default().With("system", "events"), } persister.SetEventBroadcaster(em.broadcastEvent) @@ -67,7 +70,7 @@ func (em *EventManager) Shutdown(ctx context.Context) error { func (em *EventManager) broadcastEvent(evt *XRPCStreamEvent) { // the main thing we do is send it out, so MarshalCBOR once if err := evt.Preserialize(); err != nil { - log.Errorf("broadcast serialize failed, %s", err) + em.log.Error("broadcast serialize failed", "err", err) // serialize isn't going to go better later, this event is cursed return } @@ -93,7 +96,7 @@ func (em *EventManager) broadcastEvent(evt *XRPCStreamEvent) { // code s.filter = func(*XRPCStreamEvent) bool { return false } - log.Warnw("dropping slow consumer due to event overflow", "bufferSize", len(s.outgoing), "ident", s.ident) + em.log.Warn("dropping slow consumer due to event overflow", "bufferSize", len(s.outgoing), "ident", s.ident) go func(torem *Subscriber) { torem.lk.Lock() if !torem.cleanedUp { @@ -104,7 +107,7 @@ func (em *EventManager) broadcastEvent(evt *XRPCStreamEvent) { }, }: case <-time.After(time.Second * 5): - log.Warnw("failed to send error frame to backed up consumer", "ident", torem.ident) + em.log.Warn("failed to send error frame to backed up consumer", "ident", torem.ident) } } torem.lk.Unlock() @@ -121,7 +124,7 @@ func (em *EventManager) persistAndSendEvent(ctx context.Context, evt *XRPCStream // accept a uid. The lookup inside the persister is notably expensive (despite // being an lru cache?) if err := em.persister.Persist(ctx, evt); err != nil { - log.Errorf("failed to persist outbound event: %s", err) + em.log.Error("failed to persist outbound event", "err", err) } } @@ -370,9 +373,9 @@ func (em *EventManager) Subscribe(ctx context.Context, ident string, filter func } }); err != nil { if errors.Is(err, ErrPlaybackShutdown) { - log.Warnf("events playback: %s", err) + em.log.Warn("events playback", "err", err) } else { - log.Errorf("events playback: %s", err) + em.log.Error("events playback", "err", err) } // TODO: send an error frame or something? @@ -400,7 +403,7 @@ func (em *EventManager) Subscribe(ctx context.Context, ident string, filter func } }); err != nil { if !errors.Is(err, ErrCaughtUp) { - log.Errorf("events playback: %s", err) + em.log.Error("events playback", "err", err) // TODO: send an error frame or something? close(out) diff --git a/events/pebblepersist.go b/events/pebblepersist.go index 2c1c787e5..ff65387e3 100644 --- a/events/pebblepersist.go +++ b/events/pebblepersist.go @@ -193,7 +193,7 @@ func (pp *PebblePersist) GCThread(ctx context.Context) { case <-ticker.C: err := pp.GarbageCollect(ctx) if err != nil { - log.Errorw("GC err", "err", err) + log.Error("GC err", "err", err) } case <-ctx.Done(): return @@ -239,24 +239,24 @@ func (pp *PebblePersist) GarbageCollect(ctx context.Context) error { sizeBefore, _ := pp.db.EstimateDiskUsage(zeroKey[:], ffffKey[:]) if seq == -1 { // nothing to delete - log.Infow("pebble gc nop", "size", sizeBefore) + log.Info("pebble gc nop", "size", sizeBefore) return nil } var key [16]byte setKeySeqMillis(key[:], seq, lastKeyTime) - log.Infow("pebble gc start", "to", hex.EncodeToString(key[:])) + log.Info("pebble gc start", "to", hex.EncodeToString(key[:])) err = pp.db.DeleteRange(zeroKey[:], key[:], pebble.Sync) if err != nil { return err } sizeAfter, _ := pp.db.EstimateDiskUsage(zeroKey[:], ffffKey[:]) - log.Infow("pebble gc", "before", sizeBefore, "after", sizeAfter) + log.Info("pebble gc", "before", sizeBefore, "after", sizeAfter) start := time.Now() err = pp.db.Compact(zeroKey[:], key[:], true) if err != nil { - log.Warnw("pebble gc compact", "err", err) + log.Warn("pebble gc compact", "err", err) } dt := time.Since(start) - log.Infow("pebble gc compact ok", "dt", dt) + log.Info("pebble gc compact ok", "dt", dt) return nil } diff --git a/events/schedulers/autoscaling/autoscaling.go b/events/schedulers/autoscaling/autoscaling.go index 04f973bd3..f842b8ad0 100644 --- a/events/schedulers/autoscaling/autoscaling.go +++ b/events/schedulers/autoscaling/autoscaling.go @@ -2,17 +2,15 @@ package autoscaling import ( "context" + "log/slog" "sync" "time" "github.com/bluesky-social/indigo/events" "github.com/bluesky-social/indigo/events/schedulers" - logging "github.com/ipfs/go-log" "github.com/prometheus/client_golang/prometheus" ) -var log = logging.Logger("autoscaling-scheduler") - // Scheduler is a scheduler that will scale up and down the number of workers based on the throughput of the workers. type Scheduler struct { concurrency int @@ -40,6 +38,8 @@ type Scheduler struct { autoscaleFrequency time.Duration autoscalerIn chan struct{} autoscalerOut chan struct{} + + log *slog.Logger } type AutoscaleSettings struct { @@ -99,6 +99,8 @@ func NewScheduler(autoscaleSettings AutoscaleSettings, ident string, do func(con autoscaleFrequency: autoscaleSettings.AutoscaleFrequency, autoscalerIn: make(chan struct{}), autoscalerOut: make(chan struct{}), + + log: slog.Default().With("system", "autoscaling-scheduler"), } for i := 0; i < p.concurrency; i++ { @@ -111,28 +113,28 @@ func NewScheduler(autoscaleSettings AutoscaleSettings, ident string, do func(con } func (p *Scheduler) Shutdown() { - log.Debugf("shutting down autoscaling scheduler for %s", p.ident) + p.log.Debug("shutting down autoscaling scheduler", "ident", p.ident) // stop autoscaling p.autoscalerIn <- struct{}{} close(p.autoscalerIn) <-p.autoscalerOut - log.Debug("stopping autoscaling scheduler workers") + p.log.Debug("stopping autoscaling scheduler workers") // stop workers for i := 0; i < p.concurrency; i++ { p.feeder <- &consumerTask{signal: "stop"} } close(p.feeder) - log.Debug("waiting for autoscaling scheduler workers to stop") + p.log.Debug("waiting for autoscaling scheduler workers to stop") p.workerGroup.Wait() - log.Debug("stopping autoscaling scheduler throughput manager") + p.log.Debug("stopping autoscaling scheduler throughput manager") p.throughputManager.Stop() - log.Debug("autoscaling scheduler shutdown complete") + p.log.Debug("autoscaling scheduler shutdown complete") } // Add autoscaling function @@ -197,7 +199,7 @@ func (p *Scheduler) AddWork(ctx context.Context, repo string, val *events.XRPCSt } func (p *Scheduler) worker() { - log.Debugf("starting autoscaling worker for %s", p.ident) + p.log.Debug("starting autoscaling worker", "ident", p.ident) p.workersActive.Inc() p.workerGroup.Add(1) defer p.workerGroup.Done() @@ -205,21 +207,21 @@ func (p *Scheduler) worker() { for work != nil { // Check if the work item contains a signal to stop the worker. if work.signal == "stop" { - log.Debugf("stopping autoscaling worker for %s", p.ident) + p.log.Debug("stopping autoscaling worker", "ident", p.ident) p.workersActive.Dec() return } p.itemsActive.Inc() if err := p.do(context.TODO(), work.val); err != nil { - log.Errorf("event handler failed: %s", err) + p.log.Error("event handler failed", "err", err) } p.itemsProcessed.Inc() p.lk.Lock() rem, ok := p.active[work.repo] if !ok { - log.Errorf("should always have an 'active' entry if a worker is processing a job") + p.log.Error("should always have an 'active' entry if a worker is processing a job") } if len(rem) == 0 { diff --git a/events/schedulers/parallel/parallel.go b/events/schedulers/parallel/parallel.go index 8862c94d6..296f6d8d5 100644 --- a/events/schedulers/parallel/parallel.go +++ b/events/schedulers/parallel/parallel.go @@ -2,17 +2,15 @@ package parallel import ( "context" + "log/slog" "sync" "github.com/bluesky-social/indigo/events" "github.com/bluesky-social/indigo/events/schedulers" - logging "github.com/ipfs/go-log" "github.com/prometheus/client_golang/prometheus" ) -var log = logging.Logger("parallel-scheduler") - // Scheduler is a parallel scheduler that will run work on a fixed number of workers type Scheduler struct { maxConcurrency int @@ -33,6 +31,8 @@ type Scheduler struct { itemsProcessed prometheus.Counter itemsActive prometheus.Counter workesActive prometheus.Gauge + + log *slog.Logger } func NewScheduler(maxC, maxQ int, ident string, do func(context.Context, *events.XRPCStreamEvent) error) *Scheduler { @@ -52,6 +52,8 @@ func NewScheduler(maxC, maxQ int, ident string, do func(context.Context, *events itemsProcessed: schedulers.WorkItemsProcessed.WithLabelValues(ident, "parallel"), itemsActive: schedulers.WorkItemsActive.WithLabelValues(ident, "parallel"), workesActive: schedulers.WorkersActive.WithLabelValues(ident, "parallel"), + + log: slog.Default().With("system", "parallel-scheduler"), } for i := 0; i < maxC; i++ { @@ -64,7 +66,7 @@ func NewScheduler(maxC, maxQ int, ident string, do func(context.Context, *events } func (p *Scheduler) Shutdown() { - log.Infof("shutting down parallel scheduler for %s", p.ident) + p.log.Info("shutting down parallel scheduler", "ident", p.ident) for i := 0; i < p.maxConcurrency; i++ { p.feeder <- &consumerTask{ @@ -78,7 +80,7 @@ func (p *Scheduler) Shutdown() { <-p.out } - log.Info("parallel scheduler shutdown complete") + p.log.Info("parallel scheduler shutdown complete") } type consumerTask struct { @@ -123,14 +125,14 @@ func (p *Scheduler) worker() { p.itemsActive.Inc() if err := p.do(context.TODO(), work.val); err != nil { - log.Errorf("event handler failed: %s", err) + p.log.Error("event handler failed", "err", err) } p.itemsProcessed.Inc() p.lk.Lock() rem, ok := p.active[work.repo] if !ok { - log.Errorf("should always have an 'active' entry if a worker is processing a job") + p.log.Error("should always have an 'active' entry if a worker is processing a job") } if len(rem) == 0 { diff --git a/events/schedulers/sequential/sequential.go b/events/schedulers/sequential/sequential.go index 30de71b35..77d8087e4 100644 --- a/events/schedulers/sequential/sequential.go +++ b/events/schedulers/sequential/sequential.go @@ -2,14 +2,12 @@ package sequential import ( "context" - "github.com/bluesky-social/indigo/events" "github.com/bluesky-social/indigo/events/schedulers" - logging "github.com/ipfs/go-log" "github.com/prometheus/client_golang/prometheus" ) -var log = logging.Logger("sequential-scheduler") +// var log = slog.Default().With("system", "sequential-scheduler") // Scheduler is a sequential scheduler that will run work on a single worker type Scheduler struct { diff --git a/fakedata/accounts.go b/fakedata/accounts.go index 71c35165c..85c978457 100644 --- a/fakedata/accounts.go +++ b/fakedata/accounts.go @@ -72,7 +72,7 @@ func ReadAccountCatalog(path string) (*AccountCatalog, error) { return nil, fmt.Errorf("account index didn't match: %d != %d (%s)", i, u.Index, u.AccountType) } } - log.Infof("loaded account catalog: regular=%d celebrity=%d", len(catalog.Regulars), len(catalog.Celebs)) + log.Info("loaded account catalog", "regular", len(catalog.Regulars), "celebrity", len(catalog.Celebs)) return catalog, nil } diff --git a/fakedata/generators.go b/fakedata/generators.go index 8b13af173..e07d875b6 100644 --- a/fakedata/generators.go +++ b/fakedata/generators.go @@ -7,6 +7,7 @@ import ( "bytes" "context" "fmt" + "log/slog" "math/rand" "time" @@ -16,10 +17,13 @@ import ( "github.com/bluesky-social/indigo/xrpc" "github.com/brianvoe/gofakeit/v6" - logging "github.com/ipfs/go-log" ) -var log = logging.Logger("fakedata") +var log = slog.Default().With("system", "fakedata") + +func SetLogger(logger *slog.Logger) { + log = logger +} func MeasureIterations(name string) func(int) { start := time.Now() @@ -28,7 +32,7 @@ func MeasureIterations(name string) func(int) { return } total := time.Since(start) - log.Infof("%s wall runtime: count=%d total=%s mean=%s", name, count, total, total/time.Duration(count)) + log.Info("wall runtime", "name", name, "count", count, "total", total, "rate", total/time.Duration(count)) } } diff --git a/go.mod b/go.mod index ffc0eaaea..483880f9f 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module github.com/bluesky-social/indigo -go 1.22 +go 1.22.0 + +toolchain go1.22.4 require ( contrib.go.opencensus.io/exporter/prometheus v0.4.2 @@ -17,24 +19,22 @@ require ( github.com/go-redis/cache/v9 v9.0.0 github.com/goccy/go-json v0.10.2 github.com/golang-jwt/jwt v3.2.2+incompatible - github.com/gorilla/websocket v1.5.1 + github.com/gorilla/websocket v1.5.3 github.com/hashicorp/go-retryablehttp v0.7.5 github.com/hashicorp/golang-lru/arc/v2 v2.0.6 github.com/hashicorp/golang-lru/v2 v2.0.7 github.com/icrowley/fake v0.0.0-20221112152111-d7b7e2276db2 + github.com/ipfs/boxo v0.24.3 github.com/ipfs/go-block-format v0.2.0 github.com/ipfs/go-bs-sqlite3 v0.0.0-20221122195556-bfcee1be620d github.com/ipfs/go-cid v0.4.1 github.com/ipfs/go-datastore v0.6.0 github.com/ipfs/go-ds-flatfs v0.5.1 - github.com/ipfs/go-ipfs-blockstore v1.3.1 github.com/ipfs/go-ipld-cbor v0.1.0 github.com/ipfs/go-ipld-format v0.6.0 github.com/ipfs/go-libipfs v0.7.0 - github.com/ipfs/go-log v1.0.5 - github.com/ipfs/go-log/v2 v2.5.1 - github.com/ipld/go-car v0.6.1-0.20230509095817-92d28eb23ba4 - github.com/ipld/go-car/v2 v2.13.1 + github.com/ipld/go-car v0.6.2 + github.com/ipld/go-car/v2 v2.14.2 github.com/jackc/pgx/v5 v5.5.0 github.com/joho/godotenv v1.5.1 github.com/labstack/echo-contrib v0.15.0 @@ -47,8 +47,8 @@ require ( github.com/opensearch-project/opensearch-go/v2 v2.3.0 github.com/orandin/slog-gorm v1.3.2 github.com/polydawn/refmt v0.89.1-0.20221221234430-40501e09de1f - github.com/prometheus/client_golang v1.17.0 - github.com/prometheus/client_model v0.5.0 + github.com/prometheus/client_golang v1.20.5 + github.com/prometheus/client_model v0.6.1 github.com/puzpuzpuz/xsync/v3 v3.0.2 github.com/redis/go-redis/v9 v9.3.0 github.com/rivo/uniseg v0.1.0 @@ -58,20 +58,20 @@ require ( github.com/whyrusleeping/cbor-gen v0.2.1-0.20241030202151-b7a6831be65e github.com/whyrusleeping/go-did v0.0.0-20230824162731-404d1707d5d6 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 - go.opentelemetry.io/otel v1.21.0 + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 + go.opentelemetry.io/otel v1.31.0 go.opentelemetry.io/otel/exporters/jaeger v1.14.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 - go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 - go.opentelemetry.io/otel/sdk v1.21.0 - go.opentelemetry.io/otel/trace v1.21.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 + go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 + go.opentelemetry.io/otel/sdk v1.31.0 + go.opentelemetry.io/otel/trace v1.31.0 go.uber.org/automaxprocs v1.5.3 - golang.org/x/crypto v0.21.0 - golang.org/x/sync v0.7.0 - golang.org/x/text v0.14.0 + golang.org/x/crypto v0.28.0 + golang.org/x/sync v0.8.0 + golang.org/x/text v0.19.0 golang.org/x/time v0.3.0 - golang.org/x/tools v0.15.0 - golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 + golang.org/x/tools v0.26.0 + golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da gorm.io/driver/postgres v1.5.7 gorm.io/driver/sqlite v1.5.5 gorm.io/gorm v1.25.9 @@ -90,42 +90,44 @@ require ( github.com/go-redis/redis v6.15.9+incompatible // indirect github.com/golang/snappy v0.0.4 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect + github.com/ipfs/go-ipfs-blockstore v1.3.1 // indirect + github.com/ipfs/go-log v1.0.5 // indirect + github.com/ipfs/go-log/v2 v2.5.1 // indirect github.com/jackc/puddle/v2 v2.2.1 // indirect - github.com/klauspost/compress v1.17.3 // indirect + github.com/klauspost/compress v1.17.11 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect github.com/labstack/gommon v0.4.1 // indirect - github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 // indirect + github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 // indirect github.com/pkg/errors v0.9.1 // indirect - github.com/rogpeppe/go-internal v1.10.0 // indirect + github.com/rogpeppe/go-internal v1.13.1 // indirect github.com/vmihailenco/go-tinylfu v0.2.2 // indirect github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/whyrusleeping/cbor v0.0.0-20171005072247-63513f603b11 // indirect - go.uber.org/zap v1.26.0 // indirect - golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa // indirect + go.uber.org/zap v1.27.0 // indirect + golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c // indirect ) require ( github.com/alexbrainman/goissue34681 v0.0.0-20191006012335-3fc7a47baff5 // indirect github.com/beorn7/perks v1.0.1 // indirect - github.com/cenkalti/backoff/v4 v4.2.1 // indirect - github.com/cespare/xxhash/v2 v2.2.0 // indirect + github.com/cenkalti/backoff/v4 v4.3.0 // indirect + github.com/cespare/xxhash/v2 v2.3.0 // indirect github.com/corpix/uarand v0.2.0 // indirect github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect github.com/davecgh/go-spew v1.1.1 // indirect - github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 // indirect + github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.6.0 // indirect - github.com/go-logr/logr v1.4.1 // indirect + github.com/go-logr/logr v1.4.2 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/uuid v1.4.0 // indirect - github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 // indirect + github.com/google/uuid v1.6.0 // indirect + github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 github.com/ipfs/bbloom v0.0.4 // indirect github.com/ipfs/go-blockservice v0.5.2 // indirect @@ -143,7 +145,7 @@ require ( github.com/jbenet/goprocess v0.1.4 // indirect github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect - github.com/klauspost/cpuid/v2 v2.2.7 // indirect + github.com/klauspost/cpuid/v2 v2.2.8 // indirect github.com/lestrrat-go/blackmagic v1.0.1 // indirect github.com/lestrrat-go/httpcc v1.0.1 // indirect github.com/lestrrat-go/httprc v1.0.4 // indirect @@ -159,11 +161,11 @@ require ( github.com/multiformats/go-varint v0.0.7 // indirect github.com/opentracing/opentracing-go v1.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - github.com/prometheus/common v0.45.0 // indirect - github.com/prometheus/procfs v0.12.0 // indirect + github.com/prometheus/common v0.60.0 // indirect + github.com/prometheus/procfs v0.15.1 // indirect github.com/prometheus/statsd_exporter v0.25.0 // indirect github.com/russross/blackfriday/v2 v2.1.0 // indirect - github.com/samber/lo v1.38.1 // indirect + github.com/samber/lo v1.47.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/spaolacci/murmur3 v1.1.0 github.com/valyala/bytebufferpool v1.0.0 // indirect @@ -172,18 +174,18 @@ require ( gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect go.opencensus.io v0.24.0 // indirect go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho v0.45.0 - go.opentelemetry.io/otel/metric v1.21.0 // indirect - go.opentelemetry.io/proto/otlp v1.0.0 // indirect + go.opentelemetry.io/otel/metric v1.31.0 // indirect + go.opentelemetry.io/proto/otlp v1.3.1 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.14.0 // indirect - golang.org/x/net v0.23.0 // indirect - golang.org/x/sys v0.22.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/grpc v1.59.0 // indirect - google.golang.org/protobuf v1.33.0 // indirect + golang.org/x/mod v0.21.0 // indirect + golang.org/x/net v0.30.0 // indirect + golang.org/x/sys v0.26.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 // indirect + google.golang.org/grpc v1.67.1 // indirect + google.golang.org/protobuf v1.35.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - lukechampine.com/blake3 v1.2.1 // indirect + lukechampine.com/blake3 v1.3.0 // indirect ) diff --git a/go.sum b/go.sum index b72fdce5b..79836de87 100644 --- a/go.sum +++ b/go.sum @@ -67,8 +67,8 @@ github.com/aws/aws-sdk-go-v2/service/ssooidc v1.14.10/go.mod h1:AFvkxc8xfBe8XA+5 github.com/aws/aws-sdk-go-v2/service/sts v1.19.0/go.mod h1:BgQOMsg8av8jset59jelyPW7NoZcZXLVpDsXunGDrk8= github.com/aws/smithy-go v1.13.5/go.mod h1:Tg+OJXh4MB2R/uN61Ko2f6hTZwB/ZYGOtib8J3gBHzA= github.com/benbjohnson/clock v1.1.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= -github.com/benbjohnson/clock v1.3.0 h1:ip6w0uFQkncKQ979AypyG0ER7mqUSBdKLOgAle/AT8A= -github.com/benbjohnson/clock v1.3.0/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= +github.com/benbjohnson/clock v1.3.5 h1:VvXlSJBzZpA/zum6Sj74hxwYI2DIxRWuNIoXAzHZz5o= +github.com/benbjohnson/clock v1.3.5/go.mod h1:J11/hYXuz8f4ySSvYwY0FKfm+ezbsZBKZxNJlLklBHA= github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q= github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -83,13 +83,14 @@ github.com/bsm/gomega v1.27.10 h1:yeMWxP2pV2fG3FgAODIY8EiRE3dy0aeFYt4l7wh6yKA= github.com/bsm/gomega v1.27.10/go.mod h1:JyEr/xRbxbtgWNi8tIEVPUYZ5Dzef52k01W3YH0H+O0= github.com/carlmjohnson/versioninfo v0.22.5 h1:O00sjOLUAFxYQjlN/bzYTuZiS0y6fWDQjMRvwtKgwwc= github.com/carlmjohnson/versioninfo v0.22.5/go.mod h1:QT9mph3wcVfISUKd0i9sZfVrPviHuSF+cUtLjm2WSf8= -github.com/cenkalti/backoff/v4 v4.2.1 h1:y4OZtCnogmCPw98Zjyt5a6+QwPLGkiQsYW5oUqylYbM= -github.com/cenkalti/backoff/v4 v4.2.1/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= +github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= +github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= -github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= +github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 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= @@ -120,9 +121,12 @@ github.com/cskr/pubsub v1.0.2/go.mod h1:/8MzYXk/NJAz782G8RPkFzXTZVu63VotefPnR9TI github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= 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/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c h1:pFUpOrbxDR6AkioZ1ySsx5yxlDQZ8stG2b88gTPxgJU= +github.com/davidlazar/go-crypto v0.0.0-20200604182044-b73af7476f6c/go.mod h1:6UhI8N9EjYm1c2odKpFpAYeR8dsBeM7PtzQhRgxRr9U= github.com/decred/dcrd/crypto/blake256 v1.0.1/go.mod h1:2OfgNZ5wDpcsFmHmCK5gZTPcCXqlm2ArzUIkw9czNJo= -github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0 h1:8UrgZ3GkP4i/CLijOJx79Yu+etlyjdBU4sfcs2WYQMs= github.com/decred/dcrd/dcrec/secp256k1/v4 v4.2.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0 h1:rpfIENRNNilwHwZeG5+P150SMrnNEcHYvcCuK6dPZSg= +github.com/decred/dcrd/dcrec/secp256k1/v4 v4.3.0/go.mod h1:v57UDF4pDQJcEfFUCRop3lJL149eHGSe9Jvczhzjo/0= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f h1:lO4WD4F/rVNCu3HqELle0jiPLLBs70cWOduZpkS1E78= github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f/go.mod h1:cuUVRXasLTGF7a8hSLbxyZXjz+1KgoB3wDUb6vlszIc= github.com/dustinkirkland/golang-petname v0.0.0-20231002161417-6a283f1aaaf2 h1:S6Dco8FtAhEI/qkg/00H6RdEGC+MCy5GPiQ+xweNRFE= @@ -135,6 +139,10 @@ github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2 github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/flosch/pongo2/v6 v6.0.0 h1:lsGru8IAzHgIAw6H2m4PCyleO58I40ow6apih0WprMU= github.com/flosch/pongo2/v6 v6.0.0/go.mod h1:CuDpFm47R0uGGE7z13/tTlt1Y6zdxvr2RLT5LJhsHEU= +github.com/flynn/noise v1.1.0 h1:KjPQoQCEFdZDiP03phOvGi11+SVVhBG2wOWAorLsstg= +github.com/flynn/noise v1.1.0/go.mod h1:xbMo+0i6+IGbYdJhF31t2eR1BIU0CYc12+BNAKwUTag= +github.com/francoispqt/gojay v1.2.13 h1:d2m3sFjloqoIUQU3TsHBgj6qg/BVGlTBeHDUmyJnXKk= +github.com/francoispqt/gojay v1.2.13/go.mod h1:ehT5mTG4ua4581f1++1WLG0vPdaA9HaiDsoyrBGkyDY= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= @@ -161,8 +169,8 @@ github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.4.1 h1:pKouT5E8xu9zeFC39JXRDukb6JFQPXM5p5I91188VAQ= -github.com/go-logr/logr v1.4.1/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-redis/cache/v9 v9.0.0 h1:0thdtFo0xJi0/WXbRVu8B066z8OvVymXTJGaXrVWnN0= @@ -170,7 +178,10 @@ github.com/go-redis/cache/v9 v9.0.0/go.mod h1:cMwi1N8ASBOufbIvk7cdXe2PbPjK/WMRL9 github.com/go-redis/redis v6.15.9+incompatible h1:K0pv1D7EQUjfyoMql+r/jZqCLizCGKFlFgcHWWmHQjg= github.com/go-redis/redis v6.15.9+incompatible/go.mod h1:NAIEuMOZ/fxfXJIrKDQDz8wamY7mA7PouImQ2Jvg6kA= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= +github.com/go-task/slim-sprig/v3 v3.0.0 h1:sUs3vkvUymDpBKi3qH1YSqBQk9+9D/8M2mN1vB6EwHI= +github.com/go-task/slim-sprig/v3 v3.0.0/go.mod h1:W848ghGpv3Qj3dhTPRyJypKRiqCdHZiAzKg9hl15HA8= github.com/go-yaml/yaml v2.1.0+incompatible/go.mod h1:w2MrLa16VYP0jy6N7M5kHaCkaLENm+P+Tv+MfurjSw0= github.com/goccy/go-json v0.10.2 h1:CrxCmQqYDkv1z7lO7Wbh2HN93uovUHgrECaO5ZrCXAU= github.com/goccy/go-json v0.10.2/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= @@ -209,8 +220,6 @@ github.com/golang/protobuf v1.4.2/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw github.com/golang/protobuf v1.4.3/go.mod h1:oDoupMAO8OvCJWAcko0GGGIgR6R6ocIYbsSw735rRwI= github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM= github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= @@ -242,19 +251,22 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM= github.com/google/pprof v0.0.0-20210407192527-94a9f03dee38/go.mod h1:kpwsk12EmLew5upagYY7GY0pfYCcupk39gWOCRROcvE= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc h1:NGyrhhFhwvRAZg02jnYVg3GBQy0qGBKmFQJwaPmpmxs= +github.com/google/pprof v0.0.0-20241017200806-017d972448fc/go.mod h1:vavhavw2zAxS5dIdcRluK6cSGGPlZynqzFM8NdvU144= github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.4.0 h1:MtMxsa51/r9yyhkyLsVeVt0B+BGQZzpQiTQ4eHZ8bc4= -github.com/google/uuid v1.4.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1 h1:EGx4pi6eqNxGaHF6qqu48+N2wcFQ5qg5FXgOdqsJ5d8= github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gorilla/websocket v1.5.1 h1:gmztn0JnHVt9JZquRuzLw3g4wouNVzKL15iLr/zn/QY= -github.com/gorilla/websocket v1.5.1/go.mod h1:x3kM2JMyaluk02fnUJpQuwD2dCS5NDG2ZHL0uE0tcaY= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1 h1:6UKoz5ujsI55KNpsJH3UwCq3T8kKbZwNZBNPuTTje8U= -github.com/grpc-ecosystem/grpc-gateway/v2 v2.18.1/go.mod h1:YvJ2f6MplWDhfxiUC3KpyTy76kYUZA4W3pTv/wdKQ9Y= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c h1:7lF+Vz0LqiRidnzC1Oq86fpX1q/iEv2KJdrCtttYjT4= +github.com/gopherjs/gopherjs v0.0.0-20190430165422-3e4dfb77656c/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0 h1:asbCHRVmodnJTuQ3qamDwqVOIjwqUPTYmYuemVOx+Ys= +github.com/grpc-ecosystem/grpc-gateway/v2 v2.22.0/go.mod h1:ggCgvZ2r7uOoQjOyu2Y1NhHmEPPzzuhWgcza5M1Ji1I= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= @@ -270,14 +282,16 @@ github.com/hashicorp/golang-lru/arc/v2 v2.0.6/go.mod h1:cfdDIX05DWvYV6/shsxDfa/O github.com/hashicorp/golang-lru/v2 v2.0.7 h1:a+bsQ5rvGLjzHuww6tVxozPZFVghXaHOwFs4luLUK2k= github.com/hashicorp/golang-lru/v2 v2.0.7/go.mod h1:QeFd9opnmA6QUJc5vARoKUSoFhyfM2/ZepoAG6RGpeM= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= -github.com/huin/goupnp v1.0.3 h1:N8No57ls+MnjlB+JPiCVSOyy/ot7MJTqlo7rn+NYSqQ= -github.com/huin/goupnp v1.0.3/go.mod h1:ZxNlw5WqJj6wSsRK5+YfflQGXYfccj5VgQsMNixHM7Y= +github.com/huin/goupnp v1.3.0 h1:UvLUlWDNpoUdYzb2TCn+MuTWtcjXKSza2n6CBdQ0xXc= +github.com/huin/goupnp v1.3.0/go.mod h1:gnGPsThkYa7bFi/KWmEysQRf48l2dvR5bxr2OFckNX8= github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/ianlancetaylor/demangle v0.0.0-20200824232613-28f6c0f3b639/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/icrowley/fake v0.0.0-20221112152111-d7b7e2276db2 h1:qU3v73XG4QAqCPHA4HOpfC1EfUvtLIDvQK4mNQ0LvgI= github.com/icrowley/fake v0.0.0-20221112152111-d7b7e2276db2/go.mod h1:dQ6TM/OGAe+cMws81eTe4Btv1dKxfPZ2CX+YaAFAPN4= github.com/ipfs/bbloom v0.0.4 h1:Gi+8EGJ2y5qiD5FbsbpX/TMNcJw8gSqr7eyjHa4Fhvs= github.com/ipfs/bbloom v0.0.4/go.mod h1:cS9YprKXpoZ9lT0n/Mw/a6/aFV6DTjTLYHeA+gyqMG0= +github.com/ipfs/boxo v0.24.3 h1:gldDPOWdM3Rz0v5LkVLtZu7A7gFNvAlWcmxhCqlHR3c= +github.com/ipfs/boxo v0.24.3/go.mod h1:h0DRzOY1IBFDHp6KNvrJLMFdSXTYID0Zf+q7X05JsNg= github.com/ipfs/go-bitfield v1.1.0 h1:fh7FIo8bSwaJEh6DdTWbCeZ1eqOaOkKFI74SCnsWbGA= github.com/ipfs/go-bitfield v1.1.0/go.mod h1:paqf1wjq/D2BBmzfTVFlJQ9IlFOZpg422HL0HqsGWHU= github.com/ipfs/go-bitswap v0.11.0 h1:j1WVvhDX1yhG32NTC9xfxnqycqYIlhzEzLXG/cU1HyQ= @@ -301,8 +315,6 @@ github.com/ipfs/go-ipfs-blockstore v1.3.1 h1:cEI9ci7V0sRNivqaOr0elDsamxXFxJMMMy7 github.com/ipfs/go-ipfs-blockstore v1.3.1/go.mod h1:KgtZyc9fq+P2xJUiCAzbRdhhqJHvsw8u2Dlqy2MyRTE= github.com/ipfs/go-ipfs-blocksutil v0.0.1 h1:Eh/H4pc1hsvhzsQoMEP3Bke/aW5P5rVM1IWFJMcGIPQ= github.com/ipfs/go-ipfs-blocksutil v0.0.1/go.mod h1:Yq4M86uIOmxmGPUHv/uI7uKqZNtLb449gwKqXjIsnRk= -github.com/ipfs/go-ipfs-chunker v0.0.5 h1:ojCf7HV/m+uS2vhUGWcogIIxiO5ubl5O57Q7NapWLY8= -github.com/ipfs/go-ipfs-chunker v0.0.5/go.mod h1:jhgdF8vxRHycr00k13FM8Y0E+6BoalYeobXmUyTreP8= github.com/ipfs/go-ipfs-delay v0.0.0-20181109222059-70721b86a9a8/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= github.com/ipfs/go-ipfs-delay v0.0.1 h1:r/UXYyRcddO6thwOnhiznIAiSvxMECGgtv35Xs1IeRQ= github.com/ipfs/go-ipfs-delay v0.0.1/go.mod h1:8SP1YXK1M1kXuc4KJZINY3TQQ03J2rwBG9QfXmbRPrw= @@ -339,14 +351,14 @@ github.com/ipfs/go-metrics-interface v0.0.1 h1:j+cpbjYvu4R8zbleSs36gvB7jR+wsL2fG github.com/ipfs/go-metrics-interface v0.0.1/go.mod h1:6s6euYU4zowdslK0GKHmqaIZ3j/b/tL7HTWtJ4VPgWY= github.com/ipfs/go-peertaskqueue v0.8.1 h1:YhxAs1+wxb5jk7RvS0LHdyiILpNmRIRnZVztekOF0pg= github.com/ipfs/go-peertaskqueue v0.8.1/go.mod h1:Oxxd3eaK279FxeydSPPVGHzbwVeHjatZ2GA8XD+KbPU= -github.com/ipfs/go-unixfsnode v1.8.0 h1:yCkakzuE365glu+YkgzZt6p38CSVEBPgngL9ZkfnyQU= -github.com/ipfs/go-unixfsnode v1.8.0/go.mod h1:HxRu9HYHOjK6HUqFBAi++7DVoWAHn0o4v/nZ/VA+0g8= +github.com/ipfs/go-unixfsnode v1.9.2 h1:0A12BYs4XOtDPJTMlwmNPlllDfqcc4yie4e919hcUXk= +github.com/ipfs/go-unixfsnode v1.9.2/go.mod h1:v1nuMFHf4QTIhFUdPMvg1nQu7AqDLvIdwyvJ531Ot1U= github.com/ipfs/go-verifcid v0.0.3 h1:gmRKccqhWDocCRkC+a59g5QW7uJw5bpX9HWBevXa0zs= github.com/ipfs/go-verifcid v0.0.3/go.mod h1:gcCtGniVzelKrbk9ooUSX/pM3xlH73fZZJDzQJRvOUw= -github.com/ipld/go-car v0.6.1-0.20230509095817-92d28eb23ba4 h1:oFo19cBmcP0Cmg3XXbrr0V/c+xU9U1huEZp8+OgBzdI= -github.com/ipld/go-car v0.6.1-0.20230509095817-92d28eb23ba4/go.mod h1:6nkFF8OmR5wLKBzRKi7/YFJpyYR7+oEn1DX+mMWnlLA= -github.com/ipld/go-car/v2 v2.13.1 h1:KnlrKvEPEzr5IZHKTXLAEub+tPrzeAFQVRlSQvuxBO4= -github.com/ipld/go-car/v2 v2.13.1/go.mod h1:QkdjjFNGit2GIkpQ953KBwowuoukoM75nP/JI1iDJdo= +github.com/ipld/go-car v0.6.2 h1:Hlnl3Awgnq8icK+ze3iRghk805lu8YNq3wlREDTF2qc= +github.com/ipld/go-car v0.6.2/go.mod h1:oEGXdwp6bmxJCZ+rARSkDliTeYnVzv3++eXajZ+Bmr8= +github.com/ipld/go-car/v2 v2.14.2 h1:9ERr7KXpCC7If0rChZLhYDlyr6Bes6yRKPJnCO3hdHY= +github.com/ipld/go-car/v2 v2.14.2/go.mod h1:0iPB/825lTZLU2zPK5bVTk/R3V2612E1VI279OGSXWA= github.com/ipld/go-codec-dagpb v1.6.0 h1:9nYazfyu9B1p3NAgfVdpRco3Fs2nFC72DqVsMj6rOcc= github.com/ipld/go-codec-dagpb v1.6.0/go.mod h1:ANzFhfP2uMJxRBr8CE+WQWs5UsNa0pYtmKZ+agnUw9s= github.com/ipld/go-ipld-prime v0.21.0 h1:n4JmcpOlPDIxBcY037SVfpd1G+Sj1nKZah0m6QH9C2E= @@ -364,6 +376,8 @@ github.com/jackc/puddle/v2 v2.2.1/go.mod h1:vriiEXHvEE654aYKXXjOvZM39qJ0q+azkZFr github.com/jackpal/go-nat-pmp v1.0.2 h1:KzKSgb7qkJvOUTqYl9/Hg/me3pWgBmERKrTGD7BdWus= github.com/jackpal/go-nat-pmp v1.0.2/go.mod h1:QPH045xvCAeXUZOxsnwmrtiCoxIr9eob+4orBN1SBKc= github.com/jbenet/go-cienv v0.1.0/go.mod h1:TqNnHUmJgXau0nCzC7kXWeotg3J9W34CUv5Djy1+FlA= +github.com/jbenet/go-temp-err-catcher v0.1.0 h1:zpb3ZH6wIE8Shj2sKS+khgRvf7T7RABoLk/+KKHggpk= +github.com/jbenet/go-temp-err-catcher v0.1.0/go.mod h1:0kJRvmDZXNMIiJirNPEYfhpPwbGVtZVWC34vc5WLsDk= github.com/jbenet/goprocess v0.1.4 h1:DRGOFReOMqqDNXwW70QkacFW0YN9QnwLV0Vqk+3oU0o= github.com/jbenet/goprocess v0.1.4/go.mod h1:5yspPrukOVuOLORacaBi858NqyClJPQxYZlqdZVfqY4= github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= @@ -389,14 +403,14 @@ github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvW github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/klauspost/compress v1.17.3 h1:qkRjuerhUU1EmXLYGkSH6EZL+vPSxIrYjLNAK4slzwA= -github.com/klauspost/compress v1.17.3/go.mod h1:/dCuZOvVtNoHsyb+cuJD3itjs3NbnF6KH9zAO4BDxPM= -github.com/klauspost/cpuid/v2 v2.2.7 h1:ZWSB3igEs+d0qvnxR/ZBzXVmxkgt8DdzP6m9pfuVLDM= -github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= +github.com/klauspost/compress v1.17.11 h1:In6xLpyWOi1+C7tXUUWv2ot1QvBjxevKAaI6IXrJmUc= +github.com/klauspost/compress v1.17.11/go.mod h1:pMDklpSncoRMuLFrf1W9Ss9KT+0rH90U12bZKk7uwG0= +github.com/klauspost/cpuid/v2 v2.2.8 h1:+StwCXwm9PdpiEkPyzBXIy+M9KUb4ODm0Zarf1kS5BM= +github.com/klauspost/cpuid/v2 v2.2.8/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/koron/go-ssdp v0.0.3 h1:JivLMY45N76b4p/vsWGOKewBQu6uf39y8l+AQ7sDKx8= -github.com/koron/go-ssdp v0.0.3/go.mod h1:b2MxI6yh02pKrsyNoQUsk4+YNikaGhe4894J+Q5lDvA= +github.com/koron/go-ssdp v0.0.4 h1:1IDwrghSKYM7yLf7XCzbByg2sJ/JcNOZRXS2jczTwz0= +github.com/koron/go-ssdp v0.0.4/go.mod h1:oDXq+E5IL5q0U8uSBcoAXzTzInwy5lEgC91HoKtbmZk= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= @@ -407,6 +421,8 @@ github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/labstack/echo-contrib v0.15.0 h1:9K+oRU265y4Mu9zpRDv3X+DGTqUALY6oRHCSZZKCRVU= github.com/labstack/echo-contrib v0.15.0/go.mod h1:lei+qt5CLB4oa7VHTE0yEfQSEB9XTJI1LUqko9UWvo4= github.com/labstack/echo/v4 v4.11.3 h1:Upyu3olaqSHkCjs1EJJwQ3WId8b8b1hxbogyommKktM= @@ -430,20 +446,18 @@ github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= -github.com/libp2p/go-cidranger v1.1.0 h1:ewPN8EZ0dd1LSnrtuwd4709PXVcITVeuwbag38yPW7c= -github.com/libp2p/go-cidranger v1.1.0/go.mod h1:KWZTfSr+r9qEo9OkI9/SIEeAtw+NNoU0dXIXt15Okic= -github.com/libp2p/go-libp2p v0.25.1 h1:YK+YDCHpYyTvitKWVxa5PfElgIpOONU01X5UcLEwJGA= -github.com/libp2p/go-libp2p v0.25.1/go.mod h1:xnK9/1d9+jeQCVvi/f1g12KqtVi/jP/SijtKV1hML3g= -github.com/libp2p/go-libp2p-asn-util v0.2.0 h1:rg3+Os8jbnO5DxkC7K/Utdi+DkY3q/d1/1q+8WeNAsw= -github.com/libp2p/go-libp2p-asn-util v0.2.0/go.mod h1:WoaWxbHKBymSN41hWSq/lGKJEca7TNm58+gGJi2WsLI= +github.com/libp2p/go-libp2p v0.37.0 h1:8K3mcZgwTldydMCNOiNi/ZJrOB9BY+GlI3UxYzxBi9A= +github.com/libp2p/go-libp2p v0.37.0/go.mod h1:GOKmSN99scDuYGTwaTbQPR8Nt6dxrK3ue7OjW2NGDg4= +github.com/libp2p/go-libp2p-asn-util v0.4.1 h1:xqL7++IKD9TBFMgnLPZR6/6iYhawHKHl950SO9L6n94= +github.com/libp2p/go-libp2p-asn-util v0.4.1/go.mod h1:d/NI6XZ9qxw67b4e+NgpQexCIiFYJjErASrYW4PFDN8= github.com/libp2p/go-libp2p-record v0.2.0 h1:oiNUOCWno2BFuxt3my4i1frNrt7PerzB3queqa1NkQ0= github.com/libp2p/go-libp2p-record v0.2.0/go.mod h1:I+3zMkvvg5m2OcSdoL0KPljyJyvNDFGKX7QdlpYUcwk= github.com/libp2p/go-libp2p-testing v0.12.0 h1:EPvBb4kKMWO29qP4mZGyhVzUyR25dvfUIK5WDu6iPUA= github.com/libp2p/go-libp2p-testing v0.12.0/go.mod h1:KcGDRXyN7sQCllucn1cOOS+Dmm7ujhfEyXQL5lvkcPg= github.com/libp2p/go-msgio v0.3.0 h1:mf3Z8B1xcFN314sWX+2vOTShIE0Mmn2TXn3YCUQGNj0= github.com/libp2p/go-msgio v0.3.0/go.mod h1:nyRM819GmVaF9LX3l03RMh10QdOroF++NBbxAb0mmDM= -github.com/libp2p/go-nat v0.1.0 h1:MfVsH6DLcpa04Xr+p8hmVRG4juse0s3J8HyNWYHffXg= -github.com/libp2p/go-nat v0.1.0/go.mod h1:X7teVkwRHNInVNWQiO/tAiAVRwSr5zoRz4YSTC3uRBM= +github.com/libp2p/go-nat v0.2.0 h1:Tyz+bUFAYqGyJ/ppPPymMGbIgNRH+WqC5QrT5fKrrGk= +github.com/libp2p/go-nat v0.2.0/go.mod h1:3MJr+GRpRkyT65EpVPBstXLvOlAPzUVlG6Pwg9ohLJk= github.com/libp2p/go-netroute v0.2.1 h1:V8kVrpD8GK0Riv15/7VN6RbUQ3URNZVosw7H2v9tksU= github.com/libp2p/go-netroute v0.2.1/go.mod h1:hraioZr0fhBjG0ZRXJJ6Zj2IVEVNx6tDTFQfSmcq7mQ= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= @@ -456,10 +470,6 @@ github.com/mattn/go-runewidth v0.0.10/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRC github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU= github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0 h1:jWpvCLoY8Z/e3VKvlsiIGKtc+UG6U5vzxaoagmhXfyg= -github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQthUoa9bqDv0ER0wrtXnBruoNd7aNjkbP+k= -github.com/miekg/dns v1.1.50 h1:DQUfb9uc6smULcREF09Uc+/Gd46YWqJd5DbpPE9xkcA= -github.com/miekg/dns v1.1.50/go.mod h1:e3IlAVfNqAllflbibAZEWOXOQ+Ynzk/dDozDxY7XnME= github.com/minio/sha256-simd v1.0.1 h1:6kaan5IFmwTNynnKKpDHe6FWHohJOHhCPchzK49dzMM= github.com/minio/sha256-simd v1.0.1/go.mod h1:Pz6AKMiUdngCLpeTL/RJY1M9rUuPMYujV5xJjtbRSN8= github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= @@ -473,10 +483,8 @@ github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aG github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= github.com/multiformats/go-base36 v0.2.0/go.mod h1:qvnKE++v+2MWCfePClUEjE78Z7P2a1UV0xHgWc0hkp4= -github.com/multiformats/go-multiaddr v0.8.0 h1:aqjksEcqK+iD/Foe1RRFsGZh8+XFiGo7FgUCZlpv3LU= -github.com/multiformats/go-multiaddr v0.8.0/go.mod h1:Fs50eBDWvZu+l3/9S6xAE7ZYj6yhxlvaVZjakWN7xRs= -github.com/multiformats/go-multiaddr-dns v0.3.1 h1:QgQgR+LQVt3NPTjbrLLpsaT2ufAA2y0Mkk+QRVJbW3A= -github.com/multiformats/go-multiaddr-dns v0.3.1/go.mod h1:G/245BRQ6FJGmryJCrOuTdB37AMA5AMOVuO6NY3JwTk= +github.com/multiformats/go-multiaddr v0.13.0 h1:BCBzs61E3AGHcYYTv8dqRH43ZfyrqM8RXVPT8t13tLQ= +github.com/multiformats/go-multiaddr v0.13.0/go.mod h1:sBXrNzucqkFJhvKOiwwLyqamGa/P5EIXNPLovyhQCII= github.com/multiformats/go-multiaddr-fmt v0.1.0 h1:WLEFClPycPkp4fnIzoFoV9FVd49/eQsuaL3/CWe167E= github.com/multiformats/go-multiaddr-fmt v0.1.0/go.mod h1:hGtDIW4PU4BqJ50gW2quDuPVjyWNZxToGUh/HwTZYJo= github.com/multiformats/go-multibase v0.2.0 h1:isdYCVLvksgWlMW9OZRYJEa9pZETFivncJHmHnnd87g= @@ -485,10 +493,12 @@ github.com/multiformats/go-multicodec v0.9.0 h1:pb/dlPnzee/Sxv/j4PmkDRxCOi3hXTz3 github.com/multiformats/go-multicodec v0.9.0/go.mod h1:L3QTQvMIaVBkXOXXtVmYE+LI16i14xuaojr/H7Ai54k= github.com/multiformats/go-multihash v0.2.3 h1:7Lyc8XfX/IY2jWb/gI7JP+o7JEq9hOa7BFvVU9RSh+U= github.com/multiformats/go-multihash v0.2.3/go.mod h1:dXgKXCXjBzdscBLk9JkjINiEsCKRVch90MdaGiKsvSM= -github.com/multiformats/go-multistream v0.4.1 h1:rFy0Iiyn3YT0asivDUIR05leAdwZq3de4741sbiSdfo= -github.com/multiformats/go-multistream v0.4.1/go.mod h1:Mz5eykRVAjJWckE2U78c6xqdtyNUEhKSM0Lwar2p77Q= +github.com/multiformats/go-multistream v0.5.0 h1:5htLSLl7lvJk3xx3qT/8Zm9J4K8vEOf/QGkvOGQAyiE= +github.com/multiformats/go-multistream v0.5.0/go.mod h1:n6tMZiwiP2wUsR8DgfDWw1dydlEqV3l6N3/GBsX6ILA= github.com/multiformats/go-varint v0.0.7 h1:sWSGR+f/eu5ABZA2ZpYKBILXTTs9JWpdEM/nEGOHFS8= github.com/multiformats/go-varint v0.0.7/go.mod h1:r8PUYw/fD/SjBCiKOoDlGF6QawOELpZAu9eioSos/OU= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= @@ -506,6 +516,8 @@ github.com/onsi/ginkgo/v2 v2.3.0/go.mod h1:Eew0uilEqZmIEZr8JrvYlvOM7Rr6xzTmMV8Ay github.com/onsi/ginkgo/v2 v2.4.0/go.mod h1:iHkDK1fKGcBoEHT5W7YBq4RFWaQulw+caOMkAt4OrFo= github.com/onsi/ginkgo/v2 v2.5.0/go.mod h1:Luc4sArBICYCS8THh8v3i3i5CuSZO+RaQRaJoeNwomw= github.com/onsi/ginkgo/v2 v2.7.0/go.mod h1:yjiuMwPokqY1XauOgju45q3sJt6VzQ/Fict1LFVcsAo= +github.com/onsi/ginkgo/v2 v2.20.2 h1:7NVCeyIWROIAheY21RLS+3j2bb52W0W82tkberYytp4= +github.com/onsi/ginkgo/v2 v2.20.2/go.mod h1:K9gyxPIlb+aIvnZ8bd9Ak+YP18w3APlR+5coaZoE2ag= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= @@ -528,6 +540,38 @@ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9 h1:1/WtZae0yGtPq+TI6+ github.com/petar/GoLLRB v0.0.0-20210522233825-ae3b015fd3e9/go.mod h1:x3N5drFsm2uilKKuuYo6LdyD8vZAW55sH/9w+pbo1sw= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pion/datachannel v1.5.9 h1:LpIWAOYPyDrXtU+BW7X0Yt/vGtYxtXQ8ql7dFfYUVZA= +github.com/pion/datachannel v1.5.9/go.mod h1:kDUuk4CU4Uxp82NH4LQZbISULkX/HtzKa4P7ldf9izE= +github.com/pion/dtls/v2 v2.2.12 h1:KP7H5/c1EiVAAKUmXyCzPiQe5+bCJrpOeKg/L05dunk= +github.com/pion/dtls/v2 v2.2.12/go.mod h1:d9SYc9fch0CqK90mRk1dC7AkzzpwJj6u2GU3u+9pqFE= +github.com/pion/ice/v2 v2.3.36 h1:SopeXiVbbcooUg2EIR8sq4b13RQ8gzrkkldOVg+bBsc= +github.com/pion/ice/v2 v2.3.36/go.mod h1:mBF7lnigdqgtB+YHkaY/Y6s6tsyRyo4u4rPGRuOjUBQ= +github.com/pion/interceptor v0.1.37 h1:aRA8Zpab/wE7/c0O3fh1PqY0AJI3fCSEM5lRWJVorwI= +github.com/pion/interceptor v0.1.37/go.mod h1:JzxbJ4umVTlZAf+/utHzNesY8tmRkM2lVmkS82TTj8Y= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/mdns v0.0.12 h1:CiMYlY+O0azojWDmxdNr7ADGrnZ+V6Ilfner+6mSVK8= +github.com/pion/mdns v0.0.12/go.mod h1:VExJjv8to/6Wqm1FXK+Ii/Z9tsVk/F5sD/N70cnYFbk= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/rtcp v1.2.14 h1:KCkGV3vJ+4DAJmvP0vaQShsb0xkRfWkO540Gy102KyE= +github.com/pion/rtcp v1.2.14/go.mod h1:sn6qjxvnwyAkkPzPULIbVqSKI5Dv54Rv7VG0kNxh9L4= +github.com/pion/rtp v1.8.9 h1:E2HX740TZKaqdcPmf4pw6ZZuG8u5RlMMt+l3dxeu6Wk= +github.com/pion/rtp v1.8.9/go.mod h1:pBGHaFt/yW7bf1jjWAoUjpSNoDnw98KTMg+jWWvziqU= +github.com/pion/sctp v1.8.33 h1:dSE4wX6uTJBcNm8+YlMg7lw1wqyKHggsP5uKbdj+NZw= +github.com/pion/sctp v1.8.33/go.mod h1:beTnqSzewI53KWoG3nqB282oDMGrhNxBdb+JZnkCwRM= +github.com/pion/sdp/v3 v3.0.9 h1:pX++dCHoHUwq43kuwf3PyJfHlwIj4hXA7Vrifiq0IJY= +github.com/pion/sdp/v3 v3.0.9/go.mod h1:B5xmvENq5IXJimIO4zfp6LAe1fD9N+kFv+V/1lOdz8M= +github.com/pion/srtp/v2 v2.0.20 h1:HNNny4s+OUmG280ETrCdgFndp4ufx3/uy85EawYEhTk= +github.com/pion/srtp/v2 v2.0.20/go.mod h1:0KJQjA99A6/a0DOVTu1PhDSw0CXF2jTkqOoMg3ODqdA= +github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= +github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= +github.com/pion/transport/v2 v2.2.10 h1:ucLBLE8nuxiHfvkFKnkDQRYWYfp8ejf4YBOPfaQpw6Q= +github.com/pion/transport/v2 v2.2.10/go.mod h1:sq1kSLWs+cHW9E+2fJP95QudkzbK7wscs8yYgQToO5E= +github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= +github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pion/webrtc/v3 v3.3.4 h1:v2heQVnXTSqNRXcaFQVOhIOYkLMxOu1iJG8uy1djvkk= +github.com/pion/webrtc/v3 v3.3.4/go.mod h1:liNa+E1iwyzyXqNUwvoMRNQ10x8h8FOeJKL8RkIbamE= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -546,35 +590,41 @@ github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqr github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= -github.com/prometheus/client_golang v1.17.0 h1:rl2sfwZMtSthVU752MqfjQozy7blglC+1SOtjMAMh+Q= -github.com/prometheus/client_golang v1.17.0/go.mod h1:VeL+gMmOAxkS2IqfCq0ZmHSL+LjWfWDUmp1mBz9JgUY= +github.com/prometheus/client_golang v1.20.5 h1:cxppBPuYhUnsO6yo/aoRol4L7q7UFfdm+bR9r+8l63Y= +github.com/prometheus/client_golang v1.20.5/go.mod h1:PIEt8X02hGcP8JWbeHyeZ53Y/jReSnHgO035n//V5WE= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= github.com/prometheus/client_model v0.0.0-20190129233127-fd36f4220a90/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= -github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= -github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/client_model v0.6.1 h1:ZKSh/rekM+n3CeS952MLRAdFwIKqeY8b62p8ais2e9E= +github.com/prometheus/client_model v0.6.1/go.mod h1:OrxVMOVHjw3lKMa8+x6HeMGkHMQyHDk9E3jmP2AmGiY= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= -github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= -github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= +github.com/prometheus/common v0.60.0 h1:+V9PAREWNvJMAuJ1x1BaWl9dewMW4YrHZQbx0sJNllA= +github.com/prometheus/common v0.60.0/go.mod h1:h0LYf1R1deLSKtD4Vdg8gy4RuOvENW2J/h19V5NADQw= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= -github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= -github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/procfs v0.15.1 h1:YagwOFzUgYfKKHX6Dr+sHT7km/hxC76UB0learggepc= +github.com/prometheus/procfs v0.15.1/go.mod h1:fB45yRUv8NstnjriLhBQLuOUt+WW4BsoGhij/e3PBqk= github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/prometheus/statsd_exporter v0.25.0 h1:gpVF1TMf1UqMJmBDpzBYrEaGOFMpbMBYYYUDwM38Y/I= github.com/prometheus/statsd_exporter v0.25.0/go.mod h1:HwzfSvg6ehmb0Qg71ZuFrlgj5XQt9C+MGVLz5Gt5lqc= github.com/puzpuzpuz/xsync/v3 v3.0.2 h1:3yESHrRFYr6xzkz61LLkvNiPFXxJEAABanTQpKbAaew= github.com/puzpuzpuz/xsync/v3 v3.0.2/go.mod h1:VjzYrABPabuM4KyBh1Ftq6u8nhwY5tBPKP9jpmh0nnA= +github.com/quic-go/qpack v0.5.1 h1:giqksBPnT/HDtZ6VhtFKgoLOWmlyo9Ei6u9PqzIMbhI= +github.com/quic-go/qpack v0.5.1/go.mod h1:+PC4XFrEskIVkcLzpEkbLqq1uCoxPhQuvK5rH1ZgaEg= +github.com/quic-go/quic-go v0.48.1 h1:y/8xmfWI9qmGTc+lBr4jKRUWLGSlSigv847ULJ4hYXA= +github.com/quic-go/quic-go v0.48.1/go.mod h1:yBgs3rWBOADpga7F+jJsb6Ybg1LSYiQvwWlLX+/6HMs= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66 h1:4WFk6u3sOT6pLa1kQ50ZVdm8BQFgJNA117cepZxtLIg= +github.com/quic-go/webtransport-go v0.8.1-0.20241018022711-4ac2c9250e66/go.mod h1:Vp72IJajgeOL6ddqrAhmp7IM9zbTcgkQxD/YdxrVwMw= github.com/redis/go-redis/v9 v9.0.0-rc.4/go.mod h1:Vo3EsyWnicKnSKCA7HhgnvnyA74wOA69Cd2Meli5mmA= github.com/redis/go-redis/v9 v9.3.0 h1:RiVDjmig62jIWp7Kk4XVLs0hzV6pI3PyTnnL0cnn0u0= github.com/redis/go-redis/v9 v9.3.0/go.mod h1:hdY0cQFCN4fnSYT6TkisLufl/4W5UIXyv0b/CLO2V2M= @@ -583,13 +633,13 @@ github.com/rivo/uniseg v0.1.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= +github.com/rogpeppe/go-internal v1.13.1 h1:KvO1DLK/DRN07sQ1LQKScxyZJuNnedQ5/wKSR38lUII= +github.com/rogpeppe/go-internal v1.13.1/go.mod h1:uMEvuHeurkdAXX61udpOXGD/AzZDWNMNyH2VO9fmH0o= github.com/russross/blackfriday/v2 v2.0.1/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= -github.com/samber/lo v1.38.1 h1:j2XEAqXKb09Am4ebOg31SpvzUTTs6EN3VfgeLUhPdXM= -github.com/samber/lo v1.38.1/go.mod h1:+m/ZKRl6ClXCE2Lgf3MsQlWfh4bn1bz6CXEOxnEXnEA= +github.com/samber/lo v1.47.0 h1:z7RynLwP5nbyRscyvcD043DWYoOcYRv3mV8lBeqOCLc= +github.com/samber/lo v1.47.0/go.mod h1:RmDH9Ct32Qy3gduHQuKJ3gW1fMHAnE/fAzQuf6He5cU= github.com/samber/slog-echo v1.8.0 h1:DQQRtAliSvQw+ScEdu5gv3jbHu9cCTzvHuTD8GDv7zI= github.com/samber/slog-echo v1.8.0/go.mod h1:0ab2AwcciQXNAXEcjkHwD9okOh9vEHEYn8xP97ocuhM= github.com/scylladb/termtables v0.0.0-20191203121021-c4c0b6d42ff4/go.mod h1:C1a7PQSMz9NShzorzCiG2fk9+xuCgLkPeCvMHYR2OWg= @@ -651,6 +701,8 @@ github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f h1:jQa4QT2UP github.com/whyrusleeping/chunker v0.0.0-20181014151217-fe64bd25879f/go.mod h1:p9UJB6dDgdPgMJZs7UjUOdulKyRr9fqkS+6JKAInPy8= github.com/whyrusleeping/go-did v0.0.0-20230824162731-404d1707d5d6 h1:yJ9/LwIGIk/c0CdoavpC9RNSGSruIspSZtxG3Nnldic= github.com/whyrusleeping/go-did v0.0.0-20230824162731-404d1707d5d6/go.mod h1:39U9RRVr4CKbXpXYopWn+FSH5s+vWu6+RmguSPWAq5s= +github.com/wlynxg/anet v0.0.5 h1:J3VJGi1gvo0JwZ/P1/Yc/8p63SoW98B5dHkYDmpgvvU= +github.com/wlynxg/anet v0.0.5/go.mod h1:eay5PRQr7fIVAMbTbchTnO9gG65Hg/uYGdc7mguHxoA= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU= github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -674,26 +726,26 @@ go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho v0.45.0 h1:JJCIHAxGCB5HM3NxeIwFjHc087Xwk96TG9kaZU6TAec= go.opentelemetry.io/contrib/instrumentation/github.com/labstack/echo/otelecho v0.45.0/go.mod h1:Px9kH7SJ+NhsgWRtD/eMcs15Tyt4uL3rM7X54qv6pfA= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1 h1:aFJWCqJMNjENlcleuuOkGAPH82y0yULBScfXcIEdS24= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.46.1/go.mod h1:sEGXWArGqc3tVa+ekntsN65DmVbVeW+7lTKTjZF3/Fo= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0 h1:UP6IpuHFkUgOQL9FFQFrZ+5LiwhhYRbi7VZSIx6Nj5s= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.56.0/go.mod h1:qxuZLtbq5QDtdeSHsS7bcf6EH6uO6jUAgk764zd3rhM= go.opentelemetry.io/contrib/propagators/b3 v1.20.0 h1:Yty9Vs4F3D6/liF1o6FNt0PvN85h/BJJ6DQKJ3nrcM0= go.opentelemetry.io/contrib/propagators/b3 v1.20.0/go.mod h1:On4VgbkqYL18kbJlWsa18+cMNe6rYpBnPi1ARI/BrsU= -go.opentelemetry.io/otel v1.21.0 h1:hzLeKBZEL7Okw2mGzZ0cc4k/A7Fta0uoPgaJCr8fsFc= -go.opentelemetry.io/otel v1.21.0/go.mod h1:QZzNPQPm1zLX4gZK4cMi+71eaorMSGT3A4znnUvNNEo= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= go.opentelemetry.io/otel/exporters/jaeger v1.14.0 h1:CjbUNd4iN2hHmWekmOqZ+zSCU+dzZppG8XsV+A3oc8Q= go.opentelemetry.io/otel/exporters/jaeger v1.14.0/go.mod h1:4Ay9kk5vELRrbg5z4cpP9EtmQRFap2Wb0woPG4lujZA= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0 h1:cl5P5/GIfFh4t6xyruOgJP5QiA1pw4fYYdv6nc6CBWw= -go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.21.0/go.mod h1:zgBdWWAu7oEEMC06MMKc5NLbA/1YDXV1sMpSqEeLQLg= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0 h1:digkEZCJWobwBqMwC0cwCq8/wkkRy/OowZg5OArWZrM= -go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.21.0/go.mod h1:/OpE/y70qVkndM0TrxT4KBoN3RsFZP0QaofcfYrj76I= -go.opentelemetry.io/otel/metric v1.21.0 h1:tlYWfeo+Bocx5kLEloTjbcDwBuELRrIFxwdQ36PlJu4= -go.opentelemetry.io/otel/metric v1.21.0/go.mod h1:o1p3CA8nNHW8j5yuQLdc1eeqEaPfzug24uvsyIEJRWM= -go.opentelemetry.io/otel/sdk v1.21.0 h1:FTt8qirL1EysG6sTQRZ5TokkU8d0ugCj8htOgThZXQ8= -go.opentelemetry.io/otel/sdk v1.21.0/go.mod h1:Nna6Yv7PWTdgJHVRD9hIYywQBRx7pbox6nwBnZIxl/E= -go.opentelemetry.io/otel/trace v1.21.0 h1:WD9i5gzvoUPuXIXH24ZNBudiarZDKuekPqi/E8fpfLc= -go.opentelemetry.io/otel/trace v1.21.0/go.mod h1:LGbsEB0f9LGjN+OZaQQ26sohbOmiMR+BaslueVtS/qQ= -go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= -go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0 h1:K0XaT3DwHAcV4nKLzcQvwAgSyisUghWoY20I7huthMk= +go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.31.0/go.mod h1:B5Ki776z/MBnVha1Nzwp5arlzBbE3+1jk+pGmaP5HME= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0 h1:lUsI2TYsQw2r1IASwoROaCnjdj2cvC2+Jbxvk6nHnWU= +go.opentelemetry.io/otel/exporters/otlp/otlptrace/otlptracehttp v1.31.0/go.mod h1:2HpZxxQurfGxJlJDblybejHB6RX6pmExPNe517hREw4= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= +go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= +go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.6.0/go.mod h1:sABNBOSYdrvTF6hTgEIbc7YasKWGhgEQZyfxyTvoXHQ= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= @@ -702,8 +754,10 @@ go.uber.org/atomic v1.11.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0 go.uber.org/automaxprocs v1.5.3 h1:kWazyxZUrS3Gs4qUpbwo5kEIMGe/DAvi5Z4tl2NW4j8= go.uber.org/automaxprocs v1.5.3/go.mod h1:eRbA25aqJrxAbsLO0xy5jVwPt7FQnRgjW+efnwa1WM0= go.uber.org/goleak v1.1.11-0.20210813005559-691160354723/go.mod h1:cwTWslyiVhfpKIDGSZEM2HlOvcqm+tG4zioyIeLoqMQ= -go.uber.org/goleak v1.2.0 h1:xqgm/S+aQvhWFTtR0XK3Jvg7z8kGV8P4X14IzwN3Eqk= -go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= +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/mock v0.5.0 h1:KAMbZvZPyBPWgD14IrIQ38QCyjwpvVVV6K/bHl1IwQU= +go.uber.org/mock v0.5.0/go.mod h1:ge71pBPLYDk7QIi1LupWxdAykm7KIEFchiOqd6z7qMM= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.5.0/go.mod h1:FeouvMocqHpRaaGuG9EjoKcStLC43Zu/fmqdUMPcKYU= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= @@ -713,8 +767,8 @@ go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee/go.mod h1:vJERXedbb3MVM5f9E go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.16.0/go.mod h1:MA8QOfq0BHJwdXa996Y4dYkAqRKB8/1K1QMMZVaNZjQ= go.uber.org/zap v1.19.1/go.mod h1:j3DNczoxDZroyBnOT1L/Q79cfUMGZxlv/9dzN7SM1rI= -go.uber.org/zap v1.26.0 h1:sI7k6L95XOKS281NhVKOFCUNIvv9e0w4BF8N3u+tCRo= -go.uber.org/zap v1.26.0/go.mod h1:dtElttAiwGvoJ/vj4IwHBS/gXsEu/pZ50mUIRWuG0so= +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-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= 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= @@ -724,8 +778,8 @@ golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.1.0/go.mod h1:RecgLatLF4+eUMCP1PoPZQb+cVrJcOPbHkTkbkB9sbw= golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= -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.28.0 h1:GBDwsMXVQi34v5CCYUm2jkJvu4cbtru2U4TN2PSyQnw= +golang.org/x/crypto v0.28.0/go.mod h1:rmgy+3RHxRZMyY0jjAJShp2zgEdOqj2AO7U0pYmeQ7U= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -736,8 +790,8 @@ golang.org/x/exp v0.0.0-20191227195350-da58074b4299/go.mod h1:2RIsYlXP63K8oxa1u0 golang.org/x/exp v0.0.0-20200119233911-0405dc783f0a/go.mod h1:2RIsYlXP63K8oxa1u096TMicItID8zy7Y6sNkU49FU4= golang.org/x/exp v0.0.0-20200207192155-f17229e696bd/go.mod h1:J/WKrq2StrnmMY6+EHIKF9dgMWnmCNThgcyBT1FY9mM= golang.org/x/exp v0.0.0-20200224162631-6cc2880d07d6/go.mod h1:3jZMyOhIsHpP37uCMkUooju7aAi5cS1Q23tOzKc+0MU= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa h1:FRnLl4eNAQl8hwxVVC17teOw8kdjVDVAiFMtgUdTSRQ= -golang.org/x/exp v0.0.0-20231110203233-9a3e6036ecaa/go.mod h1:zk2irFbV9DP96SEBUUAy67IdHUaZuSnrz1n472HUCLE= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c h1:7dEasQXItcW1xKJ2+gg5VOiBnqWrJc+rq0DPKyvvdbY= +golang.org/x/exp v0.0.0-20241009180824-f66d83c29e7c/go.mod h1:NQtJDoLvd6faHhE7m4T/1IY708gDefGGjR/iUW8yQQ8= golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= @@ -764,8 +818,8 @@ golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91 golang.org/x/mod v0.6.0/go.mod h1:4mET923SAdbXp2ki8ey+zGs1SLqsuM2Y0uvdZR/fUNI= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= -golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= +golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= +golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -814,8 +868,8 @@ golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/net v0.23.0 h1:7EYJ93RZ9vYSZAIb2x3lnuvqO5zneoD6IvWjuhfxjTs= -golang.org/x/net v0.23.0/go.mod h1:JKghWKKOSdJwpW2GEx0Ja7fmaKnMsbu+MWVZTokSYmg= +golang.org/x/net v0.30.0 h1:AcW1SDZMkb8IpzCdQUaIq2sP4sZ4zw+55h6ynffypl4= +golang.org/x/net v0.30.0/go.mod h1:2wGyMJ5iFasEhkwi13ChkO/t1ECNC4X4eBKkVFyYFlU= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -837,8 +891,8 @@ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= -golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= +golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -902,8 +956,8 @@ golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.22.0 h1:RI27ohtqKCnwULzJLqkv897zojh5/DwS/ENaMzUOaWI= -golang.org/x/sys v0.22.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.26.0 h1:KHjCJyddX0LoSTb3J+vWpupP9p0oznkqVk/IfjymZbo= +golang.org/x/sys v0.26.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.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -926,8 +980,8 @@ golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= -golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= -golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= +golang.org/x/text v0.19.0 h1:kTxAhCbGbxhK0IwgSKiMO5awPoDQ0RpfiVYBfK860YM= +golang.org/x/text v0.19.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= @@ -986,14 +1040,14 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA= golang.org/x/tools v0.4.0/go.mod h1:UE5sM2OK9E/d67R0ANs2xJizIymRP5gJU295PvKXxjQ= golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -golang.org/x/tools v0.15.0 h1:zdAyfUGbYmuVokhzVmghFl2ZJh5QhcfebBgmVPFYA+8= -golang.org/x/tools v0.15.0/go.mod h1:hpksKq4dtpQWS1uQ61JkdqWM3LscIS6Slf+VVkm+wQk= +golang.org/x/tools v0.26.0 h1:v/60pFQmzmT9ExmjDv2gGIfi3OqfKoEP6I5+umXlbnQ= +golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028 h1:+cNy6SZtPcJQH3LJVLOSmiC7MMxXNOb3PU/VUEz+EhU= -golang.org/x/xerrors v0.0.0-20231012003039-104605ab7028/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da h1:noIWHXmPHxILtqtCOPIhSt0ABwskkZKjD3bXGnZGpNY= +golang.org/x/xerrors v0.0.0-20240903120638-7835f813f4da/go.mod h1:NDW/Ps6MPRej6fsCIbMTohpP40sJ/P/vI1MoTEGwX90= google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE= google.golang.org/api v0.7.0/go.mod h1:WtwebWUNSVBH/HAw79HIFXZNqEvBhG+Ra+ax0hx3E3M= google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg= @@ -1045,12 +1099,10 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= -google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9 h1:T6rh4haD3GVYsgEfWExoCZA2o2FmbNyKpTuAxbEFPTg= +google.golang.org/genproto/googleapis/api v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:wp2WsuBYj6j8wUdo3ToZsdxxixbvQNAHqVJrTgi5E5M= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9 h1:QCqS/PdaHTSWGvupk2F/ehwHtGc0/GYkT+3GAcR1CCc= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241007155032-5fefd90f89a9/go.mod h1:GX3210XPVPUjJbTUbvwI8f2IpZDMZuPJWDzDuebbviI= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -1064,8 +1116,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.67.1 h1:zWnc1Vrcno+lHZCOofnIMvycFcc0QRGIzm9dhnDX68E= +google.golang.org/grpc v1.67.1/go.mod h1:1gLDyUQU7CTLJI90u3nXZ9ekeghjeM7pTDZlqFNg2AA= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -1080,8 +1132,8 @@ google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp0 google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -google.golang.org/protobuf v1.33.0 h1:uNO2rsAINq/JlFpSdYEKIZ0uKD/R9cpdv0T+yoGwGmI= -google.golang.org/protobuf v1.33.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos= +google.golang.org/protobuf v1.35.1 h1:m3LfL6/Ca+fqnjnlqQXNpFPABW1UD7mjh8KO2mKFytA= +google.golang.org/protobuf v1.35.1/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -1119,8 +1171,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -lukechampine.com/blake3 v1.2.1 h1:YuqqRuaqsGV71BV/nm9xlI0MKUv4QC54jQnBChWbGnI= -lukechampine.com/blake3 v1.2.1/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= +lukechampine.com/blake3 v1.3.0 h1:sJ3XhFINmHSrYCgl958hscfIa3bw8x4DqMP3u1YvoYE= +lukechampine.com/blake3 v1.3.0/go.mod h1:0OFRp7fBtAylGVCO40o87sbupkyIGgbpv1+M1k1LM6k= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/indexer/crawler.go b/indexer/crawler.go index e5e41b9bb..526da9bb6 100644 --- a/indexer/crawler.go +++ b/indexer/crawler.go @@ -3,6 +3,7 @@ package indexer import ( "context" "fmt" + "log/slog" "sync" "time" @@ -29,10 +30,12 @@ type CrawlDispatcher struct { concurrency int + log *slog.Logger + done chan struct{} } -func NewCrawlDispatcher(repoFn func(context.Context, *crawlWork) error, concurrency int) (*CrawlDispatcher, error) { +func NewCrawlDispatcher(repoFn func(context.Context, *crawlWork) error, concurrency int, log *slog.Logger) (*CrawlDispatcher, error) { if concurrency < 1 { return nil, fmt.Errorf("must specify a non-zero positive integer for crawl dispatcher concurrency") } @@ -46,6 +49,7 @@ func NewCrawlDispatcher(repoFn func(context.Context, *crawlWork) error, concurre concurrency: concurrency, todo: make(map[models.Uid]*crawlWork), inProgress: make(map[models.Uid]*crawlWork), + log: log, done: make(chan struct{}), } go out.CatchupRepoGaugePoller() @@ -218,7 +222,7 @@ func (c *CrawlDispatcher) fetchWorker() { select { case job := <-c.repoSync: if err := c.doRepoCrawl(context.TODO(), job); err != nil { - log.Errorf("failed to perform repo crawl of %q: %s", job.act.Did, err) + c.log.Error("failed to perform repo crawl", "did", job.act.Did, "err", err) } // TODO: do we still just do this if it errors? diff --git a/indexer/indexer.go b/indexer/indexer.go index 91f5a1b43..2c3a2b53d 100644 --- a/indexer/indexer.go +++ b/indexer/indexer.go @@ -5,6 +5,7 @@ import ( "database/sql" "errors" "fmt" + "log/slog" "time" comatproto "github.com/bluesky-social/indigo/api/atproto" @@ -19,14 +20,11 @@ import ( "github.com/bluesky-social/indigo/xrpc" "github.com/ipfs/go-cid" - logging "github.com/ipfs/go-log" "go.opentelemetry.io/otel" "gorm.io/gorm" "gorm.io/gorm/clause" ) -var log = logging.Logger("indexer") - const MaxEventSliceLength = 1000000 const MaxOpsSliceLength = 200 @@ -45,6 +43,8 @@ type Indexer struct { SendRemoteFollow func(context.Context, string, uint) error CreateExternalUser func(context.Context, string) (*models.ActorInfo, error) ApplyPDSClientSettings func(*xrpc.Client) + + log *slog.Logger } func NewIndexer(db *gorm.DB, notifman notifs.NotificationManager, evtman *events.EventManager, didr did.Resolver, fetcher *RepoFetcher, crawl, aggregate, spider bool) (*Indexer, error) { @@ -65,10 +65,11 @@ func NewIndexer(db *gorm.DB, notifman notifs.NotificationManager, evtman *events return nil }, ApplyPDSClientSettings: func(*xrpc.Client) {}, + log: slog.Default().With("system", "indexer"), } if crawl { - c, err := NewCrawlDispatcher(fetcher.FetchAndIndexRepo, fetcher.MaxConcurrency) + c, err := NewCrawlDispatcher(fetcher.FetchAndIndexRepo, fetcher.MaxConcurrency, ix.log) if err != nil { return nil, err } @@ -90,7 +91,7 @@ func (ix *Indexer) HandleRepoEvent(ctx context.Context, evt *repomgr.RepoEvent) ctx, span := otel.Tracer("indexer").Start(ctx, "HandleRepoEvent") defer span.End() - log.Debugw("Handling Repo Event!", "uid", evt.User) + ix.log.Debug("Handling Repo Event!", "uid", evt.User) outops := make([]*comatproto.SyncSubscribeRepos_RepoOp, 0, len(evt.Ops)) for _, op := range evt.Ops { @@ -102,7 +103,7 @@ func (ix *Indexer) HandleRepoEvent(ctx context.Context, evt *repomgr.RepoEvent) }) if err := ix.handleRepoOp(ctx, evt, &op); err != nil { - log.Errorw("failed to handle repo op", "err", err) + ix.log.Error("failed to handle repo op", "err", err) } } @@ -119,7 +120,7 @@ func (ix *Indexer) HandleRepoEvent(ctx context.Context, evt *repomgr.RepoEvent) toobig = true } - log.Debugw("Sending event", "did", did) + ix.log.Debug("Sending event", "did", did) if err := ix.events.AddEvent(ctx, &events.XRPCStreamEvent{ RepoCommit: &comatproto.SyncSubscribeRepos_Commit{ Repo: did, @@ -197,7 +198,7 @@ func (ix *Indexer) crawlRecordReferences(ctx context.Context, op *repomgr.RepoOp if e.Type == "mention" { _, err := ix.GetUserOrMissing(ctx, e.Value) if err != nil { - log.Infow("failed to parse user mention", "ref", e.Value, "err", err) + ix.log.Info("failed to parse user mention", "ref", e.Value, "err", err) } } } @@ -205,13 +206,13 @@ func (ix *Indexer) crawlRecordReferences(ctx context.Context, op *repomgr.RepoOp if rec.Reply != nil { if rec.Reply.Parent != nil { if err := ix.crawlAtUriRef(ctx, rec.Reply.Parent.Uri); err != nil { - log.Infow("failed to crawl reply parent", "cid", op.RecCid, "replyuri", rec.Reply.Parent.Uri, "err", err) + ix.log.Info("failed to crawl reply parent", "cid", op.RecCid, "replyuri", rec.Reply.Parent.Uri, "err", err) } } if rec.Reply.Root != nil { if err := ix.crawlAtUriRef(ctx, rec.Reply.Root.Uri); err != nil { - log.Infow("failed to crawl reply root", "cid", op.RecCid, "rooturi", rec.Reply.Root.Uri, "err", err) + ix.log.Info("failed to crawl reply root", "cid", op.RecCid, "rooturi", rec.Reply.Root.Uri, "err", err) } } } @@ -220,27 +221,27 @@ func (ix *Indexer) crawlRecordReferences(ctx context.Context, op *repomgr.RepoOp case *bsky.FeedRepost: if rec.Subject != nil { if err := ix.crawlAtUriRef(ctx, rec.Subject.Uri); err != nil { - log.Infow("failed to crawl repost subject", "cid", op.RecCid, "subjecturi", rec.Subject.Uri, "err", err) + ix.log.Info("failed to crawl repost subject", "cid", op.RecCid, "subjecturi", rec.Subject.Uri, "err", err) } } return nil case *bsky.FeedLike: if rec.Subject != nil { if err := ix.crawlAtUriRef(ctx, rec.Subject.Uri); err != nil { - log.Infow("failed to crawl like subject", "cid", op.RecCid, "subjecturi", rec.Subject.Uri, "err", err) + ix.log.Info("failed to crawl like subject", "cid", op.RecCid, "subjecturi", rec.Subject.Uri, "err", err) } } return nil case *bsky.GraphFollow: _, err := ix.GetUserOrMissing(ctx, rec.Subject) if err != nil { - log.Infow("failed to crawl follow subject", "cid", op.RecCid, "subjectdid", rec.Subject, "err", err) + ix.log.Info("failed to crawl follow subject", "cid", op.RecCid, "subjectdid", rec.Subject, "err", err) } return nil case *bsky.GraphBlock: _, err := ix.GetUserOrMissing(ctx, rec.Subject) if err != nil { - log.Infow("failed to crawl follow subject", "cid", op.RecCid, "subjectdid", rec.Subject, "err", err) + ix.log.Info("failed to crawl follow subject", "cid", op.RecCid, "subjectdid", rec.Subject, "err", err) } return nil case *bsky.ActorProfile: @@ -252,7 +253,7 @@ func (ix *Indexer) crawlRecordReferences(ctx context.Context, op *repomgr.RepoOp case *bsky.FeedGenerator: return nil default: - log.Warnw("unrecognized record type (crawling references)", "record", op.Record, "collection", op.Collection) + ix.log.Warn("unrecognized record type (crawling references)", "record", op.Record, "collection", op.Collection) return nil } } @@ -293,7 +294,7 @@ func (ix *Indexer) createMissingUserRecord(ctx context.Context, did string) (*mo } func (ix *Indexer) addUserToCrawler(ctx context.Context, ai *models.ActorInfo) error { - log.Debugw("Sending user to crawler: ", "did", ai.Did) + ix.log.Debug("Sending user to crawler: ", "did", ai.Did) if ix.Crawler == nil { return nil } @@ -395,7 +396,7 @@ func (ix *Indexer) GetPost(ctx context.Context, uri string) (*models.FeedPost, e } func (ix *Indexer) handleRecordDelete(ctx context.Context, evt *repomgr.RepoEvent, op *repomgr.RepoOp, local bool) error { - log.Debugw("record delete event", "collection", op.Collection) + ix.log.Debug("record delete event", "collection", op.Collection) switch op.Collection { case "app.bsky.feed.post": @@ -411,7 +412,7 @@ func (ix *Indexer) handleRecordDelete(ctx context.Context, evt *repomgr.RepoEven fp, err := ix.GetPost(ctx, uri) if err != nil { if errors.Is(err, gorm.ErrRecordNotFound) { - log.Warnw("deleting post weve never seen before. Weird.", "user", evt.User, "rkey", op.Rkey) + ix.log.Warn("deleting post weve never seen before. Weird.", "user", evt.User, "rkey", op.Rkey) return nil } return err @@ -425,7 +426,7 @@ func (ix *Indexer) handleRecordDelete(ctx context.Context, evt *repomgr.RepoEven return err } - log.Warn("TODO: remove notifications on delete") + ix.log.Warn("TODO: remove notifications on delete") /* if err := ix.notifman.RemoveRepost(ctx, fp.Author, rr.ID, evt.User); err != nil { return nil, err @@ -466,7 +467,7 @@ func (ix *Indexer) handleRecordDeleteFeedLike(ctx context.Context, evt *repomgr. return err } - log.Warnf("need to delete vote notification") + ix.log.Warn("need to delete vote notification") return nil } @@ -477,7 +478,7 @@ func (ix *Indexer) handleRecordDeleteGraphFollow(ctx context.Context, evt *repom } if q.RowsAffected == 0 { - log.Warnw("attempted to delete follow we did not have a record for", "user", evt.User, "rkey", op.Rkey) + ix.log.Warn("attempted to delete follow we did not have a record for", "user", evt.User, "rkey", op.Rkey) return nil } @@ -485,7 +486,7 @@ func (ix *Indexer) handleRecordDeleteGraphFollow(ctx context.Context, evt *repom } func (ix *Indexer) handleRecordCreate(ctx context.Context, evt *repomgr.RepoEvent, op *repomgr.RepoOp, local bool) ([]uint, error) { - log.Debugw("record create event", "collection", op.Collection) + ix.log.Debug("record create event", "collection", op.Collection) var out []uint switch rec := op.Record.(type) { @@ -535,7 +536,7 @@ func (ix *Indexer) handleRecordCreate(ctx context.Context, evt *repomgr.RepoEven case *bsky.FeedGenerator: return out, nil case *bsky.ActorProfile: - log.Debugf("TODO: got actor profile record creation, need to do something with this") + ix.log.Debug("TODO: got actor profile record creation, need to do something with this") default: return nil, fmt.Errorf("unrecognized record type (creation): %s", op.Collection) } @@ -609,7 +610,7 @@ func (ix *Indexer) handleRecordCreateGraphFollow(ctx context.Context, rec *bsky. } func (ix *Indexer) handleRecordUpdate(ctx context.Context, evt *repomgr.RepoEvent, op *repomgr.RepoOp, local bool) error { - log.Debugw("record update event", "collection", op.Collection) + ix.log.Debug("record update event", "collection", op.Collection) switch rec := op.Record.(type) { case *bsky.FeedPost: @@ -629,7 +630,7 @@ func (ix *Indexer) handleRecordUpdate(ctx context.Context, evt *repomgr.RepoEven if oldReply != newReply { // the 'replyness' of the post was changed... that's weird - log.Errorf("need to properly handle case where reply-ness of posts is changed") + ix.log.Error("need to properly handle case where reply-ness of posts is changed") return nil } @@ -640,7 +641,7 @@ func (ix *Indexer) handleRecordUpdate(ctx context.Context, evt *repomgr.RepoEven } if replyto.ID != fp.ReplyTo { - log.Errorf("post was changed to be a reply to a different post") + ix.log.Error("post was changed to be a reply to a different post") return nil } } @@ -693,7 +694,7 @@ func (ix *Indexer) handleRecordUpdate(ctx context.Context, evt *repomgr.RepoEven return ix.handleRecordCreateGraphFollow(ctx, rec, evt, op) case *bsky.ActorProfile: - log.Debugf("TODO: got actor profile record update, need to do something with this") + ix.log.Debug("TODO: got actor profile record update, need to do something with this") default: return fmt.Errorf("unrecognized record type (update): %s", op.Collection) } @@ -767,7 +768,7 @@ func (ix *Indexer) handleRecordCreateFeedPost(ctx context.Context, user models.U // we're likely filling in a missing reference if !maybe.Missing { // TODO: we've already processed this record creation - log.Warnw("potentially erroneous event, duplicate create", "rkey", rkey, "user", user) + ix.log.Warn("potentially erroneous event, duplicate create", "rkey", rkey, "user", user) } if err := ix.db.Clauses(clause.OnConflict{ @@ -791,7 +792,7 @@ func (ix *Indexer) handleRecordCreateFeedPost(ctx context.Context, user models.U } func (ix *Indexer) createMissingPostRecord(ctx context.Context, puri *util.ParsedUri) (*models.FeedPost, error) { - log.Warn("creating missing post record") + ix.log.Warn("creating missing post record") ai, err := ix.GetUserOrMissing(ctx, puri.Did) if err != nil { return nil, err @@ -813,7 +814,7 @@ func (ix *Indexer) addNewPostNotification(ctx context.Context, post *bsky.FeedPo if post.Reply != nil { replyto, err := ix.GetPost(ctx, post.Reply.Parent.Uri) if err != nil { - log.Error("probably shouldn't error when processing a reply to a not-found post") + ix.log.Error("probably shouldn't error when processing a reply to a not-found post") return err } diff --git a/indexer/keymgr.go b/indexer/keymgr.go index b13b980d6..9f9de2cd5 100644 --- a/indexer/keymgr.go +++ b/indexer/keymgr.go @@ -3,6 +3,7 @@ package indexer import ( "context" "fmt" + "log/slog" did "github.com/whyrusleeping/go-did" "go.opentelemetry.io/otel" @@ -12,6 +13,8 @@ type KeyManager struct { didr DidResolver signingKey *did.PrivKey + + log *slog.Logger } type DidResolver interface { @@ -22,6 +25,7 @@ func NewKeyManager(didr DidResolver, k *did.PrivKey) *KeyManager { return &KeyManager{ didr: didr, signingKey: k, + log: slog.Default().With("system", "indexer"), } } @@ -36,7 +40,7 @@ func (km *KeyManager) VerifyUserSignature(ctx context.Context, did string, sig [ err = k.Verify(msg, sig) if err != nil { - log.Warnw("signature failed to verify", "err", err, "did", did, "pubKey", k, "sigBytes", sig, "msgBytes", msg) + km.log.Warn("signature failed to verify", "err", err, "did", did, "pubKey", k, "sigBytes", sig, "msgBytes", msg) } return err } diff --git a/indexer/repofetch.go b/indexer/repofetch.go index b5f776ed8..8ce68bb5f 100644 --- a/indexer/repofetch.go +++ b/indexer/repofetch.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "io/fs" + "log/slog" "sync" "github.com/bluesky-social/indigo/api/atproto" @@ -27,6 +28,7 @@ func NewRepoFetcher(db *gorm.DB, rm *repomgr.RepoManager, maxConcurrency int) *R Limiters: make(map[uint]*rate.Limiter), ApplyPDSClientSettings: func(*xrpc.Client) {}, MaxConcurrency: maxConcurrency, + log: slog.Default().With("system", "indexer"), } } @@ -40,6 +42,8 @@ type RepoFetcher struct { MaxConcurrency int ApplyPDSClientSettings func(*xrpc.Client) + + log *slog.Logger } func (rf *RepoFetcher) GetLimiter(pdsID uint) *rate.Limiter { @@ -50,8 +54,8 @@ func (rf *RepoFetcher) GetLimiter(pdsID uint) *rate.Limiter { } func (rf *RepoFetcher) GetOrCreateLimiter(pdsID uint, pdsrate float64) *rate.Limiter { - rf.LimitMux.RLock() - defer rf.LimitMux.RUnlock() + rf.LimitMux.Lock() + defer rf.LimitMux.Unlock() lim, ok := rf.Limiters[pdsID] if !ok { @@ -84,7 +88,7 @@ func (rf *RepoFetcher) fetchRepo(ctx context.Context, c *xrpc.Client, pds *model // Wait to prevent DOSing the PDS when connecting to a new stream with lots of active repos limiter.Wait(ctx) - log.Debugw("SyncGetRepo", "did", did, "since", rev) + rf.log.Debug("SyncGetRepo", "did", did, "since", rev) // TODO: max size on these? A malicious PDS could just send us a petabyte sized repo here and kill us repo, err := atproto.SyncGetRepo(ctx, c, did, rev) if err != nil { @@ -125,7 +129,7 @@ func (rf *RepoFetcher) FetchAndIndexRepo(ctx context.Context, job *crawlWork) er for i, j := range job.catchup { catchupEventsProcessed.Inc() if err := rf.repoman.HandleExternalUserEvent(ctx, pds.ID, ai.Uid, ai.Did, j.evt.Since, j.evt.Rev, j.evt.Blocks, j.evt.Ops); err != nil { - log.Errorw("buffered event catchup failed", "error", err, "did", ai.Did, "i", i, "jobCount", len(job.catchup), "seq", j.evt.Seq) + rf.log.Error("buffered event catchup failed", "error", err, "did", ai.Did, "i", i, "jobCount", len(job.catchup), "seq", j.evt.Seq) resync = true // fall back to a repo sync break } @@ -153,7 +157,7 @@ func (rf *RepoFetcher) FetchAndIndexRepo(ctx context.Context, job *crawlWork) er span.RecordError(err) if ipld.IsNotFound(err) || errors.Is(err, io.EOF) || errors.Is(err, fs.ErrNotExist) { - log.Errorw("partial repo fetch was missing data", "did", ai.Did, "pds", pds.Host, "rev", rev) + rf.log.Error("partial repo fetch was missing data", "did", ai.Did, "pds", pds.Host, "rev", rev) repo, err := rf.fetchRepo(ctx, c, &pds, ai.Did, "") if err != nil { return err diff --git a/mst/diff.go b/mst/diff.go index 1c70e82e6..4006c756c 100644 --- a/mst/diff.go +++ b/mst/diff.go @@ -5,8 +5,8 @@ import ( "fmt" "github.com/bluesky-social/indigo/util" + "github.com/ipfs/boxo/blockstore" cid "github.com/ipfs/go-cid" - blockstore "github.com/ipfs/go-ipfs-blockstore" ) type DiffOp struct { diff --git a/mst/mst_test.go b/mst/mst_test.go index 6bd491781..2ad3ff70b 100644 --- a/mst/mst_test.go +++ b/mst/mst_test.go @@ -13,9 +13,9 @@ import ( "testing" "github.com/bluesky-social/indigo/util" + "github.com/ipfs/boxo/blockstore" cid "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" "github.com/ipld/go-car/v2" "github.com/multiformats/go-multihash" mh "github.com/multiformats/go-multihash" diff --git a/pds/feedgen.go b/pds/feedgen.go index aacb775be..9ad51387a 100644 --- a/pds/feedgen.go +++ b/pds/feedgen.go @@ -3,6 +3,7 @@ package pds import ( "context" "fmt" + "log/slog" "sort" "strings" "time" @@ -22,13 +23,16 @@ type FeedGenerator struct { ix *indexer.Indexer readRecord ReadRecordFunc + + log *slog.Logger } -func NewFeedGenerator(db *gorm.DB, ix *indexer.Indexer, readRecord ReadRecordFunc) (*FeedGenerator, error) { +func NewFeedGenerator(db *gorm.DB, ix *indexer.Indexer, readRecord ReadRecordFunc, log *slog.Logger) (*FeedGenerator, error) { return &FeedGenerator{ db: db, ix: ix, readRecord: readRecord, + log: log, }, nil } @@ -355,7 +359,7 @@ func (fg *FeedGenerator) hydrateVote(ctx context.Context, v *models.VoteRecord) func (fg *FeedGenerator) GetVotes(ctx context.Context, uri string, pcid cid.Cid, limit int, before string) ([]*HydratedVote, error) { if before != "" { - log.Warn("not respecting 'before' yet") + fg.log.Warn("not respecting 'before' yet") } p, err := fg.ix.GetPost(ctx, uri) diff --git a/pds/server.go b/pds/server.go index 54f1dfed1..da534518c 100644 --- a/pds/server.go +++ b/pds/server.go @@ -5,6 +5,7 @@ import ( "database/sql" "errors" "fmt" + "log/slog" "net" "net/http" "net/mail" @@ -30,7 +31,6 @@ import ( gojwt "github.com/golang-jwt/jwt" "github.com/gorilla/websocket" "github.com/ipfs/go-cid" - logging "github.com/ipfs/go-log" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" "github.com/lestrrat-go/jwx/v2/jwt" @@ -38,8 +38,6 @@ import ( "gorm.io/gorm" ) -var log = logging.Logger("pds") - type Server struct { db *gorm.DB cs carstore.CarStore @@ -57,6 +55,8 @@ type Server struct { serviceUrl string plc plc.PLCClient + + log *slog.Logger } // serverListenerBootTimeout is how long to wait for the requested server socket @@ -97,18 +97,20 @@ func NewServer(db *gorm.DB, cs carstore.CarStore, serkey *did.PrivKey, handleSuf serviceUrl: serviceUrl, jwtSigningKey: jwtkey, enforcePeering: false, + + log: slog.Default().With("system", "pds"), } repoman.SetEventHandler(func(ctx context.Context, evt *repomgr.RepoEvent) { if err := ix.HandleRepoEvent(ctx, evt); err != nil { - log.Errorw("handle repo event failed", "user", evt.User, "err", err) + s.log.Error("handle repo event failed", "user", evt.User, "err", err) } }, true) //ix.SendRemoteFollow = s.sendRemoteFollow ix.CreateExternalUser = s.createExternalUser - feedgen, err := NewFeedGenerator(db, ix, s.readRecordFunc) + feedgen, err := NewFeedGenerator(db, ix, s.readRecordFunc, s.log) if err != nil { return nil, err } @@ -434,7 +436,7 @@ type HealthStatus struct { func (s *Server) HandleHealthCheck(c echo.Context) error { if err := s.db.Exec("SELECT 1").Error; err != nil { - log.Errorf("healthcheck can't connect to database: %v", err) + s.log.Error("healthcheck can't connect to database", "err", err) return c.JSON(500, HealthStatus{Status: "error", Message: "can't connect to database"}) } else { return c.JSON(200, HealthStatus{Status: "ok"}) @@ -726,7 +728,7 @@ func (s *Server) EventsHandler(c echo.Context) error { func (s *Server) UpdateUserHandle(ctx context.Context, u *User, handle string) error { if u.Handle == handle { // no change? move on - log.Warnw("attempted to change handle to current handle", "did", u.Did, "handle", handle) + s.log.Warn("attempted to change handle to current handle", "did", u.Did, "handle", handle) return nil } diff --git a/repo/repo.go b/repo/repo.go index acdafcce6..0ee46e06e 100644 --- a/repo/repo.go +++ b/repo/repo.go @@ -9,9 +9,9 @@ import ( lexutil "github.com/bluesky-social/indigo/lex/util" "github.com/bluesky-social/indigo/mst" "github.com/bluesky-social/indigo/util" + "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" cbor "github.com/ipfs/go-ipld-cbor" "github.com/ipld/go-car/v2" cbg "github.com/whyrusleeping/cbor-gen" diff --git a/repomgr/repomgr.go b/repomgr/repomgr.go index bdf20d784..9dae44e38 100644 --- a/repomgr/repomgr.go +++ b/repomgr/repomgr.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "io" + "log/slog" "strings" "sync" "time" @@ -19,12 +20,11 @@ import ( "github.com/bluesky-social/indigo/repo" "github.com/bluesky-social/indigo/util" + "github.com/ipfs/boxo/blockstore" blocks "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" ipld "github.com/ipfs/go-ipld-format" - logging "github.com/ipfs/go-log/v2" "github.com/ipld/go-car" cbg "github.com/whyrusleeping/cbor-gen" "go.opentelemetry.io/otel" @@ -32,14 +32,13 @@ import ( "gorm.io/gorm" ) -var log = logging.Logger("repomgr") - func NewRepoManager(cs carstore.CarStore, kmgr KeyManager) *RepoManager { return &RepoManager{ cs: cs, userLocks: make(map[models.Uid]*userLock), kmgr: kmgr, + log: slog.Default().With("system", "repomgr"), } } @@ -62,6 +61,8 @@ type RepoManager struct { events func(context.Context, *RepoEvent) hydrateRecords bool + + log *slog.Logger } type ActorInfo struct { @@ -534,7 +535,7 @@ func (rm *RepoManager) HandleExternalUserEvent(ctx context.Context, pdsid uint, span.SetAttributes(attribute.Int64("uid", int64(uid))) - log.Debugw("HandleExternalUserEvent", "pds", pdsid, "uid", uid, "since", since, "nrev", nrev) + rm.log.Debug("HandleExternalUserEvent", "pds", pdsid, "uid", uid, "since", since, "nrev", nrev) unlock := rm.lockUser(ctx, uid) defer unlock() @@ -835,9 +836,9 @@ func (rm *RepoManager) ImportNewRepo(ctx context.Context, user models.Uid, repoD ops := make([]RepoOp, 0, len(diffops)) for _, op := range diffops { repoOpsImported.Inc() - out, err := processOp(ctx, bs, op, rm.hydrateRecords) + out, err := rm.processOp(ctx, bs, op, rm.hydrateRecords) if err != nil { - log.Errorw("failed to process repo op", "err", err, "path", op.Rpath, "repo", repoDid) + rm.log.Error("failed to process repo op", "err", err, "path", op.Rpath, "repo", repoDid) } if out != nil { @@ -871,7 +872,7 @@ func (rm *RepoManager) ImportNewRepo(ctx context.Context, user models.Uid, repoD return nil } -func processOp(ctx context.Context, bs blockstore.Blockstore, op *mst.DiffOp, hydrateRecords bool) (*RepoOp, error) { +func (rm *RepoManager) processOp(ctx context.Context, bs blockstore.Blockstore, op *mst.DiffOp, hydrateRecords bool) (*RepoOp, error) { parts := strings.SplitN(op.Rpath, "/", 2) if len(parts) != 2 { return nil, fmt.Errorf("repo mst had invalid rpath: %q", op.Rpath) @@ -904,7 +905,7 @@ func processOp(ctx context.Context, bs blockstore.Blockstore, op *mst.DiffOp, hy return nil, err } - log.Warnf("failed processing repo diff: %s", err) + rm.log.Warn("failed processing repo diff", "err", err) } else { outop.Record = rec } @@ -960,7 +961,7 @@ func (rm *RepoManager) processNewRepo(ctx context.Context, user models.Uid, r io // the repos lifecycle, this will end up erroneously not including // them. We should compute the set of blocks needed to read any repo // ops that happened in the commit and use that for our 'output' blocks - cids, err := walkTree(ctx, seen, root, membs, true) + cids, err := rm.walkTree(ctx, seen, root, membs, true) if err != nil { return fmt.Errorf("walkTree: %w", err) } @@ -1001,7 +1002,7 @@ func stringOrNil(s *string) string { // walkTree returns all cids linked recursively by the root, skipping any cids // in the 'skip' map, and not erroring on 'not found' if prevMissing is set -func walkTree(ctx context.Context, skip map[cid.Cid]bool, root cid.Cid, bs blockstore.Blockstore, prevMissing bool) ([]cid.Cid, error) { +func (rm *RepoManager) walkTree(ctx context.Context, skip map[cid.Cid]bool, root cid.Cid, bs blockstore.Blockstore, prevMissing bool) ([]cid.Cid, error) { // TODO: what if someone puts non-cbor links in their repo? if root.Prefix().Codec != cid.DagCBOR { return nil, fmt.Errorf("can only handle dag-cbor objects in repos (%s is %d)", root, root.Prefix().Codec) @@ -1015,7 +1016,7 @@ func walkTree(ctx context.Context, skip map[cid.Cid]bool, root cid.Cid, bs block var links []cid.Cid if err := cbg.ScanForLinks(bytes.NewReader(blk.RawData()), func(c cid.Cid) { if c.Prefix().Codec == cid.Raw { - log.Debugw("skipping 'raw' CID in record", "recordCid", root, "rawCid", c) + rm.log.Debug("skipping 'raw' CID in record", "recordCid", root, "rawCid", c) return } if skip[c] { @@ -1035,7 +1036,7 @@ func walkTree(ctx context.Context, skip map[cid.Cid]bool, root cid.Cid, bs block // TODO: should do this non-recursive since i expect these may get deep for _, c := range links { - sub, err := walkTree(ctx, skip, c, bs, prevMissing) + sub, err := rm.walkTree(ctx, skip, c, bs, prevMissing) if err != nil { if prevMissing && !ipld.IsNotFound(err) { return nil, err diff --git a/search/firehose.go b/search/firehose.go index 0400b9648..6db633cc0 100644 --- a/search/firehose.go +++ b/search/firehose.go @@ -139,6 +139,7 @@ func (idx *Indexer) RunIndexer(ctx context.Context) error { idx.relayhost, rsc.EventHandler, ), + idx.logger, ) } diff --git a/splitter/splitter.go b/splitter/splitter.go index b592edd8c..ca63aa05d 100644 --- a/splitter/splitter.go +++ b/splitter/splitter.go @@ -5,6 +5,7 @@ import ( "errors" "fmt" "io" + "log/slog" "math/rand" "net" "net/http" @@ -18,7 +19,6 @@ import ( events "github.com/bluesky-social/indigo/events" "github.com/bluesky-social/indigo/events/schedulers/sequential" "github.com/gorilla/websocket" - logging "github.com/ipfs/go-log" "github.com/labstack/echo/v4" "github.com/labstack/echo/v4/middleware" promclient "github.com/prometheus/client_golang/prometheus" @@ -26,8 +26,6 @@ import ( dto "github.com/prometheus/client_model/go" ) -var log = logging.Logger("splitter") - type Splitter struct { erb *EventRingBuffer pp *events.PebblePersist @@ -39,6 +37,8 @@ type Splitter struct { consumers map[uint64]*SocketConsumer conf SplitterConfig + + log *slog.Logger } type SplitterConfig struct { @@ -61,6 +61,7 @@ func NewMemSplitter(host string) *Splitter { erb: erb, events: em, consumers: make(map[uint64]*SocketConsumer), + log: slog.Default().With("system", "splitter"), } } func NewSplitter(conf SplitterConfig) (*Splitter, error) { @@ -74,6 +75,7 @@ func NewSplitter(conf SplitterConfig) (*Splitter, error) { erb: erb, events: em, consumers: make(map[uint64]*SocketConsumer), + log: slog.Default().With("system", "splitter"), }, nil } else { pp, err := events.NewPebblePersistance(conf.PebbleOptions) @@ -88,6 +90,7 @@ func NewSplitter(conf SplitterConfig) (*Splitter, error) { pp: pp, events: em, consumers: make(map[uint64]*SocketConsumer), + log: slog.Default().With("system", "splitter"), }, nil } } @@ -115,6 +118,7 @@ func NewDiskSplitter(host, path string, persistHours float64, maxBytes int64) (* pp: pp, events: em, consumers: make(map[uint64]*SocketConsumer), + log: slog.Default().With("system", "splitter"), }, nil } @@ -173,7 +177,7 @@ func (s *Splitter) StartWithListener(listen net.Listener) error { if err2 := ctx.JSON(err.Code, map[string]any{ "error": err.Message, }); err2 != nil { - log.Errorf("Failed to write http error: %s", err2) + s.log.Error("Failed to write http error", "err", err2) } default: sendHeader := true @@ -181,7 +185,7 @@ func (s *Splitter) StartWithListener(listen net.Listener) error { sendHeader = false } - log.Warnf("HANDLER ERROR: (%s) %s", ctx.Path(), err) + s.log.Warn("HANDLER ERROR", "path", ctx.Path(), "err", err) if strings.HasPrefix(ctx.Path(), "/admin/") { ctx.JSON(500, map[string]any{ @@ -275,7 +279,7 @@ func (s *Splitter) EventsHandler(c echo.Context) error { } if err := conn.WriteControl(websocket.PingMessage, []byte{}, time.Now().Add(5*time.Second)); err != nil { - log.Errorf("failed to ping client: %s", err) + s.log.Error("failed to ping client", "err", err) cancel() return } @@ -300,7 +304,7 @@ func (s *Splitter) EventsHandler(c echo.Context) error { for { _, _, err := conn.ReadMessage() if err != nil { - log.Errorf("failed to read message from client: %s", err) + s.log.Error("failed to read message from client", "err", err) cancel() return } @@ -327,7 +331,7 @@ func (s *Splitter) EventsHandler(c echo.Context) error { consumerID := s.registerConsumer(&consumer) defer s.cleanupConsumer(consumerID) - log.Infow("new consumer", + s.log.Info("new consumer", "remote_addr", consumer.RemoteAddr, "user_agent", consumer.UserAgent, "cursor", since, @@ -340,13 +344,13 @@ func (s *Splitter) EventsHandler(c echo.Context) error { select { case evt, ok := <-evts: if !ok { - log.Error("event stream closed unexpectedly") + s.log.Error("event stream closed unexpectedly") return nil } wc, err := conn.NextWriter(websocket.BinaryMessage) if err != nil { - log.Errorf("failed to get next writer: %s", err) + s.log.Error("failed to get next writer", "err", err) return err } @@ -360,7 +364,7 @@ func (s *Splitter) EventsHandler(c echo.Context) error { } if err := wc.Close(); err != nil { - log.Warnf("failed to flush-close our event write: %s", err) + s.log.Warn("failed to flush-close our event write", "err", err) return nil } @@ -401,10 +405,10 @@ func (s *Splitter) cleanupConsumer(id uint64) { var m = &dto.Metric{} if err := c.EventsSent.Write(m); err != nil { - log.Errorf("failed to get sent counter: %s", err) + s.log.Error("failed to get sent counter", "err", err) } - log.Infow("consumer disconnected", + s.log.Info("consumer disconnected", "consumer_id", id, "remote_addr", c.RemoteAddr, "user_agent", c.UserAgent, @@ -450,17 +454,17 @@ func (s *Splitter) subscribeWithRedialer(ctx context.Context, host string, curso } con, res, err := d.DialContext(ctx, url, header) if err != nil { - log.Warnw("dialing failed", "host", host, "err", err, "backoff", backoff) + s.log.Warn("dialing failed", "host", host, "err", err, "backoff", backoff) time.Sleep(sleepForBackoff(backoff)) backoff++ continue } - log.Info("event subscription response code: ", res.StatusCode) + s.log.Info("event subscription response", "code", res.StatusCode) if err := s.handleConnection(ctx, host, con, &cursor); err != nil { - log.Warnf("connection to %q failed: %s", host, err) + s.log.Warn("connection failed", "host", host, "err", err) } } } @@ -483,7 +487,7 @@ func (s *Splitter) handleConnection(ctx context.Context, host string, con *webso if seq%5000 == 0 { // TODO: don't need this after we move to getting seq from pebble if err := s.writeCursor(seq); err != nil { - log.Errorf("write cursor failed: %s", err) + s.log.Error("write cursor failed", "err", err) } } @@ -491,19 +495,19 @@ func (s *Splitter) handleConnection(ctx context.Context, host string, con *webso return nil }) - return events.HandleRepoStream(ctx, con, sched) + return events.HandleRepoStream(ctx, con, sched, nil) } func (s *Splitter) getLastCursor() (int64, error) { if s.pp != nil { seq, millis, _, err := s.pp.GetLast(context.Background()) if err == nil { - log.Debugw("got last cursor from pebble", "seq", seq, "millis", millis) + s.log.Debug("got last cursor from pebble", "seq", seq, "millis", millis) return seq, nil } else if errors.Is(err, events.ErrNoLast) { - log.Info("pebble no last") + s.log.Info("pebble no last") } else { - log.Errorw("pebble seq fail", "err", err) + s.log.Error("pebble seq fail", "err", err) } } diff --git a/testing/car_did_repro_test.go b/testing/car_did_repro_test.go index e75c26045..34e4b2f5e 100644 --- a/testing/car_did_repro_test.go +++ b/testing/car_did_repro_test.go @@ -14,9 +14,9 @@ import ( "github.com/bluesky-social/indigo/repo" "github.com/bluesky-social/indigo/util" + "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-cid" "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" "github.com/stretchr/testify/assert" cbg "github.com/whyrusleeping/cbor-gen" "github.com/whyrusleeping/go-did" diff --git a/testing/integ_test.go b/testing/integ_test.go index cef32d3a4..df3c3fedb 100644 --- a/testing/integ_test.go +++ b/testing/integ_test.go @@ -15,15 +15,10 @@ import ( "github.com/bluesky-social/indigo/repo" "github.com/bluesky-social/indigo/xrpc" "github.com/ipfs/go-cid" - "github.com/ipfs/go-log/v2" car "github.com/ipld/go-car" "github.com/stretchr/testify/assert" ) -func init() { - log.SetAllLoggers(log.LevelInfo) -} - func TestRelayBasic(t *testing.T) { if testing.Short() { t.Skip("skipping Relay test in 'short' test mode") diff --git a/testing/sig_test.go b/testing/sig_test.go index 7dc0fb603..bc90e9772 100644 --- a/testing/sig_test.go +++ b/testing/sig_test.go @@ -10,8 +10,8 @@ import ( "github.com/bluesky-social/indigo/repo" + "github.com/ipfs/boxo/blockstore" "github.com/ipfs/go-datastore" - blockstore "github.com/ipfs/go-ipfs-blockstore" "github.com/stretchr/testify/assert" "github.com/whyrusleeping/go-did" secp "gitlab.com/yawning/secp256k1-voi" diff --git a/testing/utils.go b/testing/utils.go index 7af6e1adc..066f7bf51 100644 --- a/testing/utils.go +++ b/testing/utils.go @@ -691,7 +691,7 @@ func (b *TestRelay) Events(t *testing.T, since int64) *EventStream { }, } seqScheduler := sequential.NewScheduler("test", rsc.EventHandler) - if err := events.HandleRepoStream(ctx, con, seqScheduler); err != nil { + if err := events.HandleRepoStream(ctx, con, seqScheduler, nil); err != nil { fmt.Println(err) } }() diff --git a/util/cbor.go b/util/cbor.go index 70d040f1d..797994c25 100644 --- a/util/cbor.go +++ b/util/cbor.go @@ -1,7 +1,7 @@ package util import ( - blockstore "github.com/ipfs/go-ipfs-blockstore" + "github.com/ipfs/boxo/blockstore" cbor "github.com/ipfs/go-ipld-cbor" mh "github.com/multiformats/go-multihash" ) diff --git a/util/cliutil/ipfslog.go b/util/cliutil/ipfslog.go new file mode 100644 index 000000000..4f3a0f1c9 --- /dev/null +++ b/util/cliutil/ipfslog.go @@ -0,0 +1,35 @@ +package cliutil + +import ( + "io" + + ipfslog "github.com/ipfs/go-log/v2" + "go.uber.org/zap/zapcore" +) + +func SetIpfsWriter(out io.Writer, format string, level string) { + var ze zapcore.Encoder + switch format { + case "json": + ze = zapcore.NewJSONEncoder(zapcore.EncoderConfig{}) + case "text": + ze = zapcore.NewConsoleEncoder(zapcore.EncoderConfig{}) + default: + ze = zapcore.NewConsoleEncoder(zapcore.EncoderConfig{}) + } + var zl zapcore.LevelEnabler + switch level { + case "debug": + zl = zapcore.DebugLevel + case "info": + zl = zapcore.InfoLevel + case "warn": + zl = zapcore.WarnLevel + case "error": + zl = zapcore.ErrorLevel + default: + zl = zapcore.InfoLevel + } + nc := zapcore.NewCore(ze, zapcore.AddSync(out), zl) + ipfslog.SetPrimaryCore(nc) +} diff --git a/util/cliutil/util.go b/util/cliutil/util.go index 758643eff..4694b5b99 100644 --- a/util/cliutil/util.go +++ b/util/cliutil/util.go @@ -2,10 +2,17 @@ package cliutil import ( "encoding/json" + "errors" "fmt" + "io" + "io/fs" + "log/slog" "net/http" "os" "path/filepath" + "regexp" + "sort" + "strconv" "strings" "time" @@ -230,3 +237,333 @@ func SetupDatabase(dburl string, maxConnections int) (*gorm.DB, error) { return db, nil } + +type LogOptions struct { + // e.g. 1_000_000_000 + LogRotateBytes int64 + + // path to write to, if rotating, %T gets UnixMilli at file open time + // NOTE: substitution is simple replace("%T", "") + LogPath string + + // text|json + LogFormat string + + // info|debug|warn|error + LogLevel string + + // Keep N old logs (not including current); <0 disables removal, 0==remove all old log files immediately + KeepOld int +} + +// SetupSlog integrates passed in options and env vars. +// +// passing default cliutil.LogOptions{} is ok. +// +// BSKYLOG_LOG_LEVEL=info|debug|warn|error +// +// BSKYLOG_LOG_FMT=text|json +// +// BSKYLOG_FILE=path (or "-" or "" for stdout), %T gets UnixMilli; if a path with '/', {prefix}/current becomes a link to active log file +// +// BSKYLOG_ROTATE_BYTES=int maximum size of log chunk before rotating +// +// BSKYLOG_ROTATE_KEEP=int keep N olg logs (not including current) +// +// (env vars derived from ipfs logging library) +func SetupSlog(options LogOptions) (*slog.Logger, error) { + fmt.Fprintf(os.Stderr, "SetupSlog\n") + var hopts slog.HandlerOptions + hopts.Level = slog.LevelInfo + hopts.AddSource = true + if options.LogLevel == "" { + options.LogLevel = os.Getenv("BSKYLOG_LOG_LEVEL") + } + if options.LogLevel == "" { + hopts.Level = slog.LevelInfo + options.LogLevel = "info" + } else { + level := strings.ToLower(options.LogLevel) + switch level { + case "debug": + hopts.Level = slog.LevelDebug + case "info": + hopts.Level = slog.LevelInfo + case "warn": + hopts.Level = slog.LevelWarn + case "error": + hopts.Level = slog.LevelError + default: + return nil, fmt.Errorf("unknown log level: %#v", options.LogLevel) + } + } + if options.LogFormat == "" { + options.LogFormat = os.Getenv("BSKYLOG_LOG_FMT") + } + if options.LogFormat == "" { + options.LogFormat = "text" + } else { + format := strings.ToLower(options.LogFormat) + if format == "json" || format == "text" { + // ok + } else { + return nil, fmt.Errorf("invalid log format: %#v", options.LogFormat) + } + options.LogFormat = format + } + + if options.LogPath == "" { + options.LogPath = os.Getenv("BSKYLOG_FILE") + } + if options.LogRotateBytes == 0 { + rotateBytesStr := os.Getenv("BSKYLOG_ROTATE_BYTES") + if rotateBytesStr != "" { + rotateBytes, err := strconv.ParseInt(rotateBytesStr, 10, 64) + if err != nil { + return nil, fmt.Errorf("invalid BSKYLOG_ROTATE_BYTES value: %w", err) + } + options.LogRotateBytes = rotateBytes + } + } + if options.KeepOld == 0 { + keepOldUnset := true + keepOldStr := os.Getenv("BSKYLOG_ROTATE_KEEP") + if keepOldStr != "" { + keepOld, err := strconv.ParseInt(keepOldStr, 10, 64) + if err != nil { + return nil, fmt.Errorf("invalid BSKYLOG_ROTATE_KEEP value: %w", err) + } + keepOldUnset = false + options.KeepOld = int(keepOld) + } + if keepOldUnset { + options.KeepOld = 2 + } + } + logaround := make(chan string, 100) + go logbouncer(logaround) + var out io.Writer + if (options.LogPath == "") || (options.LogPath == "-") { + out = os.Stdout + } else if options.LogRotateBytes != 0 { + out = &logRotateWriter{ + rotateBytes: options.LogRotateBytes, + outPathTemplate: options.LogPath, + keep: options.KeepOld, + logaround: logaround, + } + } else { + var err error + out, err = os.Create(options.LogPath) + if err != nil { + return nil, fmt.Errorf("%s: %w", options.LogPath, err) + } + fmt.Fprintf(os.Stderr, "SetupSlog create %#v\n", options.LogPath) + } + var handler slog.Handler + switch options.LogFormat { + case "text": + handler = slog.NewTextHandler(out, &hopts) + case "json": + handler = slog.NewJSONHandler(out, &hopts) + default: + return nil, fmt.Errorf("unknown log format: %#v", options.LogFormat) + } + logger := slog.New(handler) + slog.SetDefault(logger) + templateDirPart, _ := filepath.Split(options.LogPath) + ents, _ := os.ReadDir(templateDirPart) + for _, ent := range ents { + fmt.Fprintf(os.Stdout, "%s\n", filepath.Join(templateDirPart, ent.Name())) + } + SetIpfsWriter(out, options.LogFormat, options.LogLevel) + return logger, nil +} + +type logRotateWriter struct { + currentWriter io.WriteCloser + + // how much has been written to current log file + currentBytes int64 + + // e.g. path/to/logs/foo%T + currentPath string + + // e.g. path/to/logs/current + currentPathCurrent string + + rotateBytes int64 + + outPathTemplate string + + // keep the most recent N log files (not including current) + keep int + + // write strings to this from inside the log system, a task outside the log system hands them to slog.Info() + logaround chan<- string +} + +func logbouncer(out <-chan string) { + var logger *slog.Logger + for line := range out { + fmt.Fprintf(os.Stderr, "ll %s\n", line) + if logger == nil { + // lazy to make sure it crops up after slog Default has been set + logger = slog.Default().With("system", "logging") + } + logger.Info(line) + } +} + +var currentMatcher = regexp.MustCompile("current_\\d+") + +func (w *logRotateWriter) cleanOldLogs() { + if w.keep < 0 { + // old log removal is disabled + return + } + // w.currentPath was recently set as the new log + dirpart, _ := filepath.Split(w.currentPath) + // find old logs + templateDirPart, templateNamePart := filepath.Split(w.outPathTemplate) + if dirpart != templateDirPart { + w.logaround <- fmt.Sprintf("current dir part %#v != template dir part %#v\n", w.currentPath, w.outPathTemplate) + return + } + // build a regexp that is string literal parts with \d+ replacing the UnixMilli part + templateNameParts := strings.Split(templateNamePart, "%T") + var sb strings.Builder + first := true + for _, part := range templateNameParts { + if first { + first = false + } else { + sb.WriteString("\\d+") + } + sb.WriteString(regexp.QuoteMeta(part)) + } + tmre, err := regexp.Compile(sb.String()) + if err != nil { + w.logaround <- fmt.Sprintf("failed to compile old log template regexp: %#v\n", err) + return + } + dir, err := os.ReadDir(dirpart) + if err != nil { + w.logaround <- fmt.Sprintf("failed to read old log template dir: %#v\n", err) + return + } + var found []fs.FileInfo + for _, ent := range dir { + name := ent.Name() + if tmre.MatchString(name) || currentMatcher.MatchString(name) { + fi, err := ent.Info() + if err != nil { + continue + } + found = append(found, fi) + } + } + if len(found) <= w.keep { + // not too many, nothing to do + return + } + foundMtimeLess := func(i, j int) bool { + return found[i].ModTime().Before(found[j].ModTime()) + } + sort.Slice(found, foundMtimeLess) + drops := found[:len(found)-w.keep] + for _, fi := range drops { + fullpath := filepath.Join(dirpart, fi.Name()) + err = os.Remove(fullpath) + if err != nil { + w.logaround <- fmt.Sprintf("failed to rm old log: %#v\n", err) + // but keep going + } + // maybe it would be safe to debug-log old log removal from within the logging infrastructure? + } +} + +func (w *logRotateWriter) closeOldLog() []error { + if w.currentWriter == nil { + return nil + } + var earlyWeakErrors []error + err := w.currentWriter.Close() + if err != nil { + earlyWeakErrors = append(earlyWeakErrors, err) + } + w.currentWriter = nil + w.currentBytes = 0 + w.currentPath = "" + if w.currentPathCurrent != "" { + err = os.Remove(w.currentPathCurrent) // not really an error until something else goes wrong + if err != nil { + earlyWeakErrors = append(earlyWeakErrors, err) + } + w.currentPathCurrent = "" + } + return earlyWeakErrors +} + +func (w *logRotateWriter) openNewLog(earlyWeakErrors []error) (badErr error, weakErrors []error) { + nowMillis := time.Now().UnixMilli() + nows := strconv.FormatInt(nowMillis, 10) + w.currentPath = strings.Replace(w.outPathTemplate, "%T", nows, -1) + var err error + w.currentWriter, err = os.Create(w.currentPath) + if err != nil { + earlyWeakErrors = append(earlyWeakErrors, err) + return errors.Join(earlyWeakErrors...), nil + } + w.logaround <- fmt.Sprintf("new log file %#v", w.currentPath) + w.cleanOldLogs() + dirpart, _ := filepath.Split(w.currentPath) + if dirpart != "" { + w.currentPathCurrent = filepath.Join(dirpart, "current") + fi, err := os.Stat(w.currentPathCurrent) + if err == nil && fi.Mode().IsRegular() { + // move aside unknown "current" from a previous run + // see also currentMatcher regexp current_\d+ + err = os.Rename(w.currentPathCurrent, w.currentPathCurrent+"_"+nows) + if err != nil { + // not crucial if we can't move aside "current" + // TODO: log warning ... but not from inside log writer? + earlyWeakErrors = append(earlyWeakErrors, err) + } + } + err = os.Link(w.currentPath, w.currentPathCurrent) + if err != nil { + // not crucial if we can't make "current" link + // TODO: log warning ... but not from inside log writer? + earlyWeakErrors = append(earlyWeakErrors, err) + } + } + return nil, earlyWeakErrors +} + +func (w *logRotateWriter) Write(p []byte) (n int, err error) { + var earlyWeakErrors []error + if int64(len(p))+w.currentBytes > w.rotateBytes { + // next write would be over the limit + earlyWeakErrors = w.closeOldLog() + } + if w.currentWriter == nil { + // start new log file + var err error + err, earlyWeakErrors = w.openNewLog(earlyWeakErrors) + if err != nil { + return 0, err + } + } + var wrote int + wrote, err = w.currentWriter.Write(p) + w.currentBytes += int64(wrote) + if err != nil { + earlyWeakErrors = append(earlyWeakErrors, err) + return wrote, errors.Join(earlyWeakErrors...) + } + if earlyWeakErrors != nil { + w.logaround <- fmt.Sprintf("ok, but: %s", errors.Join(earlyWeakErrors...).Error()) + } + return wrote, nil +} diff --git a/util/readrecordbs.go b/util/readrecordbs.go index 41cb36143..3045118d8 100644 --- a/util/readrecordbs.go +++ b/util/readrecordbs.go @@ -4,9 +4,9 @@ import ( "context" "fmt" + "github.com/ipfs/boxo/blockstore" blockformat "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" - blockstore "github.com/ipfs/go-ipfs-blockstore" ) type LoggingBstore struct { diff --git a/util/tierbs.go b/util/tierbs.go index 484ceff19..debfd85e5 100644 --- a/util/tierbs.go +++ b/util/tierbs.go @@ -4,9 +4,9 @@ import ( "context" "fmt" + "github.com/ipfs/boxo/blockstore" blockformat "github.com/ipfs/go-block-format" "github.com/ipfs/go-cid" - blockstore "github.com/ipfs/go-ipfs-blockstore" ipld "github.com/ipfs/go-ipld-format" )