From 99c7f811ef7efaed77de5d9fb52af08bfc3b6919 Mon Sep 17 00:00:00 2001 From: oppiliappan Date: Thu, 9 Oct 2025 14:04:19 +0100 Subject: [PATCH] appview: improve the logging situation a bit Change-Id: rvtvrxvprtwloxtxrnqsnuyrkqnqtoyt needs a lot more work, but we now inject slog in several places. Signed-off-by: oppiliappan --- appview/db/db.go | 64 +++---- appview/ingester.go | 2 +- appview/issues/issues.go | 53 +++--- appview/labels/labels.go | 4 +- appview/notifications/notifications.go | 27 +-- appview/pages/pages.go | 4 +- appview/pipelines/pipelines.go | 4 +- appview/pulls/pulls.go | 4 + appview/repo/index.go | 25 +-- appview/repo/repo.go | 222 +++++++++++++++---------- appview/signup/signup.go | 2 +- appview/state/knotstream.go | 4 +- appview/state/login.go | 11 +- appview/state/router.go | 72 ++++++-- appview/state/spindlestream.go | 4 +- appview/state/state.go | 38 ++--- cmd/appview/main.go | 23 ++- cmd/spindle/main.go | 12 +- go.mod | 13 ++ go.sum | 27 +++ jetstream/jetstream.go | 2 +- nix/gomod2nix.toml | 39 +++++ xrpc/serviceauth/service_auth.go | 9 +- 23 files changed, 430 insertions(+), 235 deletions(-) diff --git a/appview/db/db.go b/appview/db/db.go index cabfaa1b..8cd3fac9 100644 --- a/appview/db/db.go +++ b/appview/db/db.go @@ -4,15 +4,17 @@ import ( "context" "database/sql" "fmt" - "log" + "log/slog" "reflect" "strings" _ "github.com/mattn/go-sqlite3" + "tangled.org/core/log" ) type DB struct { *sql.DB + logger *slog.Logger } type Execer interface { @@ -26,7 +28,7 @@ type Execer interface { PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) } -func Make(dbPath string) (*DB, error) { +func Make(ctx context.Context, dbPath string) (*DB, error) { // https://github.com/mattn/go-sqlite3#connection-string opts := []string{ "_foreign_keys=1", @@ -35,13 +37,14 @@ func Make(dbPath string) (*DB, error) { "_auto_vacuum=incremental", } + logger := log.FromContext(ctx) + logger = log.SubLogger(logger, "db") + db, err := sql.Open("sqlite3", dbPath+"?"+strings.Join(opts, "&")) if err != nil { return nil, err } - ctx := context.Background() - conn, err := db.Conn(ctx) if err != nil { return nil, err @@ -574,14 +577,14 @@ func Make(dbPath string) (*DB, error) { } // run migrations - runMigration(conn, "add-description-to-repos", func(tx *sql.Tx) error { + runMigration(conn, logger, "add-description-to-repos", func(tx *sql.Tx) error { tx.Exec(` alter table repos add column description text check (length(description) <= 200); `) return nil }) - runMigration(conn, "add-rkey-to-pubkeys", func(tx *sql.Tx) error { + runMigration(conn, logger, "add-rkey-to-pubkeys", func(tx *sql.Tx) error { // add unconstrained column _, err := tx.Exec(` alter table public_keys @@ -604,7 +607,7 @@ func Make(dbPath string) (*DB, error) { return nil }) - runMigration(conn, "add-rkey-to-comments", func(tx *sql.Tx) error { + runMigration(conn, logger, "add-rkey-to-comments", func(tx *sql.Tx) error { _, err := tx.Exec(` alter table comments drop column comment_at; alter table comments add column rkey text; @@ -612,7 +615,7 @@ func Make(dbPath string) (*DB, error) { return err }) - runMigration(conn, "add-deleted-and-edited-to-issue-comments", func(tx *sql.Tx) error { + runMigration(conn, logger, "add-deleted-and-edited-to-issue-comments", func(tx *sql.Tx) error { _, err := tx.Exec(` alter table comments add column deleted text; -- timestamp alter table comments add column edited text; -- timestamp @@ -620,7 +623,7 @@ func Make(dbPath string) (*DB, error) { return err }) - runMigration(conn, "add-source-info-to-pulls-and-submissions", func(tx *sql.Tx) error { + runMigration(conn, logger, "add-source-info-to-pulls-and-submissions", func(tx *sql.Tx) error { _, err := tx.Exec(` alter table pulls add column source_branch text; alter table pulls add column source_repo_at text; @@ -629,7 +632,7 @@ func Make(dbPath string) (*DB, error) { return err }) - runMigration(conn, "add-source-to-repos", func(tx *sql.Tx) error { + runMigration(conn, logger, "add-source-to-repos", func(tx *sql.Tx) error { _, err := tx.Exec(` alter table repos add column source text; `) @@ -641,7 +644,7 @@ func Make(dbPath string) (*DB, error) { // // [0]: https://sqlite.org/pragma.html#pragma_foreign_keys conn.ExecContext(ctx, "pragma foreign_keys = off;") - runMigration(conn, "recreate-pulls-column-for-stacking-support", func(tx *sql.Tx) error { + runMigration(conn, logger, "recreate-pulls-column-for-stacking-support", func(tx *sql.Tx) error { _, err := tx.Exec(` create table pulls_new ( -- identifiers @@ -698,7 +701,7 @@ func Make(dbPath string) (*DB, error) { }) conn.ExecContext(ctx, "pragma foreign_keys = on;") - runMigration(conn, "add-spindle-to-repos", func(tx *sql.Tx) error { + runMigration(conn, logger, "add-spindle-to-repos", func(tx *sql.Tx) error { tx.Exec(` alter table repos add column spindle text; `) @@ -708,7 +711,7 @@ func Make(dbPath string) (*DB, error) { // drop all knot secrets, add unique constraint to knots // // knots will henceforth use service auth for signed requests - runMigration(conn, "no-more-secrets", func(tx *sql.Tx) error { + runMigration(conn, logger, "no-more-secrets", func(tx *sql.Tx) error { _, err := tx.Exec(` create table registrations_new ( id integer primary key autoincrement, @@ -731,7 +734,7 @@ func Make(dbPath string) (*DB, error) { }) // recreate and add rkey + created columns with default constraint - runMigration(conn, "rework-collaborators-table", func(tx *sql.Tx) error { + runMigration(conn, logger, "rework-collaborators-table", func(tx *sql.Tx) error { // create new table // - repo_at instead of repo integer // - rkey field @@ -785,7 +788,7 @@ func Make(dbPath string) (*DB, error) { return err }) - runMigration(conn, "add-rkey-to-issues", func(tx *sql.Tx) error { + runMigration(conn, logger, "add-rkey-to-issues", func(tx *sql.Tx) error { _, err := tx.Exec(` alter table issues add column rkey text not null default ''; @@ -797,7 +800,7 @@ func Make(dbPath string) (*DB, error) { }) // repurpose the read-only column to "needs-upgrade" - runMigration(conn, "rename-registrations-read-only-to-needs-upgrade", func(tx *sql.Tx) error { + runMigration(conn, logger, "rename-registrations-read-only-to-needs-upgrade", func(tx *sql.Tx) error { _, err := tx.Exec(` alter table registrations rename column read_only to needs_upgrade; `) @@ -805,7 +808,7 @@ func Make(dbPath string) (*DB, error) { }) // require all knots to upgrade after the release of total xrpc - runMigration(conn, "migrate-knots-to-total-xrpc", func(tx *sql.Tx) error { + runMigration(conn, logger, "migrate-knots-to-total-xrpc", func(tx *sql.Tx) error { _, err := tx.Exec(` update registrations set needs_upgrade = 1; `) @@ -813,7 +816,7 @@ func Make(dbPath string) (*DB, error) { }) // require all knots to upgrade after the release of total xrpc - runMigration(conn, "migrate-spindles-to-xrpc-owner", func(tx *sql.Tx) error { + runMigration(conn, logger, "migrate-spindles-to-xrpc-owner", func(tx *sql.Tx) error { _, err := tx.Exec(` alter table spindles add column needs_upgrade integer not null default 0; `) @@ -831,7 +834,7 @@ func Make(dbPath string) (*DB, error) { // // disable foreign-keys for the next migration conn.ExecContext(ctx, "pragma foreign_keys = off;") - runMigration(conn, "remove-issue-at-from-issues", func(tx *sql.Tx) error { + runMigration(conn, logger, "remove-issue-at-from-issues", func(tx *sql.Tx) error { _, err := tx.Exec(` create table if not exists issues_new ( -- identifiers @@ -901,7 +904,7 @@ func Make(dbPath string) (*DB, error) { // - new columns // * column "reply_to" which can be any other comment // * column "at-uri" which is a generated column - runMigration(conn, "rework-issue-comments", func(tx *sql.Tx) error { + runMigration(conn, logger, "rework-issue-comments", func(tx *sql.Tx) error { _, err := tx.Exec(` create table if not exists issue_comments ( -- identifiers @@ -961,7 +964,7 @@ func Make(dbPath string) (*DB, error) { // // disable foreign-keys for the next migration conn.ExecContext(ctx, "pragma foreign_keys = off;") - runMigration(conn, "add-at-uri-to-pulls", func(tx *sql.Tx) error { + runMigration(conn, logger, "add-at-uri-to-pulls", func(tx *sql.Tx) error { _, err := tx.Exec(` create table if not exists pulls_new ( -- identifiers @@ -1042,7 +1045,7 @@ func Make(dbPath string) (*DB, error) { // // disable foreign-keys for the next migration conn.ExecContext(ctx, "pragma foreign_keys = off;") - runMigration(conn, "remove-repo-at-pull-id-from-pull-submissions", func(tx *sql.Tx) error { + runMigration(conn, logger, "remove-repo-at-pull-id-from-pull-submissions", func(tx *sql.Tx) error { _, err := tx.Exec(` create table if not exists pull_submissions_new ( -- identifiers @@ -1094,12 +1097,17 @@ func Make(dbPath string) (*DB, error) { }) conn.ExecContext(ctx, "pragma foreign_keys = on;") - return &DB{db}, nil + return &DB{ + db, + logger, + }, nil } type migrationFn = func(*sql.Tx) error -func runMigration(c *sql.Conn, name string, migrationFn migrationFn) error { +func runMigration(c *sql.Conn, logger *slog.Logger, name string, migrationFn migrationFn) error { + logger = logger.With("migration", name) + tx, err := c.BeginTx(context.Background(), nil) if err != nil { return err @@ -1116,14 +1124,14 @@ func runMigration(c *sql.Conn, name string, migrationFn migrationFn) error { // run migration err = migrationFn(tx) if err != nil { - log.Printf("Failed to run migration %s: %v", name, err) + logger.Error("failed to run migration", "err", err) return err } // mark migration as complete _, err = tx.Exec("insert into migrations (name) values (?)", name) if err != nil { - log.Printf("Failed to mark migration %s as complete: %v", name, err) + logger.Error("failed to mark migration as complete", "err", err) return err } @@ -1132,9 +1140,9 @@ func runMigration(c *sql.Conn, name string, migrationFn migrationFn) error { return err } - log.Printf("migration %s applied successfully", name) + logger.Info("migration applied successfully") } else { - log.Printf("skipped migration %s, already applied", name) + logger.Warn("skipped migration, already applied") } return nil diff --git a/appview/ingester.go b/appview/ingester.go index cead268f..547233fe 100644 --- a/appview/ingester.go +++ b/appview/ingester.go @@ -89,7 +89,7 @@ func (i *Ingester) Ingest() processFunc { } if err != nil { - l.Debug("error ingesting record", "err", err) + l.Warn("refused to ingest record", "err", err) } return nil diff --git a/appview/issues/issues.go b/appview/issues/issues.go index d454d890..a758eb2b 100644 --- a/appview/issues/issues.go +++ b/appview/issues/issues.go @@ -5,7 +5,6 @@ import ( "database/sql" "errors" "fmt" - "log" "log/slog" "net/http" "slices" @@ -28,7 +27,6 @@ import ( "tangled.org/core/appview/reporesolver" "tangled.org/core/appview/validator" "tangled.org/core/idresolver" - tlog "tangled.org/core/log" "tangled.org/core/tid" ) @@ -53,6 +51,7 @@ func New( config *config.Config, notifier notify.Notifier, validator *validator.Validator, + logger *slog.Logger, ) *Issues { return &Issues{ oauth: oauth, @@ -62,7 +61,7 @@ func New( db: db, config: config, notifier: notifier, - logger: tlog.New("issues"), + logger: logger, validator: validator, } } @@ -72,7 +71,7 @@ func (rp *Issues) RepoSingleIssue(w http.ResponseWriter, r *http.Request) { user := rp.oauth.GetUser(r) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -99,7 +98,7 @@ func (rp *Issues) RepoSingleIssue(w http.ResponseWriter, r *http.Request) { db.FilterContains("scope", tangled.RepoIssueNSID), ) if err != nil { - log.Println("failed to fetch labels", err) + l.Error("failed to fetch labels", "err", err) rp.pages.Error503(w) return } @@ -126,7 +125,7 @@ func (rp *Issues) EditIssue(w http.ResponseWriter, r *http.Request) { user := rp.oauth.GetUser(r) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -199,7 +198,7 @@ func (rp *Issues) EditIssue(w http.ResponseWriter, r *http.Request) { err = db.PutIssue(tx, newIssue) if err != nil { - log.Println("failed to edit issue", err) + l.Error("failed to edit issue", "err", err) rp.pages.Notice(w, "issues", "Failed to edit issue.") return } @@ -237,7 +236,7 @@ func (rp *Issues) DeleteIssue(w http.ResponseWriter, r *http.Request) { // delete from PDS client, err := rp.oauth.AuthorizedClient(r) if err != nil { - log.Println("failed to get authorized client", err) + l.Error("failed to get authorized client", "err", err) rp.pages.Notice(w, "issue-comment", "Failed to delete comment.") return } @@ -282,7 +281,7 @@ func (rp *Issues) CloseIssue(w http.ResponseWriter, r *http.Request) { collaborators, err := f.Collaborators(r.Context()) if err != nil { - log.Println("failed to fetch repo collaborators: %w", err) + l.Error("failed to fetch repo collaborators", "err", err) } isCollaborator := slices.ContainsFunc(collaborators, func(collab pages.Collaborator) bool { return user.Did == collab.Did @@ -296,7 +295,7 @@ func (rp *Issues) CloseIssue(w http.ResponseWriter, r *http.Request) { db.FilterEq("id", issue.Id), ) if err != nil { - log.Println("failed to close issue", err) + l.Error("failed to close issue", "err", err) rp.pages.Notice(w, "issue-action", "Failed to close issue. Try again later.") return } @@ -307,7 +306,7 @@ func (rp *Issues) CloseIssue(w http.ResponseWriter, r *http.Request) { rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId)) return } else { - log.Println("user is not permitted to close issue") + l.Error("user is not permitted to close issue") http.Error(w, "for biden", http.StatusUnauthorized) return } @@ -318,7 +317,7 @@ func (rp *Issues) ReopenIssue(w http.ResponseWriter, r *http.Request) { user := rp.oauth.GetUser(r) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -331,7 +330,7 @@ func (rp *Issues) ReopenIssue(w http.ResponseWriter, r *http.Request) { collaborators, err := f.Collaborators(r.Context()) if err != nil { - log.Println("failed to fetch repo collaborators: %w", err) + l.Error("failed to fetch repo collaborators", "err", err) } isCollaborator := slices.ContainsFunc(collaborators, func(collab pages.Collaborator) bool { return user.Did == collab.Did @@ -344,14 +343,14 @@ func (rp *Issues) ReopenIssue(w http.ResponseWriter, r *http.Request) { db.FilterEq("id", issue.Id), ) if err != nil { - log.Println("failed to reopen issue", err) + l.Error("failed to reopen issue", "err", err) rp.pages.Notice(w, "issue-action", "Failed to reopen issue. Try again later.") return } rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId)) return } else { - log.Println("user is not the owner of the repo") + l.Error("user is not the owner of the repo") http.Error(w, "forbidden", http.StatusUnauthorized) return } @@ -538,7 +537,7 @@ func (rp *Issues) EditIssueComment(w http.ResponseWriter, r *http.Request) { newBody := r.FormValue("body") client, err := rp.oauth.AuthorizedClient(r) if err != nil { - log.Println("failed to get authorized client", err) + l.Error("failed to get authorized client", "err", err) rp.pages.Notice(w, "issue-comment", "Failed to create comment.") return } @@ -551,7 +550,7 @@ func (rp *Issues) EditIssueComment(w http.ResponseWriter, r *http.Request) { _, err = db.AddIssueComment(rp.db, newComment) if err != nil { - log.Println("failed to perferom update-description query", err) + l.Error("failed to perferom update-description query", "err", err) rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.") return } @@ -561,7 +560,7 @@ func (rp *Issues) EditIssueComment(w http.ResponseWriter, r *http.Request) { // update the record on pds ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueCommentNSID, user.Did, comment.Rkey) if err != nil { - log.Println("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey) + l.Error("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey) rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "Failed to update description, no record found on PDS.") return } @@ -729,7 +728,7 @@ func (rp *Issues) DeleteIssueComment(w http.ResponseWriter, r *http.Request) { if comment.Rkey != "" { client, err := rp.oauth.AuthorizedClient(r) if err != nil { - log.Println("failed to get authorized client", err) + l.Error("failed to get authorized client", "err", err) rp.pages.Notice(w, "issue-comment", "Failed to delete comment.") return } @@ -739,7 +738,7 @@ func (rp *Issues) DeleteIssueComment(w http.ResponseWriter, r *http.Request) { Rkey: comment.Rkey, }) if err != nil { - log.Println(err) + l.Error("failed to delete from PDS", "err", err) } } @@ -757,6 +756,8 @@ func (rp *Issues) DeleteIssueComment(w http.ResponseWriter, r *http.Request) { } func (rp *Issues) RepoIssues(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoIssues") + params := r.URL.Query() state := params.Get("state") isOpen := true @@ -771,14 +772,14 @@ func (rp *Issues) RepoIssues(w http.ResponseWriter, r *http.Request) { page, ok := r.Context().Value("page").(pagination.Page) if !ok { - log.Println("failed to get page") + l.Error("failed to get page") page = pagination.FirstPage() } user := rp.oauth.GetUser(r) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -793,7 +794,7 @@ func (rp *Issues) RepoIssues(w http.ResponseWriter, r *http.Request) { db.FilterEq("open", openVal), ) if err != nil { - log.Println("failed to get issues", err) + l.Error("failed to get issues", "err", err) rp.pages.Notice(w, "issues", "Failed to load issues. Try again later.") return } @@ -804,7 +805,7 @@ func (rp *Issues) RepoIssues(w http.ResponseWriter, r *http.Request) { db.FilterContains("scope", tangled.RepoIssueNSID), ) if err != nil { - log.Println("failed to fetch labels", err) + l.Error("failed to fetch labels", "err", err) rp.pages.Error503(w) return } @@ -901,13 +902,13 @@ func (rp *Issues) NewIssue(w http.ResponseWriter, r *http.Request) { err = db.PutIssue(tx, issue) if err != nil { - log.Println("failed to create issue", err) + l.Error("failed to create issue", "err", err) rp.pages.Notice(w, "issues", "Failed to create issue.") return } if err = tx.Commit(); err != nil { - log.Println("failed to create issue", err) + l.Error("failed to create issue", "err", err) rp.pages.Notice(w, "issues", "Failed to create issue.") return } diff --git a/appview/labels/labels.go b/appview/labels/labels.go index f1384032..2e5819e5 100644 --- a/appview/labels/labels.go +++ b/appview/labels/labels.go @@ -16,7 +16,6 @@ import ( "tangled.org/core/appview/oauth" "tangled.org/core/appview/pages" "tangled.org/core/appview/validator" - "tangled.org/core/log" "tangled.org/core/rbac" "tangled.org/core/tid" @@ -42,9 +41,8 @@ func New( db *db.DB, validator *validator.Validator, enforcer *rbac.Enforcer, + logger *slog.Logger, ) *Labels { - logger := log.New("labels") - return &Labels{ oauth: oauth, pages: pages, diff --git a/appview/notifications/notifications.go b/appview/notifications/notifications.go index 5cda8e39..01ff59af 100644 --- a/appview/notifications/notifications.go +++ b/appview/notifications/notifications.go @@ -1,7 +1,7 @@ package notifications import ( - "log" + "log/slog" "net/http" "strconv" @@ -14,16 +14,18 @@ import ( ) type Notifications struct { - db *db.DB - oauth *oauth.OAuth - pages *pages.Pages + db *db.DB + oauth *oauth.OAuth + pages *pages.Pages + logger *slog.Logger } -func New(database *db.DB, oauthHandler *oauth.OAuth, pagesHandler *pages.Pages) *Notifications { +func New(database *db.DB, oauthHandler *oauth.OAuth, pagesHandler *pages.Pages, logger *slog.Logger) *Notifications { return &Notifications{ - db: database, - oauth: oauthHandler, - pages: pagesHandler, + db: database, + oauth: oauthHandler, + pages: pagesHandler, + logger: logger, } } @@ -44,11 +46,12 @@ func (n *Notifications) Router(mw *middleware.Middleware) http.Handler { } func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request) { + l := n.logger.With("handler", "notificationsPage") user := n.oauth.GetUser(r) page, ok := r.Context().Value("page").(pagination.Page) if !ok { - log.Println("failed to get page") + l.Error("failed to get page") page = pagination.FirstPage() } @@ -57,7 +60,7 @@ func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request db.FilterEq("recipient_did", user.Did), ) if err != nil { - log.Println("failed to get total notifications:", err) + l.Error("failed to get total notifications", "err", err) n.pages.Error500(w) return } @@ -68,14 +71,14 @@ func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request db.FilterEq("recipient_did", user.Did), ) if err != nil { - log.Println("failed to get notifications:", err) + l.Error("failed to get notifications", "err", err) n.pages.Error500(w) return } err = n.db.MarkAllNotificationsRead(r.Context(), user.Did) if err != nil { - log.Println("failed to mark notifications as read:", err) + l.Error("failed to mark notifications as read", "err", err) } unreadCount := 0 diff --git a/appview/pages/pages.go b/appview/pages/pages.go index ad3b248b..296d797d 100644 --- a/appview/pages/pages.go +++ b/appview/pages/pages.go @@ -54,7 +54,7 @@ type Pages struct { logger *slog.Logger } -func NewPages(config *config.Config, res *idresolver.Resolver) *Pages { +func NewPages(config *config.Config, res *idresolver.Resolver, logger *slog.Logger) *Pages { // initialized with safe defaults, can be overriden per use rctx := &markup.RenderContext{ IsDev: config.Core.Dev, @@ -72,7 +72,7 @@ func NewPages(config *config.Config, res *idresolver.Resolver) *Pages { rctx: rctx, resolver: res, templateDir: "appview/pages", - logger: slog.Default().With("component", "pages"), + logger: logger, } if p.dev { diff --git a/appview/pipelines/pipelines.go b/appview/pipelines/pipelines.go index 619087c4..397c6631 100644 --- a/appview/pipelines/pipelines.go +++ b/appview/pipelines/pipelines.go @@ -16,7 +16,6 @@ import ( "tangled.org/core/appview/reporesolver" "tangled.org/core/eventconsumer" "tangled.org/core/idresolver" - "tangled.org/core/log" "tangled.org/core/rbac" spindlemodel "tangled.org/core/spindle/models" @@ -45,9 +44,8 @@ func New( db *db.DB, config *config.Config, enforcer *rbac.Enforcer, + logger *slog.Logger, ) *Pipelines { - logger := log.New("pipelines") - return &Pipelines{ oauth: oauth, repoResolver: repoResolver, diff --git a/appview/pulls/pulls.go b/appview/pulls/pulls.go index bf0da184..f3a15b96 100644 --- a/appview/pulls/pulls.go +++ b/appview/pulls/pulls.go @@ -6,6 +6,7 @@ import ( "errors" "fmt" "log" + "log/slog" "net/http" "slices" "sort" @@ -46,6 +47,7 @@ type Pulls struct { config *config.Config notifier notify.Notifier enforcer *rbac.Enforcer + logger *slog.Logger } func New( @@ -57,6 +59,7 @@ func New( config *config.Config, notifier notify.Notifier, enforcer *rbac.Enforcer, + logger *slog.Logger, ) *Pulls { return &Pulls{ oauth: oauth, @@ -67,6 +70,7 @@ func New( config: config, notifier: notifier, enforcer: enforcer, + logger: logger, } } diff --git a/appview/repo/index.go b/appview/repo/index.go index 179f3646..3e3865cd 100644 --- a/appview/repo/index.go +++ b/appview/repo/index.go @@ -3,7 +3,7 @@ package repo import ( "errors" "fmt" - "log" + "log/slog" "net/http" "net/url" "slices" @@ -31,12 +31,14 @@ import ( ) func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoIndex") + ref := chi.URLParam(r, "ref") ref, _ = url.PathUnescape(ref) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to fully resolve repo", err) + l.Error("failed to fully resolve repo", "err", err) return } @@ -56,7 +58,7 @@ func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { result, err := rp.buildIndexResponse(r.Context(), xrpcc, f, ref) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { if errors.Is(xrpcerr, xrpcclient.ErrXrpcUnsupported) { - log.Println("failed to call XRPC repo.index", err) + l.Error("failed to call XRPC repo.index", "err", err) rp.pages.RepoIndexPage(w, pages.RepoIndexParams{ LoggedInUser: user, NeedsKnotUpgrade: true, @@ -66,7 +68,7 @@ func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { } rp.pages.Error503(w) - log.Println("failed to build index response", err) + l.Error("failed to build index response", "err", err) return } @@ -119,18 +121,18 @@ func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { emails := uniqueEmails(commitsTrunc) emailToDidMap, err := db.GetEmailToDid(rp.db, emails, true) if err != nil { - log.Println("failed to get email to did map", err) + l.Error("failed to get email to did map", "err", err) } vc, err := commitverify.GetVerifiedObjectCommits(rp.db, emailToDidMap, commitsTrunc) if err != nil { - log.Println(err) + l.Error("failed to GetVerifiedObjectCommits", "err", err) } // TODO: a bit dirty - languageInfo, err := rp.getLanguageInfo(r.Context(), f, xrpcc, result.Ref, ref == "") + languageInfo, err := rp.getLanguageInfo(r.Context(), l, f, xrpcc, result.Ref, ref == "") if err != nil { - log.Printf("failed to compute language percentages: %s", err) + l.Warn("failed to compute language percentages", "err", err) // non-fatal } @@ -140,7 +142,7 @@ func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { } pipelines, err := getPipelineStatuses(rp.db, repoInfo, shas) if err != nil { - log.Printf("failed to fetch pipeline statuses: %s", err) + l.Error("failed to fetch pipeline statuses", "err", err) // non-fatal } @@ -162,6 +164,7 @@ func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { func (rp *Repo) getLanguageInfo( ctx context.Context, + l *slog.Logger, f *reporesolver.ResolvedRepo, xrpcc *indigoxrpc.Client, currentRef string, @@ -180,7 +183,7 @@ func (rp *Repo) getLanguageInfo( ls, err := tangled.RepoLanguages(ctx, xrpcc, currentRef, repo) if err != nil { if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.languages", xrpcerr) + l.Error("failed to call XRPC repo.languages", "err", xrpcerr) return nil, xrpcerr } return nil, err @@ -210,7 +213,7 @@ func (rp *Repo) getLanguageInfo( err = db.UpdateRepoLanguages(tx, f.RepoAt(), currentRef, langs) if err != nil { // non-fatal - log.Println("failed to cache lang results", err) + l.Error("failed to cache lang results", "err", err) } err = tx.Commit() diff --git a/appview/repo/repo.go b/appview/repo/repo.go index e8cc75d7..0174d151 100644 --- a/appview/repo/repo.go +++ b/appview/repo/repo.go @@ -7,7 +7,6 @@ import ( "errors" "fmt" "io" - "log" "log/slog" "net/http" "net/url" @@ -90,12 +89,14 @@ func New( } func (rp *Repo) DownloadArchive(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "DownloadArchive") + ref := chi.URLParam(r, "ref") ref, _ = url.PathUnescape(ref) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -111,7 +112,7 @@ func (rp *Repo) DownloadArchive(w http.ResponseWriter, r *http.Request) { repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) archiveBytes, err := tangled.RepoArchive(r.Context(), xrpcc, "tar.gz", "", ref, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.archive", xrpcerr) + l.Error("failed to call XRPC repo.archive", "err", xrpcerr) rp.pages.Error503(w) return } @@ -128,9 +129,11 @@ func (rp *Repo) DownloadArchive(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) RepoLog(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoLog") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to fully resolve repo", err) + l.Error("failed to fully resolve repo", "err", err) return } @@ -165,21 +168,21 @@ func (rp *Repo) RepoLog(w http.ResponseWriter, r *http.Request) { repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) xrpcBytes, err := tangled.RepoLog(r.Context(), xrpcc, cursor, limit, "", ref, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.log", xrpcerr) + l.Error("failed to call XRPC repo.log", "err", xrpcerr) rp.pages.Error503(w) return } var xrpcResp types.RepoLogResponse if err := json.Unmarshal(xrpcBytes, &xrpcResp); err != nil { - log.Println("failed to decode XRPC response", err) + l.Error("failed to decode XRPC response", "err", err) rp.pages.Error503(w) return } tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.tags", xrpcerr) + l.Error("failed to call XRPC repo.tags", "err", xrpcerr) rp.pages.Error503(w) return } @@ -196,7 +199,7 @@ func (rp *Repo) RepoLog(w http.ResponseWriter, r *http.Request) { branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.branches", xrpcerr) + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) rp.pages.Error503(w) return } @@ -214,12 +217,12 @@ func (rp *Repo) RepoLog(w http.ResponseWriter, r *http.Request) { emailToDidMap, err := db.GetEmailToDid(rp.db, uniqueEmails(xrpcResp.Commits), true) if err != nil { - log.Println("failed to fetch email to did mapping", err) + l.Error("failed to fetch email to did mapping", "err", err) } vc, err := commitverify.GetVerifiedObjectCommits(rp.db, emailToDidMap, xrpcResp.Commits) if err != nil { - log.Println(err) + l.Error("failed to GetVerifiedObjectCommits", "err", err) } repoInfo := f.RepoInfo(user) @@ -230,7 +233,7 @@ func (rp *Repo) RepoLog(w http.ResponseWriter, r *http.Request) { } pipelines, err := getPipelineStatuses(rp.db, repoInfo, shas) if err != nil { - log.Println(err) + l.Error("failed to getPipelineStatuses", "err", err) // non-fatal } @@ -246,9 +249,11 @@ func (rp *Repo) RepoLog(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) RepoDescriptionEdit(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoDescriptionEdit") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) w.WriteHeader(http.StatusBadRequest) return } @@ -260,9 +265,11 @@ func (rp *Repo) RepoDescriptionEdit(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) RepoDescription(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoDescription") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) w.WriteHeader(http.StatusBadRequest) return } @@ -270,7 +277,7 @@ func (rp *Repo) RepoDescription(w http.ResponseWriter, r *http.Request) { repoAt := f.RepoAt() rkey := repoAt.RecordKey().String() if rkey == "" { - log.Println("invalid aturi for repo", err) + l.Error("invalid aturi for repo", "err", err) w.WriteHeader(http.StatusInternalServerError) return } @@ -287,7 +294,7 @@ func (rp *Repo) RepoDescription(w http.ResponseWriter, r *http.Request) { newDescription := r.FormValue("description") client, err := rp.oauth.AuthorizedClient(r) if err != nil { - log.Println("failed to get client") + l.Error("failed to get client") rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.") return } @@ -295,7 +302,7 @@ func (rp *Repo) RepoDescription(w http.ResponseWriter, r *http.Request) { // optimistic update err = db.UpdateDescription(rp.db, string(repoAt), newDescription) if err != nil { - log.Println("failed to perferom update-description query", err) + l.Error("failed to perform update-description query", "err", err) rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.") return } @@ -324,7 +331,7 @@ func (rp *Repo) RepoDescription(w http.ResponseWriter, r *http.Request) { }) if err != nil { - log.Println("failed to perferom update-description query", err) + l.Error("failed to perferom update-description query", "err", err) // failed to get record rp.pages.Notice(w, "repo-notice", "Failed to update description, unable to save to PDS.") return @@ -341,9 +348,11 @@ func (rp *Repo) RepoDescription(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) RepoCommit(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoCommit") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to fully resolve repo", err) + l.Error("failed to fully resolve repo", "err", err) return } ref := chi.URLParam(r, "ref") @@ -371,33 +380,33 @@ func (rp *Repo) RepoCommit(w http.ResponseWriter, r *http.Request) { repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) xrpcBytes, err := tangled.RepoDiff(r.Context(), xrpcc, ref, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.diff", xrpcerr) + l.Error("failed to call XRPC repo.diff", "err", xrpcerr) rp.pages.Error503(w) return } var result types.RepoCommitResponse if err := json.Unmarshal(xrpcBytes, &result); err != nil { - log.Println("failed to decode XRPC response", err) + l.Error("failed to decode XRPC response", "err", err) rp.pages.Error503(w) return } emailToDidMap, err := db.GetEmailToDid(rp.db, []string{result.Diff.Commit.Committer.Email, result.Diff.Commit.Author.Email}, true) if err != nil { - log.Println("failed to get email to did mapping:", err) + l.Error("failed to get email to did mapping", "err", err) } vc, err := commitverify.GetVerifiedCommits(rp.db, emailToDidMap, []types.NiceDiff{*result.Diff}) if err != nil { - log.Println(err) + l.Error("failed to GetVerifiedCommits", "err", err) } user := rp.oauth.GetUser(r) repoInfo := f.RepoInfo(user) pipelines, err := getPipelineStatuses(rp.db, repoInfo, []string{result.Diff.Commit.This}) if err != nil { - log.Println(err) + l.Error("failed to getPipelineStatuses", "err", err) // non-fatal } var pipeline *models.Pipeline @@ -417,9 +426,11 @@ func (rp *Repo) RepoCommit(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) RepoTree(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoTree") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to fully resolve repo", err) + l.Error("failed to fully resolve repo", "err", err) return } @@ -444,7 +455,7 @@ func (rp *Repo) RepoTree(w http.ResponseWriter, r *http.Request) { repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) xrpcResp, err := tangled.RepoTree(r.Context(), xrpcc, treePath, ref, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.tree", xrpcerr) + l.Error("failed to call XRPC repo.tree", "err", xrpcerr) rp.pages.Error503(w) return } @@ -519,9 +530,11 @@ func (rp *Repo) RepoTree(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) RepoTags(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoTags") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -537,21 +550,21 @@ func (rp *Repo) RepoTags(w http.ResponseWriter, r *http.Request) { repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) xrpcBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.tags", xrpcerr) + l.Error("failed to call XRPC repo.tags", "err", xrpcerr) rp.pages.Error503(w) return } var result types.RepoTagsResponse if err := json.Unmarshal(xrpcBytes, &result); err != nil { - log.Println("failed to decode XRPC response", err) + l.Error("failed to decode XRPC response", "err", err) rp.pages.Error503(w) return } artifacts, err := db.GetArtifact(rp.db, db.FilterEq("repo_at", f.RepoAt())) if err != nil { - log.Println("failed grab artifacts", err) + l.Error("failed grab artifacts", "err", err) return } @@ -588,9 +601,11 @@ func (rp *Repo) RepoTags(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) RepoBranches(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoBranches") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -606,14 +621,14 @@ func (rp *Repo) RepoBranches(w http.ResponseWriter, r *http.Request) { repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.branches", xrpcerr) + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) rp.pages.Error503(w) return } var result types.RepoBranchesResponse if err := json.Unmarshal(xrpcBytes, &result); err != nil { - log.Println("failed to decode XRPC response", err) + l.Error("failed to decode XRPC response", "err", err) rp.pages.Error503(w) return } @@ -629,15 +644,17 @@ func (rp *Repo) RepoBranches(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) DeleteBranch(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "DeleteBranch") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } noticeId := "delete-branch-error" fail := func(msg string, err error) { - log.Println(msg, "err", err) + l.Error(msg, "err", err) rp.pages.Notice(w, noticeId, msg) } @@ -670,15 +687,17 @@ func (rp *Repo) DeleteBranch(w http.ResponseWriter, r *http.Request) { fail(fmt.Sprintf("Failed to delete branch: %s", err), err) return } - log.Println("deleted branch from knot", "branch", branch, "repo", f.RepoAt()) + l.Error("deleted branch from knot", "branch", branch, "repo", f.RepoAt()) rp.pages.HxRefresh(w) } func (rp *Repo) RepoBlob(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoBlob") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -700,7 +719,7 @@ func (rp *Repo) RepoBlob(w http.ResponseWriter, r *http.Request) { repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Repo.Name) resp, err := tangled.RepoBlob(r.Context(), xrpcc, filePath, false, ref, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.blob", xrpcerr) + l.Error("failed to call XRPC repo.blob", "err", xrpcerr) rp.pages.Error503(w) return } @@ -800,9 +819,11 @@ func (rp *Repo) RepoBlob(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) RepoBlobRaw(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoBlobRaw") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", err) w.WriteHeader(http.StatusBadRequest) return } @@ -834,7 +855,7 @@ func (rp *Repo) RepoBlobRaw(w http.ResponseWriter, r *http.Request) { req, err := http.NewRequest("GET", blobURL, nil) if err != nil { - log.Println("failed to create request", err) + l.Error("failed to create request", "err", err) return } @@ -846,7 +867,7 @@ func (rp *Repo) RepoBlobRaw(w http.ResponseWriter, r *http.Request) { client := &http.Client{} resp, err := client.Do(req) if err != nil { - log.Println("failed to reach knotserver", err) + l.Error("failed to reach knotserver", "err", err) rp.pages.Error503(w) return } @@ -859,7 +880,7 @@ func (rp *Repo) RepoBlobRaw(w http.ResponseWriter, r *http.Request) { } if resp.StatusCode != http.StatusOK { - log.Printf("knotserver returned non-OK status for raw blob %s: %d", blobURL, resp.StatusCode) + l.Error("knotserver returned non-OK status for raw blob", "url", blobURL, "statuscode", resp.StatusCode) w.WriteHeader(resp.StatusCode) _, _ = io.Copy(w, resp.Body) return @@ -868,7 +889,7 @@ func (rp *Repo) RepoBlobRaw(w http.ResponseWriter, r *http.Request) { contentType := resp.Header.Get("Content-Type") body, err := io.ReadAll(resp.Body) if err != nil { - log.Printf("error reading response body from knotserver: %v", err) + l.Error("error reading response body from knotserver", "err", err) w.WriteHeader(http.StatusInternalServerError) return } @@ -1443,7 +1464,7 @@ func (rp *Repo) LabelPanel(w http.ResponseWriter, r *http.Request) { db.FilterContains("scope", subject.Collection().String()), ) if err != nil { - log.Println("failed to fetch label defs", err) + l.Error("failed to fetch label defs", "err", err) return } @@ -1454,7 +1475,7 @@ func (rp *Repo) LabelPanel(w http.ResponseWriter, r *http.Request) { states, err := db.GetLabels(rp.db, db.FilterEq("subject", subject)) if err != nil { - log.Println("failed to build label state", err) + l.Error("failed to build label state", "err", err) return } state := states[subject] @@ -1491,7 +1512,7 @@ func (rp *Repo) EditLabelPanel(w http.ResponseWriter, r *http.Request) { db.FilterContains("scope", subject.Collection().String()), ) if err != nil { - log.Println("failed to fetch labels", err) + l.Error("failed to fetch labels", "err", err) return } @@ -1502,7 +1523,7 @@ func (rp *Repo) EditLabelPanel(w http.ResponseWriter, r *http.Request) { states, err := db.GetLabels(rp.db, db.FilterEq("subject", subject)) if err != nil { - log.Println("failed to build label state", err) + l.Error("failed to build label state", "err", err) return } state := states[subject] @@ -1649,18 +1670,19 @@ func (rp *Repo) AddCollaborator(w http.ResponseWriter, r *http.Request) { func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) { user := rp.oauth.GetUser(r) + l := rp.logger.With("handler", "DeleteRepo") noticeId := "operation-error" f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } // remove record from pds atpClient, err := rp.oauth.AuthorizedClient(r) if err != nil { - log.Println("failed to get authorized client", err) + l.Error("failed to get authorized client", "err", err) return } _, err = comatproto.RepoDeleteRecord(r.Context(), atpClient, &comatproto.RepoDeleteRecord_Input{ @@ -1669,11 +1691,11 @@ func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) { Rkey: f.Rkey, }) if err != nil { - log.Printf("failed to delete record: %s", err) + l.Error("failed to delete record", "err", err) rp.pages.Notice(w, noticeId, "Failed to delete repository from PDS.") return } - log.Println("removed repo record ", f.RepoAt().String()) + l.Info("removed repo record", "aturi", f.RepoAt().String()) client, err := rp.oauth.ServiceClient( r, @@ -1682,7 +1704,7 @@ func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) { oauth.WithDev(rp.config.Core.Dev), ) if err != nil { - log.Println("failed to connect to knot server:", err) + l.Error("failed to connect to knot server", "err", err) return } @@ -1699,11 +1721,11 @@ func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) { rp.pages.Notice(w, noticeId, err.Error()) return } - log.Println("deleted repo from knot") + l.Info("deleted repo from knot") tx, err := rp.db.BeginTx(r.Context(), nil) if err != nil { - log.Println("failed to start tx") + l.Error("failed to start tx") w.Write(fmt.Append(nil, "failed to add collaborator: ", err)) return } @@ -1711,7 +1733,7 @@ func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) { tx.Rollback() err = rp.enforcer.E.LoadPolicy() if err != nil { - log.Println("failed to rollback policies") + l.Error("failed to rollback policies") } }() @@ -1725,7 +1747,7 @@ func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) { did := c[0] rp.enforcer.RemoveCollaborator(did, f.Knot, f.DidSlashRepo()) } - log.Println("removed collaborators") + l.Info("removed collaborators") // remove repo RBAC err = rp.enforcer.RemoveRepo(f.OwnerDid(), f.Knot, f.DidSlashRepo()) @@ -1740,18 +1762,18 @@ func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) { rp.pages.Notice(w, noticeId, "Failed to update appview") return } - log.Println("removed repo from db") + l.Info("removed repo from db") err = tx.Commit() if err != nil { - log.Println("failed to commit changes", err) + l.Error("failed to commit changes", "err", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } err = rp.enforcer.E.SavePolicy() if err != nil { - log.Println("failed to update ACLs", err) + l.Error("failed to update ACLs", "err", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -1760,9 +1782,11 @@ func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) SetDefaultBranch(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "SetDefaultBranch") + f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -1780,7 +1804,7 @@ func (rp *Repo) SetDefaultBranch(w http.ResponseWriter, r *http.Request) { oauth.WithDev(rp.config.Core.Dev), ) if err != nil { - log.Println("failed to connect to knot server:", err) + l.Error("failed to connect to knot server", "err", err) rp.pages.Notice(w, noticeId, "Failed to connect to knot server.") return } @@ -1794,7 +1818,7 @@ func (rp *Repo) SetDefaultBranch(w http.ResponseWriter, r *http.Request) { }, ) if err := xrpcclient.HandleXrpcErr(xe); err != nil { - log.Println("xrpc failed", "err", xe) + l.Error("xrpc failed", "err", xe) rp.pages.Notice(w, noticeId, err.Error()) return } @@ -1809,12 +1833,12 @@ func (rp *Repo) Secrets(w http.ResponseWriter, r *http.Request) { f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } if f.Spindle == "" { - log.Println("empty spindle cannot add/rm secret", err) + l.Error("empty spindle cannot add/rm secret", "err", err) return } @@ -1831,7 +1855,7 @@ func (rp *Repo) Secrets(w http.ResponseWriter, r *http.Request) { oauth.WithDev(rp.config.Core.Dev), ) if err != nil { - log.Println("failed to create spindle client", err) + l.Error("failed to create spindle client", "err", err) return } @@ -1917,6 +1941,8 @@ func (rp *Repo) RepoSettings(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) generalSettings(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "generalSettings") + f, err := rp.repoResolver.Resolve(r) user := rp.oauth.GetUser(r) @@ -1932,28 +1958,28 @@ func (rp *Repo) generalSettings(w http.ResponseWriter, r *http.Request) { repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.branches", xrpcerr) + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) rp.pages.Error503(w) return } var result types.RepoBranchesResponse if err := json.Unmarshal(xrpcBytes, &result); err != nil { - log.Println("failed to decode XRPC response", err) + l.Error("failed to decode XRPC response", "err", err) rp.pages.Error503(w) return } defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", models.DefaultLabelDefs())) if err != nil { - log.Println("failed to fetch labels", err) + l.Error("failed to fetch labels", "err", err) rp.pages.Error503(w) return } labels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", f.Repo.Labels)) if err != nil { - log.Println("failed to fetch labels", err) + l.Error("failed to fetch labels", "err", err) rp.pages.Error503(w) return } @@ -2001,12 +2027,14 @@ func (rp *Repo) generalSettings(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) accessSettings(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "accessSettings") + f, err := rp.repoResolver.Resolve(r) user := rp.oauth.GetUser(r) repoCollaborators, err := f.Collaborators(r.Context()) if err != nil { - log.Println("failed to get collaborators", err) + l.Error("failed to get collaborators", "err", err) } rp.pages.RepoAccessSettings(w, pages.RepoAccessSettingsParams{ @@ -2019,13 +2047,15 @@ func (rp *Repo) accessSettings(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) pipelineSettings(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "pipelineSettings") + f, err := rp.repoResolver.Resolve(r) user := rp.oauth.GetUser(r) // all spindles that the repo owner is a member of spindles, err := rp.enforcer.GetSpindlesForUser(f.OwnerDid()) if err != nil { - log.Println("failed to fetch spindles", err) + l.Error("failed to fetch spindles", "err", err) return } @@ -2038,9 +2068,9 @@ func (rp *Repo) pipelineSettings(w http.ResponseWriter, r *http.Request) { oauth.WithExp(60), oauth.WithDev(rp.config.Core.Dev), ); err != nil { - log.Println("failed to create spindle client", err) + l.Error("failed to create spindle client", "err", err) } else if resp, err := tangled.RepoListSecrets(r.Context(), spindleClient, f.RepoAt().String()); err != nil { - log.Println("failed to fetch secrets", err) + l.Error("failed to fetch secrets", "err", err) } else { secrets = resp.Secrets } @@ -2080,13 +2110,15 @@ func (rp *Repo) pipelineSettings(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) SyncRepoFork(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "SyncRepoFork") + ref := chi.URLParam(r, "ref") ref, _ = url.PathUnescape(ref) user := rp.oauth.GetUser(r) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Printf("failed to resolve source repo: %v", err) + l.Error("failed to resolve source repo", "err", err) return } @@ -2130,10 +2162,12 @@ func (rp *Repo) SyncRepoFork(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) ForkRepo(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "ForkRepo") + user := rp.oauth.GetUser(r) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Printf("failed to resolve source repo: %v", err) + l.Error("failed to resolve source repo", "err", err) return } @@ -2184,7 +2218,7 @@ func (rp *Repo) ForkRepo(w http.ResponseWriter, r *http.Request) { ) if err != nil { if !errors.Is(err, sql.ErrNoRows) { - log.Println("error fetching existing repo from db", "err", err) + l.Error("error fetching existing repo from db", "err", err) rp.pages.Notice(w, "repo", "Failed to fork this repository. Try again later.") return } @@ -2299,7 +2333,7 @@ func (rp *Repo) ForkRepo(w http.ResponseWriter, r *http.Request) { err = db.AddRepo(tx, repo) if err != nil { - log.Println(err) + l.Error("failed to AddRepo", "err", err) rp.pages.Notice(w, "repo", "Failed to save repository information.") return } @@ -2308,21 +2342,21 @@ func (rp *Repo) ForkRepo(w http.ResponseWriter, r *http.Request) { p, _ := securejoin.SecureJoin(user.Did, forkName) err = rp.enforcer.AddRepo(user.Did, targetKnot, p) if err != nil { - log.Println(err) + l.Error("failed to add ACLs", "err", err) rp.pages.Notice(w, "repo", "Failed to set up repository permissions.") return } err = tx.Commit() if err != nil { - log.Println("failed to commit changes", err) + l.Error("failed to commit changes", "err", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } err = rp.enforcer.E.SavePolicy() if err != nil { - log.Println("failed to update ACLs", err) + l.Error("failed to update ACLs", "err", err) http.Error(w, err.Error(), http.StatusInternalServerError) return } @@ -2358,10 +2392,12 @@ func rollbackRecord(ctx context.Context, aturi string, client *atpclient.APIClie } func (rp *Repo) RepoCompareNew(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoCompareNew") + user := rp.oauth.GetUser(r) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -2377,14 +2413,14 @@ func (rp *Repo) RepoCompareNew(w http.ResponseWriter, r *http.Request) { repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.branches", xrpcerr) + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) rp.pages.Error503(w) return } var branchResult types.RepoBranchesResponse if err := json.Unmarshal(branchBytes, &branchResult); err != nil { - log.Println("failed to decode XRPC branches response", err) + l.Error("failed to decode XRPC branches response", "err", err) rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") return } @@ -2414,14 +2450,14 @@ func (rp *Repo) RepoCompareNew(w http.ResponseWriter, r *http.Request) { tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.tags", xrpcerr) + l.Error("failed to call XRPC repo.tags", "err", xrpcerr) rp.pages.Error503(w) return } var tags types.RepoTagsResponse if err := json.Unmarshal(tagBytes, &tags); err != nil { - log.Println("failed to decode XRPC tags response", err) + l.Error("failed to decode XRPC tags response", "err", err) rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") return } @@ -2439,10 +2475,12 @@ func (rp *Repo) RepoCompareNew(w http.ResponseWriter, r *http.Request) { } func (rp *Repo) RepoCompare(w http.ResponseWriter, r *http.Request) { + l := rp.logger.With("handler", "RepoCompare") + user := rp.oauth.GetUser(r) f, err := rp.repoResolver.Resolve(r) if err != nil { - log.Println("failed to get repo and knot", err) + l.Error("failed to get repo and knot", "err", err) return } @@ -2469,7 +2507,7 @@ func (rp *Repo) RepoCompare(w http.ResponseWriter, r *http.Request) { head, _ = url.PathUnescape(head) if base == "" || head == "" { - log.Printf("invalid comparison") + l.Error("invalid comparison") rp.pages.Error404(w) return } @@ -2487,42 +2525,42 @@ func (rp *Repo) RepoCompare(w http.ResponseWriter, r *http.Request) { branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.branches", xrpcerr) + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) rp.pages.Error503(w) return } var branches types.RepoBranchesResponse if err := json.Unmarshal(branchBytes, &branches); err != nil { - log.Println("failed to decode XRPC branches response", err) + l.Error("failed to decode XRPC branches response", "err", err) rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") return } tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.tags", xrpcerr) + l.Error("failed to call XRPC repo.tags", "err", xrpcerr) rp.pages.Error503(w) return } var tags types.RepoTagsResponse if err := json.Unmarshal(tagBytes, &tags); err != nil { - log.Println("failed to decode XRPC tags response", err) + l.Error("failed to decode XRPC tags response", "err", err) rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") return } compareBytes, err := tangled.RepoCompare(r.Context(), xrpcc, repo, base, head) if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { - log.Println("failed to call XRPC repo.compare", xrpcerr) + l.Error("failed to call XRPC repo.compare", "err", xrpcerr) rp.pages.Error503(w) return } var formatPatch types.RepoFormatPatchResponse if err := json.Unmarshal(compareBytes, &formatPatch); err != nil { - log.Println("failed to decode XRPC compare response", err) + l.Error("failed to decode XRPC compare response", "err", err) rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") return } diff --git a/appview/signup/signup.go b/appview/signup/signup.go index 6c79cd26..c433c487 100644 --- a/appview/signup/signup.go +++ b/appview/signup/signup.go @@ -62,7 +62,7 @@ func loadDisallowedNicknames(filepath string, logger *slog.Logger) map[string]bo disallowed := make(map[string]bool) if filepath == "" { - logger.Debug("no disallowed nicknames file configured") + logger.Warn("no disallowed nicknames file configured") return disallowed } diff --git a/appview/state/knotstream.go b/appview/state/knotstream.go index 1bf48648..7a149184 100644 --- a/appview/state/knotstream.go +++ b/appview/state/knotstream.go @@ -25,6 +25,9 @@ import ( ) func Knotstream(ctx context.Context, c *config.Config, d *db.DB, enforcer *rbac.Enforcer, posthog posthog.Client) (*ec.Consumer, error) { + logger := log.FromContext(ctx) + logger = log.SubLogger(logger, "knotstream") + knots, err := db.GetRegistrations( d, db.FilterIsNot("registered", "null"), @@ -39,7 +42,6 @@ func Knotstream(ctx context.Context, c *config.Config, d *db.DB, enforcer *rbac. srcs[s] = struct{}{} } - logger := log.New("knotstream") cache := cache.New(c.Redis.Addr) cursorStore := cursor.NewRedisCursorStore(cache) diff --git a/appview/state/login.go b/appview/state/login.go index 2dd8191c..a476cfb3 100644 --- a/appview/state/login.go +++ b/appview/state/login.go @@ -2,7 +2,6 @@ package state import ( "fmt" - "log" "net/http" "strings" @@ -10,6 +9,8 @@ import ( ) func (s *State) Login(w http.ResponseWriter, r *http.Request) { + l := s.logger.With("handler", "Login") + switch r.Method { case http.MethodGet: returnURL := r.URL.Query().Get("return_url") @@ -32,7 +33,7 @@ func (s *State) Login(w http.ResponseWriter, r *http.Request) { // basic handle validation if !strings.Contains(handle, ".") { - log.Println("invalid handle format", "raw", handle) + l.Error("invalid handle format", "raw", handle) s.pages.Notice( w, "login-msg", @@ -52,11 +53,13 @@ func (s *State) Login(w http.ResponseWriter, r *http.Request) { } func (s *State) Logout(w http.ResponseWriter, r *http.Request) { + l := s.logger.With("handler", "Logout") + err := s.oauth.DeleteSession(w, r) if err != nil { - log.Println("failed to logout", "err", err) + l.Error("failed to logout", "err", err) } else { - log.Println("logged out successfully") + l.Info("logged out successfully") } s.pages.HxRedirect(w, "/login") diff --git a/appview/state/router.go b/appview/state/router.go index f0396fc9..ef44896d 100644 --- a/appview/state/router.go +++ b/appview/state/router.go @@ -205,7 +205,7 @@ func (s *State) SettingsRouter() http.Handler { } func (s *State) SpindlesRouter() http.Handler { - logger := log.New("spindles") + logger := log.SubLogger(s.logger, "spindles") spindles := &spindles.Spindles{ Db: s.db, @@ -221,7 +221,7 @@ func (s *State) SpindlesRouter() http.Handler { } func (s *State) KnotsRouter() http.Handler { - logger := log.New("knots") + logger := log.SubLogger(s.logger, "knots") knots := &knots.Knots{ Db: s.db, @@ -238,7 +238,7 @@ func (s *State) KnotsRouter() http.Handler { } func (s *State) StringsRouter(mw *middleware.Middleware) http.Handler { - logger := log.New("strings") + logger := log.SubLogger(s.logger, "strings") strs := &avstrings.Strings{ Db: s.db, @@ -253,39 +253,85 @@ func (s *State) StringsRouter(mw *middleware.Middleware) http.Handler { } func (s *State) IssuesRouter(mw *middleware.Middleware) http.Handler { - issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier, s.validator) + issues := issues.New( + s.oauth, + s.repoResolver, + s.pages, + s.idResolver, + s.db, + s.config, + s.notifier, + s.validator, + log.SubLogger(s.logger, "issues"), + ) return issues.Router(mw) } func (s *State) PullsRouter(mw *middleware.Middleware) http.Handler { - pulls := pulls.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier, s.enforcer) + pulls := pulls.New( + s.oauth, + s.repoResolver, + s.pages, + s.idResolver, + s.db, + s.config, + s.notifier, + s.enforcer, + log.SubLogger(s.logger, "pulls"), + ) return pulls.Router(mw) } func (s *State) RepoRouter(mw *middleware.Middleware) http.Handler { - logger := log.New("repo") - repo := repo.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.notifier, s.enforcer, logger, s.validator) + repo := repo.New( + s.oauth, + s.repoResolver, + s.pages, + s.spindlestream, + s.idResolver, + s.db, + s.config, + s.notifier, + s.enforcer, + log.SubLogger(s.logger, "repo"), + s.validator, + ) return repo.Router(mw) } func (s *State) PipelinesRouter(mw *middleware.Middleware) http.Handler { - pipes := pipelines.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.enforcer) + pipes := pipelines.New( + s.oauth, + s.repoResolver, + s.pages, + s.spindlestream, + s.idResolver, + s.db, + s.config, + s.enforcer, + log.SubLogger(s.logger, "pipelines"), + ) return pipes.Router(mw) } func (s *State) LabelsRouter(mw *middleware.Middleware) http.Handler { - ls := labels.New(s.oauth, s.pages, s.db, s.validator, s.enforcer) + ls := labels.New( + s.oauth, + s.pages, + s.db, + s.validator, + s.enforcer, + log.SubLogger(s.logger, "labels"), + ) return ls.Router(mw) } func (s *State) NotificationsRouter(mw *middleware.Middleware) http.Handler { - notifs := notifications.New(s.db, s.oauth, s.pages) + notifs := notifications.New(s.db, s.oauth, s.pages, log.SubLogger(s.logger, "notifications")) return notifs.Router(mw) } func (s *State) SignupRouter() http.Handler { - logger := log.New("signup") - - sig := signup.New(s.config, s.db, s.posthog, s.idResolver, s.pages, logger) + sig := signup.New(s.config, s.db, s.posthog, s.idResolver, s.pages, log.SubLogger(s.logger, "signup")) return sig.Router() } diff --git a/appview/state/spindlestream.go b/appview/state/spindlestream.go index 339c6ca9..994e2298 100644 --- a/appview/state/spindlestream.go +++ b/appview/state/spindlestream.go @@ -22,6 +22,9 @@ import ( ) func Spindlestream(ctx context.Context, c *config.Config, d *db.DB, enforcer *rbac.Enforcer) (*ec.Consumer, error) { + logger := log.FromContext(ctx) + logger = log.SubLogger(logger, "spindlestream") + spindles, err := db.GetSpindles( d, db.FilterIsNot("verified", "null"), @@ -36,7 +39,6 @@ func Spindlestream(ctx context.Context, c *config.Config, d *db.DB, enforcer *rb srcs[src] = struct{}{} } - logger := log.New("spindlestream") cache := cache.New(c.Redis.Addr) cursorStore := cursor.NewRedisCursorStore(cache) diff --git a/appview/state/state.go b/appview/state/state.go index ae911092..f7a9e5ac 100644 --- a/appview/state/state.go +++ b/appview/state/state.go @@ -5,7 +5,6 @@ import ( "database/sql" "errors" "fmt" - "log" "log/slog" "net/http" "strings" @@ -13,8 +12,6 @@ import ( "tangled.org/core/api/tangled" "tangled.org/core/appview" - "tangled.org/core/appview/cache" - "tangled.org/core/appview/cache/session" "tangled.org/core/appview/config" "tangled.org/core/appview/db" "tangled.org/core/appview/models" @@ -29,6 +26,7 @@ import ( "tangled.org/core/eventconsumer" "tangled.org/core/idresolver" "tangled.org/core/jetstream" + "tangled.org/core/log" tlog "tangled.org/core/log" "tangled.org/core/rbac" "tangled.org/core/tid" @@ -48,7 +46,6 @@ type State struct { oauth *oauth.OAuth enforcer *rbac.Enforcer pages *pages.Pages - sess *session.SessionStore idResolver *idresolver.Resolver posthog posthog.Client jc *jetstream.JetstreamClient @@ -61,7 +58,9 @@ type State struct { } func Make(ctx context.Context, config *config.Config) (*State, error) { - d, err := db.Make(config.Core.DbPath) + logger := tlog.FromContext(ctx) + + d, err := db.Make(ctx, config.Core.DbPath) if err != nil { return nil, fmt.Errorf("failed to create db: %w", err) } @@ -73,20 +72,20 @@ func Make(ctx context.Context, config *config.Config) (*State, error) { res, err := idresolver.RedisResolver(config.Redis.ToURL()) if err != nil { - log.Printf("failed to create redis resolver: %v", err) + logger.Error("failed to create redis resolver", "err", err) res = idresolver.DefaultResolver() } - pages := pages.NewPages(config, res) - cache := cache.New(config.Redis.Addr) - sess := session.New(cache) - oauth2, err := oauth.New(config) + pages := pages.NewPages(config, res, log.SubLogger(logger, "pages")) + oauth, err := oauth.New(config) if err != nil { return nil, fmt.Errorf("failed to start oauth handler: %w", err) } validator := validator.New(d, res, enforcer) - posthog, err := posthog.NewWithConfig(config.Posthog.ApiKey, posthog.Config{Endpoint: config.Posthog.Endpoint}) + posthog, err := posthog.NewWithConfig(config.Posthog.ApiKey, posthog.Config{ + Endpoint: config.Posthog.Endpoint, + }) if err != nil { return nil, fmt.Errorf("failed to create posthog client: %w", err) } @@ -112,7 +111,7 @@ func Make(ctx context.Context, config *config.Config) (*State, error) { tangled.LabelOpNSID, }, nil, - slog.Default(), + tlog.SubLogger(logger, "jetstream"), wrapper, false, @@ -133,7 +132,7 @@ func Make(ctx context.Context, config *config.Config) (*State, error) { Enforcer: enforcer, IdResolver: res, Config: config, - Logger: tlog.New("ingester"), + Logger: log.SubLogger(logger, "ingester"), Validator: validator, } err = jc.StartJetstream(ctx, ingester.Ingest()) @@ -167,10 +166,9 @@ func Make(ctx context.Context, config *config.Config) (*State, error) { state := &State{ d, notifier, - oauth2, + oauth, enforcer, pages, - sess, res, posthog, jc, @@ -178,7 +176,7 @@ func Make(ctx context.Context, config *config.Config) (*State, error) { repoResolver, knotstream, spindlestream, - slog.Default(), + logger, validator, } @@ -277,13 +275,13 @@ func (s *State) Timeline(w http.ResponseWriter, r *http.Request) { } timeline, err := db.MakeTimeline(s.db, 50, userDid, filtered) if err != nil { - log.Println(err) + s.logger.Error("failed to make timeline", "err", err) s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.") } repos, err := db.GetTopStarredReposLastWeek(s.db) if err != nil { - log.Println(err) + s.logger.Error("failed to get top starred repos", "err", err) s.pages.Notice(w, "topstarredrepos", "Unable to load.") return } @@ -344,14 +342,14 @@ func (s *State) Home(w http.ResponseWriter, r *http.Request) { timeline, err := db.MakeTimeline(s.db, 5, "", filtered) if err != nil { - log.Println(err) + s.logger.Error("failed to make timeline", "err", err) s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.") return } repos, err := db.GetTopStarredReposLastWeek(s.db) if err != nil { - log.Println(err) + s.logger.Error("failed to get top starred repos", "err", err) s.pages.Notice(w, "topstarredrepos", "Unable to load.") return } diff --git a/cmd/appview/main.go b/cmd/appview/main.go index 47359823..ae63a5f9 100644 --- a/cmd/appview/main.go +++ b/cmd/appview/main.go @@ -2,35 +2,40 @@ package main import ( "context" - "log" - "log/slog" "net/http" "os" "tangled.org/core/appview/config" "tangled.org/core/appview/state" + tlog "tangled.org/core/log" ) func main() { - slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, nil))) - ctx := context.Background() + logger := tlog.New("appview") + ctx = tlog.IntoContext(ctx, logger) c, err := config.LoadConfig(ctx) if err != nil { - log.Println("failed to load config", "error", err) + logger.Error("failed to load config", "error", err) return } state, err := state.Make(ctx, c) defer func() { - log.Println(state.Close()) + if err := state.Close(); err != nil { + logger.Error("failed to close state", "err", err) + } }() if err != nil { - log.Fatal(err) + logger.Error("failed to start appview", "err", err) + os.Exit(-1) } - log.Println("starting server on", c.Core.ListenAddr) - log.Println(http.ListenAndServe(c.Core.ListenAddr, state.Router())) + logger.Info("starting server", "address", c.Core.ListenAddr) + + if err := http.ListenAndServe(c.Core.ListenAddr, state.Router()); err != nil { + logger.Error("failed to start appview", "err", err) + } } diff --git a/cmd/spindle/main.go b/cmd/spindle/main.go index 95d6ce33..85b46efb 100644 --- a/cmd/spindle/main.go +++ b/cmd/spindle/main.go @@ -2,18 +2,24 @@ package main import ( "context" + "log/slog" "os" - "tangled.org/core/log" + tlog "tangled.org/core/log" "tangled.org/core/spindle" _ "tangled.org/core/tid" ) func main() { - ctx := log.NewContext(context.Background(), "spindle") + logger := tlog.New("spindl3") + slog.SetDefault(logger) + + ctx := context.Background() + ctx = tlog.IntoContext(ctx, logger) + err := spindle.Run(ctx) if err != nil { - log.FromContext(ctx).Error("error running spindle", "error", err) + logger.Error("error running spindle", "error", err) os.Exit(-1) } } diff --git a/go.mod b/go.mod index bfd1725d..2f887e5c 100644 --- a/go.mod +++ b/go.mod @@ -60,12 +60,19 @@ require ( github.com/ProtonMail/go-crypto v1.3.0 // indirect github.com/alecthomas/repr v0.4.0 // indirect github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect github.com/aymerick/douceur v0.2.0 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect github.com/casbin/govaluate v1.3.0 // indirect github.com/cenkalti/backoff/v4 v4.3.0 // indirect github.com/cespare/xxhash/v2 v2.3.0 // indirect + github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect + github.com/charmbracelet/lipgloss v1.1.0 // indirect + github.com/charmbracelet/log v0.4.2 // indirect + github.com/charmbracelet/x/ansi v0.8.0 // indirect + github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect + github.com/charmbracelet/x/term v0.2.1 // indirect github.com/cloudflare/circl v1.6.2-0.20250618153321-aa837fd1539d // indirect github.com/containerd/errdefs v1.0.0 // indirect github.com/containerd/errdefs/pkg v0.3.0 // indirect @@ -84,6 +91,7 @@ require ( github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect github.com/go-git/go-billy/v5 v5.6.2 // indirect github.com/go-jose/go-jose/v3 v3.0.4 // indirect + github.com/go-logfmt/logfmt v0.6.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-redis/cache/v9 v9.0.0 // indirect @@ -126,7 +134,9 @@ require ( github.com/lestrrat-go/httprc v1.0.6 // indirect github.com/lestrrat-go/iter v1.0.2 // indirect github.com/lestrrat-go/option v1.0.1 // indirect + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-runewidth v0.0.16 // indirect github.com/minio/sha256-simd v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/moby/docker-image-spec v1.3.1 // indirect @@ -134,6 +144,7 @@ require ( github.com/moby/term v0.5.2 // indirect github.com/morikuni/aec v1.0.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect + github.com/muesli/termenv v0.16.0 // indirect github.com/multiformats/go-base32 v0.1.0 // indirect github.com/multiformats/go-base36 v0.2.0 // indirect github.com/multiformats/go-multibase v0.2.0 // indirect @@ -152,6 +163,7 @@ require ( github.com/prometheus/client_model v0.6.2 // indirect github.com/prometheus/common v0.64.0 // indirect github.com/prometheus/procfs v0.16.1 // indirect + github.com/rivo/uniseg v0.4.7 // indirect github.com/ryanuber/go-glob v1.0.0 // indirect github.com/segmentio/asm v1.2.0 // indirect github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect @@ -160,6 +172,7 @@ require ( github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect github.com/wyatt915/treeblood v0.1.15 // indirect + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect gitlab.com/staticnoise/goldmark-callout v0.0.0-20240609120641-6366b799e4ab // indirect gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect diff --git a/go.sum b/go.sum index 5040aa2a..073f2767 100644 --- a/go.sum +++ b/go.sum @@ -19,6 +19,8 @@ github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPd github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= github.com/avast/retry-go/v4 v4.6.1 h1:VkOLRubHdisGrHnTu89g08aQEWEgRU7LVEop3GbIcMk= github.com/avast/retry-go/v4 v4.6.1/go.mod h1:V6oF8njAwxJ5gRo1Q7Cxab24xs5NCWZBeaHHBklR8mA= +github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= +github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= @@ -48,6 +50,18 @@ github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XL 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/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= +github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= +github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= +github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= +github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= +github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= +github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= +github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= +github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= +github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= +github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= 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,6 +134,8 @@ github.com/go-git/go-git-fixtures/v5 v5.0.0-20241203230421-0753e18f8f03 h1:LumE+ github.com/go-git/go-git-fixtures/v5 v5.0.0-20241203230421-0753e18f8f03/go.mod h1:hMKrMnUE4W0SJ7bFyM00dyz/HoknZoptGWzrj6M+dEM= github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= +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.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= @@ -276,10 +292,14 @@ github.com/lestrrat-go/jwx/v2 v2.1.6 h1:hxM1gfDILk/l5ylers6BX/Eq1m/pnxe9NBwW6lVf github.com/lestrrat-go/jwx/v2 v2.1.6/go.mod h1:Y722kU5r/8mV7fYDifjug0r8FK8mZdw0K0GpJw/l8pU= github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= +github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= +github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= +github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= @@ -300,6 +320,8 @@ github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= +github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= +github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= 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= @@ -377,6 +399,9 @@ github.com/redis/go-redis/v9 v9.7.3 h1:YpPyAayJV+XErNsatSElgRZZVCwXX9QzkKYNvO7x0 github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= github.com/resend/resend-go/v2 v2.15.0 h1:B6oMEPf8IEQwn2Ovx/9yymkESLDSeNfLFaNMw+mzHhE= github.com/resend/resend-go/v2 v2.15.0/go.mod h1:3YCb8c8+pLiqhtRFXTyFwlLvfjQtluxOr9HEh2BwCkQ= +github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= +github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= +github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 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.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= @@ -434,6 +459,8 @@ github.com/wyatt915/goldmark-treeblood v0.0.0-20250825231212-5dcbdb2f4b57 h1:Uqt github.com/wyatt915/goldmark-treeblood v0.0.0-20250825231212-5dcbdb2f4b57/go.mod h1:BxSCWByWSRSuembL3cDG1IBUbkBoO/oW/6tF19aA4hs= github.com/wyatt915/treeblood v0.1.15 h1:3KZ3o2LpcKZAzOLqMoW9qeUzKEaKArKpbcPpTkNfQC8= github.com/wyatt915/treeblood v0.1.15/go.mod h1:i7+yhhmzdDP17/97pIsOSffw74EK/xk+qJ0029cSXUY= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= +github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= diff --git a/jetstream/jetstream.go b/jetstream/jetstream.go index 4948c3f0..e5d3e98b 100644 --- a/jetstream/jetstream.go +++ b/jetstream/jetstream.go @@ -114,7 +114,7 @@ func (j *JetstreamClient) StartJetstream(ctx context.Context, processFunc func(c sched := sequential.NewScheduler(j.ident, logger, j.withDidFilter(processFunc)) - client, err := client.NewClient(j.cfg, log.New("jetstream"), sched) + client, err := client.NewClient(j.cfg, logger, sched) if err != nil { return fmt.Errorf("failed to create jetstream client: %w", err) } diff --git a/nix/gomod2nix.toml b/nix/gomod2nix.toml index 65c6e23b..b1c6969b 100644 --- a/nix/gomod2nix.toml +++ b/nix/gomod2nix.toml @@ -29,6 +29,9 @@ schema = 3 [mod."github.com/avast/retry-go/v4"] version = "v4.6.1" hash = "sha256-PeZc8k4rDV64+k8nZt/oy1YNVbLevltXP3ZD1jf6Z6k=" + [mod."github.com/aymanbagabas/go-osc52/v2"] + version = "v2.0.1" + hash = "sha256-6Bp0jBZ6npvsYcKZGHHIUSVSTAMEyieweAX2YAKDjjg=" [mod."github.com/aymerick/douceur"] version = "v0.2.0" hash = "sha256-NiBX8EfOvLXNiK3pJaZX4N73YgfzdrzRXdiBFe3X3sE=" @@ -63,6 +66,24 @@ schema = 3 [mod."github.com/cespare/xxhash/v2"] version = "v2.3.0" hash = "sha256-7hRlwSR+fos1kx4VZmJ/7snR7zHh8ZFKX+qqqqGcQpY=" + [mod."github.com/charmbracelet/colorprofile"] + version = "v0.2.3-0.20250311203215-f60798e515dc" + hash = "sha256-D9E/bMOyLXAUVOHA1/6o3i+vVmLfwIMOWib6sU7A6+Q=" + [mod."github.com/charmbracelet/lipgloss"] + version = "v1.1.0" + hash = "sha256-RHsRT2EZ1nDOElxAK+6/DC9XAaGVjDTgPvRh3pyCfY4=" + [mod."github.com/charmbracelet/log"] + version = "v0.4.2" + hash = "sha256-3w1PCM/c4JvVEh2d0sMfv4C77Xs1bPa1Ea84zdynC7I=" + [mod."github.com/charmbracelet/x/ansi"] + version = "v0.8.0" + hash = "sha256-/YyDkGrULV2BtnNk3ojeSl0nUWQwIfIdW7WJuGbAZas=" + [mod."github.com/charmbracelet/x/cellbuf"] + version = "v0.0.13-0.20250311204145-2c3ea96c31dd" + hash = "sha256-XAhCOt8qJ2vR77lH1ez0IVU1/2CaLTq9jSmrHVg5HHU=" + [mod."github.com/charmbracelet/x/term"] + version = "v0.2.1" + hash = "sha256-VBkCZLI90PhMasftGw3403IqoV7d3E5WEGAIVrN5xQM=" [mod."github.com/cloudflare/circl"] version = "v1.6.2-0.20250618153321-aa837fd1539d" hash = "sha256-0s/i/XmMcuvPQ+qK9OIU5KxwYZyLVXRtdlYvIXRJT3Y=" @@ -145,6 +166,9 @@ schema = 3 [mod."github.com/go-jose/go-jose/v3"] version = "v3.0.4" hash = "sha256-RrLHCu9l6k0XVobdZQJ9Sx/VTQcWjrdLR5BEG7yXTEQ=" + [mod."github.com/go-logfmt/logfmt"] + version = "v0.6.0" + hash = "sha256-RtIG2qARd5sT10WQ7F3LR8YJhS8exs+KiuUiVf75bWg=" [mod."github.com/go-logr/logr"] version = "v1.4.3" hash = "sha256-Nnp/dEVNMxLp3RSPDHZzGbI8BkSNuZMX0I0cjWKXXLA=" @@ -298,9 +322,15 @@ schema = 3 [mod."github.com/lestrrat-go/option"] version = "v1.0.1" hash = "sha256-jVcIYYVsxElIS/l2akEw32vdEPR8+anR6oeT1FoYULI=" + [mod."github.com/lucasb-eyer/go-colorful"] + version = "v1.2.0" + hash = "sha256-Gg9dDJFCTaHrKHRR1SrJgZ8fWieJkybljybkI9x0gyE=" [mod."github.com/mattn/go-isatty"] version = "v0.0.20" hash = "sha256-qhw9hWtU5wnyFyuMbKx+7RB8ckQaFQ8D+8GKPkN3HHQ=" + [mod."github.com/mattn/go-runewidth"] + version = "v0.0.16" + hash = "sha256-NC+ntvwIpqDNmXb7aixcg09il80ygq6JAnW0Gb5b/DQ=" [mod."github.com/mattn/go-sqlite3"] version = "v1.14.24" hash = "sha256-taGKFZFQlR5++5b2oZ1dYS3RERKv6yh1gniNWhb4egg=" @@ -328,6 +358,9 @@ schema = 3 [mod."github.com/mr-tron/base58"] version = "v1.2.0" hash = "sha256-8FzMu3kHUbBX10pUdtGf59Ag7BNupx8ZHeUaodR1/Vk=" + [mod."github.com/muesli/termenv"] + version = "v0.16.0" + hash = "sha256-hGo275DJlyLtcifSLpWnk8jardOksdeX9lH4lBeE3gI=" [mod."github.com/multiformats/go-base32"] version = "v0.1.0" hash = "sha256-O2IM7FB+Y9MkDdZztyQL5F8oEnmON2Yew7XkotQziio=" @@ -394,6 +427,9 @@ schema = 3 [mod."github.com/resend/resend-go/v2"] version = "v2.15.0" hash = "sha256-1lMoxuMLQXaNWFKadS6rpztAKwvIl3/LWMXqw7f5WYg=" + [mod."github.com/rivo/uniseg"] + version = "v0.4.7" + hash = "sha256-rDcdNYH6ZD8KouyyiZCUEy8JrjOQoAkxHBhugrfHjFo=" [mod."github.com/ryanuber/go-glob"] version = "v1.0.0" hash = "sha256-YkMl1utwUhi3E0sHK23ISpAsPyj4+KeXyXKoFYGXGVY=" @@ -440,6 +476,9 @@ schema = 3 [mod."github.com/wyatt915/treeblood"] version = "v0.1.15" hash = "sha256-hb99exdkoY2Qv8WdDxhwgPXGbEYimUr6wFtPXEvcO9g=" + [mod."github.com/xo/terminfo"] + version = "v0.0.0-20220910002029-abceb7e1c41e" + hash = "sha256-GyCDxxMQhXA3Pi/TsWXpA8cX5akEoZV7CFx4RO3rARU=" [mod."github.com/yuin/goldmark"] version = "v1.7.13" hash = "sha256-vBCxZrPYPc8x/nvAAv3Au59dCCyfS80Vw3/a9EXK7TE=" diff --git a/xrpc/serviceauth/service_auth.go b/xrpc/serviceauth/service_auth.go index c45d3060..5aaf6cf8 100644 --- a/xrpc/serviceauth/service_auth.go +++ b/xrpc/serviceauth/service_auth.go @@ -9,6 +9,7 @@ import ( "github.com/bluesky-social/indigo/atproto/auth" "tangled.org/core/idresolver" + "tangled.org/core/log" xrpcerr "tangled.org/core/xrpc/errors" ) @@ -22,7 +23,7 @@ type ServiceAuth struct { func NewServiceAuth(logger *slog.Logger, resolver *idresolver.Resolver, audienceDid string) *ServiceAuth { return &ServiceAuth{ - logger: logger, + logger: log.SubLogger(logger, "serviceauth"), resolver: resolver, audienceDid: audienceDid, } @@ -30,8 +31,6 @@ func NewServiceAuth(logger *slog.Logger, resolver *idresolver.Resolver, audience func (sa *ServiceAuth) VerifyServiceAuth(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - l := sa.logger.With("url", r.URL) - token := r.Header.Get("Authorization") token = strings.TrimPrefix(token, "Bearer ") @@ -42,11 +41,13 @@ func (sa *ServiceAuth) VerifyServiceAuth(next http.Handler) http.Handler { did, err := s.Validate(r.Context(), token, nil) if err != nil { - l.Error("signature verification failed", "err", err) + sa.logger.Error("signature verification failed", "err", err) writeError(w, xrpcerr.AuthError(err), http.StatusForbidden) return } + sa.logger.Debug("valid signature", ActorDid, did) + r = r.WithContext( context.WithValue(r.Context(), ActorDid, did), ) -- 2.43.0