Monorepo for Tangled tangled.org

appview: improve the logging situation a bit

needs a lot more work, but we now inject slog in several places.

Signed-off-by: oppiliappan <me@oppi.li>

authored by oppi.li and committed by oppi.li c9726979 3ebdcdbd

Changed files
+427 -234
appview
cmd
appview
spindle
jetstream
nix
xrpc
serviceauth
+36 -28
appview/db/db.go
··· 4 4 "context" 5 5 "database/sql" 6 6 "fmt" 7 - "log" 7 + "log/slog" 8 8 "reflect" 9 9 "strings" 10 10 11 11 _ "github.com/mattn/go-sqlite3" 12 + "tangled.org/core/log" 12 13 ) 13 14 14 15 type DB struct { 15 16 *sql.DB 17 + logger *slog.Logger 16 18 } 17 19 18 20 type Execer interface { ··· 26 28 PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) 27 29 } 28 30 29 - func Make(dbPath string) (*DB, error) { 31 + func Make(ctx context.Context, dbPath string) (*DB, error) { 30 32 // https://github.com/mattn/go-sqlite3#connection-string 31 33 opts := []string{ 32 34 "_foreign_keys=1", ··· 35 37 "_auto_vacuum=incremental", 36 38 } 37 39 40 + logger := log.FromContext(ctx) 41 + logger = log.SubLogger(logger, "db") 42 + 38 43 db, err := sql.Open("sqlite3", dbPath+"?"+strings.Join(opts, "&")) 39 44 if err != nil { 40 45 return nil, err 41 46 } 42 - 43 - ctx := context.Background() 44 47 45 48 conn, err := db.Conn(ctx) 46 49 if err != nil { ··· 574 577 } 575 578 576 579 // run migrations 577 - runMigration(conn, "add-description-to-repos", func(tx *sql.Tx) error { 580 + runMigration(conn, logger, "add-description-to-repos", func(tx *sql.Tx) error { 578 581 tx.Exec(` 579 582 alter table repos add column description text check (length(description) <= 200); 580 583 `) 581 584 return nil 582 585 }) 583 586 584 - runMigration(conn, "add-rkey-to-pubkeys", func(tx *sql.Tx) error { 587 + runMigration(conn, logger, "add-rkey-to-pubkeys", func(tx *sql.Tx) error { 585 588 // add unconstrained column 586 589 _, err := tx.Exec(` 587 590 alter table public_keys ··· 604 607 return nil 605 608 }) 606 609 607 - runMigration(conn, "add-rkey-to-comments", func(tx *sql.Tx) error { 610 + runMigration(conn, logger, "add-rkey-to-comments", func(tx *sql.Tx) error { 608 611 _, err := tx.Exec(` 609 612 alter table comments drop column comment_at; 610 613 alter table comments add column rkey text; ··· 612 615 return err 613 616 }) 614 617 615 - runMigration(conn, "add-deleted-and-edited-to-issue-comments", func(tx *sql.Tx) error { 618 + runMigration(conn, logger, "add-deleted-and-edited-to-issue-comments", func(tx *sql.Tx) error { 616 619 _, err := tx.Exec(` 617 620 alter table comments add column deleted text; -- timestamp 618 621 alter table comments add column edited text; -- timestamp ··· 620 623 return err 621 624 }) 622 625 623 - runMigration(conn, "add-source-info-to-pulls-and-submissions", func(tx *sql.Tx) error { 626 + runMigration(conn, logger, "add-source-info-to-pulls-and-submissions", func(tx *sql.Tx) error { 624 627 _, err := tx.Exec(` 625 628 alter table pulls add column source_branch text; 626 629 alter table pulls add column source_repo_at text; ··· 629 632 return err 630 633 }) 631 634 632 - runMigration(conn, "add-source-to-repos", func(tx *sql.Tx) error { 635 + runMigration(conn, logger, "add-source-to-repos", func(tx *sql.Tx) error { 633 636 _, err := tx.Exec(` 634 637 alter table repos add column source text; 635 638 `) ··· 641 644 // 642 645 // [0]: https://sqlite.org/pragma.html#pragma_foreign_keys 643 646 conn.ExecContext(ctx, "pragma foreign_keys = off;") 644 - runMigration(conn, "recreate-pulls-column-for-stacking-support", func(tx *sql.Tx) error { 647 + runMigration(conn, logger, "recreate-pulls-column-for-stacking-support", func(tx *sql.Tx) error { 645 648 _, err := tx.Exec(` 646 649 create table pulls_new ( 647 650 -- identifiers ··· 698 701 }) 699 702 conn.ExecContext(ctx, "pragma foreign_keys = on;") 700 703 701 - runMigration(conn, "add-spindle-to-repos", func(tx *sql.Tx) error { 704 + runMigration(conn, logger, "add-spindle-to-repos", func(tx *sql.Tx) error { 702 705 tx.Exec(` 703 706 alter table repos add column spindle text; 704 707 `) ··· 708 711 // drop all knot secrets, add unique constraint to knots 709 712 // 710 713 // knots will henceforth use service auth for signed requests 711 - runMigration(conn, "no-more-secrets", func(tx *sql.Tx) error { 714 + runMigration(conn, logger, "no-more-secrets", func(tx *sql.Tx) error { 712 715 _, err := tx.Exec(` 713 716 create table registrations_new ( 714 717 id integer primary key autoincrement, ··· 731 734 }) 732 735 733 736 // recreate and add rkey + created columns with default constraint 734 - runMigration(conn, "rework-collaborators-table", func(tx *sql.Tx) error { 737 + runMigration(conn, logger, "rework-collaborators-table", func(tx *sql.Tx) error { 735 738 // create new table 736 739 // - repo_at instead of repo integer 737 740 // - rkey field ··· 785 788 return err 786 789 }) 787 790 788 - runMigration(conn, "add-rkey-to-issues", func(tx *sql.Tx) error { 791 + runMigration(conn, logger, "add-rkey-to-issues", func(tx *sql.Tx) error { 789 792 _, err := tx.Exec(` 790 793 alter table issues add column rkey text not null default ''; 791 794 ··· 797 800 }) 798 801 799 802 // repurpose the read-only column to "needs-upgrade" 800 - runMigration(conn, "rename-registrations-read-only-to-needs-upgrade", func(tx *sql.Tx) error { 803 + runMigration(conn, logger, "rename-registrations-read-only-to-needs-upgrade", func(tx *sql.Tx) error { 801 804 _, err := tx.Exec(` 802 805 alter table registrations rename column read_only to needs_upgrade; 803 806 `) ··· 805 808 }) 806 809 807 810 // require all knots to upgrade after the release of total xrpc 808 - runMigration(conn, "migrate-knots-to-total-xrpc", func(tx *sql.Tx) error { 811 + runMigration(conn, logger, "migrate-knots-to-total-xrpc", func(tx *sql.Tx) error { 809 812 _, err := tx.Exec(` 810 813 update registrations set needs_upgrade = 1; 811 814 `) ··· 813 816 }) 814 817 815 818 // require all knots to upgrade after the release of total xrpc 816 - runMigration(conn, "migrate-spindles-to-xrpc-owner", func(tx *sql.Tx) error { 819 + runMigration(conn, logger, "migrate-spindles-to-xrpc-owner", func(tx *sql.Tx) error { 817 820 _, err := tx.Exec(` 818 821 alter table spindles add column needs_upgrade integer not null default 0; 819 822 `) ··· 831 834 // 832 835 // disable foreign-keys for the next migration 833 836 conn.ExecContext(ctx, "pragma foreign_keys = off;") 834 - runMigration(conn, "remove-issue-at-from-issues", func(tx *sql.Tx) error { 837 + runMigration(conn, logger, "remove-issue-at-from-issues", func(tx *sql.Tx) error { 835 838 _, err := tx.Exec(` 836 839 create table if not exists issues_new ( 837 840 -- identifiers ··· 901 904 // - new columns 902 905 // * column "reply_to" which can be any other comment 903 906 // * column "at-uri" which is a generated column 904 - runMigration(conn, "rework-issue-comments", func(tx *sql.Tx) error { 907 + runMigration(conn, logger, "rework-issue-comments", func(tx *sql.Tx) error { 905 908 _, err := tx.Exec(` 906 909 create table if not exists issue_comments ( 907 910 -- identifiers ··· 961 964 // 962 965 // disable foreign-keys for the next migration 963 966 conn.ExecContext(ctx, "pragma foreign_keys = off;") 964 - runMigration(conn, "add-at-uri-to-pulls", func(tx *sql.Tx) error { 967 + runMigration(conn, logger, "add-at-uri-to-pulls", func(tx *sql.Tx) error { 965 968 _, err := tx.Exec(` 966 969 create table if not exists pulls_new ( 967 970 -- identifiers ··· 1042 1045 // 1043 1046 // disable foreign-keys for the next migration 1044 1047 conn.ExecContext(ctx, "pragma foreign_keys = off;") 1045 - runMigration(conn, "remove-repo-at-pull-id-from-pull-submissions", func(tx *sql.Tx) error { 1048 + runMigration(conn, logger, "remove-repo-at-pull-id-from-pull-submissions", func(tx *sql.Tx) error { 1046 1049 _, err := tx.Exec(` 1047 1050 create table if not exists pull_submissions_new ( 1048 1051 -- identifiers ··· 1094 1097 }) 1095 1098 conn.ExecContext(ctx, "pragma foreign_keys = on;") 1096 1099 1097 - return &DB{db}, nil 1100 + return &DB{ 1101 + db, 1102 + logger, 1103 + }, nil 1098 1104 } 1099 1105 1100 1106 type migrationFn = func(*sql.Tx) error 1101 1107 1102 - func runMigration(c *sql.Conn, name string, migrationFn migrationFn) error { 1108 + func runMigration(c *sql.Conn, logger *slog.Logger, name string, migrationFn migrationFn) error { 1109 + logger = logger.With("migration", name) 1110 + 1103 1111 tx, err := c.BeginTx(context.Background(), nil) 1104 1112 if err != nil { 1105 1113 return err ··· 1116 1124 // run migration 1117 1125 err = migrationFn(tx) 1118 1126 if err != nil { 1119 - log.Printf("Failed to run migration %s: %v", name, err) 1127 + logger.Error("failed to run migration", "err", err) 1120 1128 return err 1121 1129 } 1122 1130 1123 1131 // mark migration as complete 1124 1132 _, err = tx.Exec("insert into migrations (name) values (?)", name) 1125 1133 if err != nil { 1126 - log.Printf("Failed to mark migration %s as complete: %v", name, err) 1134 + logger.Error("failed to mark migration as complete", "err", err) 1127 1135 return err 1128 1136 } 1129 1137 ··· 1132 1140 return err 1133 1141 } 1134 1142 1135 - log.Printf("migration %s applied successfully", name) 1143 + logger.Info("migration applied successfully") 1136 1144 } else { 1137 - log.Printf("skipped migration %s, already applied", name) 1145 + logger.Warn("skipped migration, already applied") 1138 1146 } 1139 1147 1140 1148 return nil
+1 -1
appview/ingester.go
··· 89 89 } 90 90 91 91 if err != nil { 92 - l.Debug("error ingesting record", "err", err) 92 + l.Warn("refused to ingest record", "err", err) 93 93 } 94 94 95 95 return nil
+27 -26
appview/issues/issues.go
··· 5 5 "database/sql" 6 6 "errors" 7 7 "fmt" 8 - "log" 9 8 "log/slog" 10 9 "net/http" 11 10 "slices" ··· 28 27 "tangled.org/core/appview/reporesolver" 29 28 "tangled.org/core/appview/validator" 30 29 "tangled.org/core/idresolver" 31 - tlog "tangled.org/core/log" 32 30 "tangled.org/core/tid" 33 31 ) 34 32 ··· 53 51 config *config.Config, 54 52 notifier notify.Notifier, 55 53 validator *validator.Validator, 54 + logger *slog.Logger, 56 55 ) *Issues { 57 56 return &Issues{ 58 57 oauth: oauth, ··· 62 61 db: db, 63 62 config: config, 64 63 notifier: notifier, 65 - logger: tlog.New("issues"), 64 + logger: logger, 66 65 validator: validator, 67 66 } 68 67 } ··· 72 71 user := rp.oauth.GetUser(r) 73 72 f, err := rp.repoResolver.Resolve(r) 74 73 if err != nil { 75 - log.Println("failed to get repo and knot", err) 74 + l.Error("failed to get repo and knot", "err", err) 76 75 return 77 76 } 78 77 ··· 99 98 db.FilterContains("scope", tangled.RepoIssueNSID), 100 99 ) 101 100 if err != nil { 102 - log.Println("failed to fetch labels", err) 101 + l.Error("failed to fetch labels", "err", err) 103 102 rp.pages.Error503(w) 104 103 return 105 104 } ··· 126 125 user := rp.oauth.GetUser(r) 127 126 f, err := rp.repoResolver.Resolve(r) 128 127 if err != nil { 129 - log.Println("failed to get repo and knot", err) 128 + l.Error("failed to get repo and knot", "err", err) 130 129 return 131 130 } 132 131 ··· 199 198 200 199 err = db.PutIssue(tx, newIssue) 201 200 if err != nil { 202 - log.Println("failed to edit issue", err) 201 + l.Error("failed to edit issue", "err", err) 203 202 rp.pages.Notice(w, "issues", "Failed to edit issue.") 204 203 return 205 204 } ··· 237 236 // delete from PDS 238 237 client, err := rp.oauth.AuthorizedClient(r) 239 238 if err != nil { 240 - log.Println("failed to get authorized client", err) 239 + l.Error("failed to get authorized client", "err", err) 241 240 rp.pages.Notice(w, "issue-comment", "Failed to delete comment.") 242 241 return 243 242 } ··· 282 281 283 282 collaborators, err := f.Collaborators(r.Context()) 284 283 if err != nil { 285 - log.Println("failed to fetch repo collaborators: %w", err) 284 + l.Error("failed to fetch repo collaborators", "err", err) 286 285 } 287 286 isCollaborator := slices.ContainsFunc(collaborators, func(collab pages.Collaborator) bool { 288 287 return user.Did == collab.Did ··· 296 295 db.FilterEq("id", issue.Id), 297 296 ) 298 297 if err != nil { 299 - log.Println("failed to close issue", err) 298 + l.Error("failed to close issue", "err", err) 300 299 rp.pages.Notice(w, "issue-action", "Failed to close issue. Try again later.") 301 300 return 302 301 } ··· 307 306 rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId)) 308 307 return 309 308 } else { 310 - log.Println("user is not permitted to close issue") 309 + l.Error("user is not permitted to close issue") 311 310 http.Error(w, "for biden", http.StatusUnauthorized) 312 311 return 313 312 } ··· 318 317 user := rp.oauth.GetUser(r) 319 318 f, err := rp.repoResolver.Resolve(r) 320 319 if err != nil { 321 - log.Println("failed to get repo and knot", err) 320 + l.Error("failed to get repo and knot", "err", err) 322 321 return 323 322 } 324 323 ··· 331 330 332 331 collaborators, err := f.Collaborators(r.Context()) 333 332 if err != nil { 334 - log.Println("failed to fetch repo collaborators: %w", err) 333 + l.Error("failed to fetch repo collaborators", "err", err) 335 334 } 336 335 isCollaborator := slices.ContainsFunc(collaborators, func(collab pages.Collaborator) bool { 337 336 return user.Did == collab.Did ··· 344 343 db.FilterEq("id", issue.Id), 345 344 ) 346 345 if err != nil { 347 - log.Println("failed to reopen issue", err) 346 + l.Error("failed to reopen issue", "err", err) 348 347 rp.pages.Notice(w, "issue-action", "Failed to reopen issue. Try again later.") 349 348 return 350 349 } 351 350 rp.pages.HxLocation(w, fmt.Sprintf("/%s/issues/%d", f.OwnerSlashRepo(), issue.IssueId)) 352 351 return 353 352 } else { 354 - log.Println("user is not the owner of the repo") 353 + l.Error("user is not the owner of the repo") 355 354 http.Error(w, "forbidden", http.StatusUnauthorized) 356 355 return 357 356 } ··· 538 537 newBody := r.FormValue("body") 539 538 client, err := rp.oauth.AuthorizedClient(r) 540 539 if err != nil { 541 - log.Println("failed to get authorized client", err) 540 + l.Error("failed to get authorized client", "err", err) 542 541 rp.pages.Notice(w, "issue-comment", "Failed to create comment.") 543 542 return 544 543 } ··· 551 550 552 551 _, err = db.AddIssueComment(rp.db, newComment) 553 552 if err != nil { 554 - log.Println("failed to perferom update-description query", err) 553 + l.Error("failed to perferom update-description query", "err", err) 555 554 rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.") 556 555 return 557 556 } ··· 561 560 // update the record on pds 562 561 ex, err := comatproto.RepoGetRecord(r.Context(), client, "", tangled.RepoIssueCommentNSID, user.Did, comment.Rkey) 563 562 if err != nil { 564 - log.Println("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey) 563 + l.Error("failed to get record", "err", err, "did", newComment.Did, "rkey", newComment.Rkey) 565 564 rp.pages.Notice(w, fmt.Sprintf("comment-%s-status", commentId), "Failed to update description, no record found on PDS.") 566 565 return 567 566 } ··· 729 728 if comment.Rkey != "" { 730 729 client, err := rp.oauth.AuthorizedClient(r) 731 730 if err != nil { 732 - log.Println("failed to get authorized client", err) 731 + l.Error("failed to get authorized client", "err", err) 733 732 rp.pages.Notice(w, "issue-comment", "Failed to delete comment.") 734 733 return 735 734 } ··· 739 738 Rkey: comment.Rkey, 740 739 }) 741 740 if err != nil { 742 - log.Println(err) 741 + l.Error("failed to delete from PDS", "err", err) 743 742 } 744 743 } 745 744 ··· 757 756 } 758 757 759 758 func (rp *Issues) RepoIssues(w http.ResponseWriter, r *http.Request) { 759 + l := rp.logger.With("handler", "RepoIssues") 760 + 760 761 params := r.URL.Query() 761 762 state := params.Get("state") 762 763 isOpen := true ··· 771 772 772 773 page, ok := r.Context().Value("page").(pagination.Page) 773 774 if !ok { 774 - log.Println("failed to get page") 775 + l.Error("failed to get page") 775 776 page = pagination.FirstPage() 776 777 } 777 778 778 779 user := rp.oauth.GetUser(r) 779 780 f, err := rp.repoResolver.Resolve(r) 780 781 if err != nil { 781 - log.Println("failed to get repo and knot", err) 782 + l.Error("failed to get repo and knot", "err", err) 782 783 return 783 784 } 784 785 ··· 793 794 db.FilterEq("open", openVal), 794 795 ) 795 796 if err != nil { 796 - log.Println("failed to get issues", err) 797 + l.Error("failed to get issues", "err", err) 797 798 rp.pages.Notice(w, "issues", "Failed to load issues. Try again later.") 798 799 return 799 800 } ··· 804 805 db.FilterContains("scope", tangled.RepoIssueNSID), 805 806 ) 806 807 if err != nil { 807 - log.Println("failed to fetch labels", err) 808 + l.Error("failed to fetch labels", "err", err) 808 809 rp.pages.Error503(w) 809 810 return 810 811 } ··· 901 902 902 903 err = db.PutIssue(tx, issue) 903 904 if err != nil { 904 - log.Println("failed to create issue", err) 905 + l.Error("failed to create issue", "err", err) 905 906 rp.pages.Notice(w, "issues", "Failed to create issue.") 906 907 return 907 908 } 908 909 909 910 if err = tx.Commit(); err != nil { 910 - log.Println("failed to create issue", err) 911 + l.Error("failed to create issue", "err", err) 911 912 rp.pages.Notice(w, "issues", "Failed to create issue.") 912 913 return 913 914 }
+1 -3
appview/labels/labels.go
··· 16 16 "tangled.org/core/appview/oauth" 17 17 "tangled.org/core/appview/pages" 18 18 "tangled.org/core/appview/validator" 19 - "tangled.org/core/log" 20 19 "tangled.org/core/rbac" 21 20 "tangled.org/core/tid" 22 21 ··· 42 41 db *db.DB, 43 42 validator *validator.Validator, 44 43 enforcer *rbac.Enforcer, 44 + logger *slog.Logger, 45 45 ) *Labels { 46 - logger := log.New("labels") 47 - 48 46 return &Labels{ 49 47 oauth: oauth, 50 48 pages: pages,
+15 -12
appview/notifications/notifications.go
··· 1 1 package notifications 2 2 3 3 import ( 4 - "log" 4 + "log/slog" 5 5 "net/http" 6 6 "strconv" 7 7 ··· 14 14 ) 15 15 16 16 type Notifications struct { 17 - db *db.DB 18 - oauth *oauth.OAuth 19 - pages *pages.Pages 17 + db *db.DB 18 + oauth *oauth.OAuth 19 + pages *pages.Pages 20 + logger *slog.Logger 20 21 } 21 22 22 - func New(database *db.DB, oauthHandler *oauth.OAuth, pagesHandler *pages.Pages) *Notifications { 23 + func New(database *db.DB, oauthHandler *oauth.OAuth, pagesHandler *pages.Pages, logger *slog.Logger) *Notifications { 23 24 return &Notifications{ 24 - db: database, 25 - oauth: oauthHandler, 26 - pages: pagesHandler, 25 + db: database, 26 + oauth: oauthHandler, 27 + pages: pagesHandler, 28 + logger: logger, 27 29 } 28 30 } 29 31 ··· 44 46 } 45 47 46 48 func (n *Notifications) notificationsPage(w http.ResponseWriter, r *http.Request) { 49 + l := n.logger.With("handler", "notificationsPage") 47 50 user := n.oauth.GetUser(r) 48 51 49 52 page, ok := r.Context().Value("page").(pagination.Page) 50 53 if !ok { 51 - log.Println("failed to get page") 54 + l.Error("failed to get page") 52 55 page = pagination.FirstPage() 53 56 } 54 57 ··· 57 60 db.FilterEq("recipient_did", user.Did), 58 61 ) 59 62 if err != nil { 60 - log.Println("failed to get total notifications:", err) 63 + l.Error("failed to get total notifications", "err", err) 61 64 n.pages.Error500(w) 62 65 return 63 66 } ··· 68 71 db.FilterEq("recipient_did", user.Did), 69 72 ) 70 73 if err != nil { 71 - log.Println("failed to get notifications:", err) 74 + l.Error("failed to get notifications", "err", err) 72 75 n.pages.Error500(w) 73 76 return 74 77 } 75 78 76 79 err = n.db.MarkAllNotificationsRead(r.Context(), user.Did) 77 80 if err != nil { 78 - log.Println("failed to mark notifications as read:", err) 81 + l.Error("failed to mark notifications as read", "err", err) 79 82 } 80 83 81 84 unreadCount := 0
+2 -2
appview/pages/pages.go
··· 54 54 logger *slog.Logger 55 55 } 56 56 57 - func NewPages(config *config.Config, res *idresolver.Resolver) *Pages { 57 + func NewPages(config *config.Config, res *idresolver.Resolver, logger *slog.Logger) *Pages { 58 58 // initialized with safe defaults, can be overriden per use 59 59 rctx := &markup.RenderContext{ 60 60 IsDev: config.Core.Dev, ··· 72 72 rctx: rctx, 73 73 resolver: res, 74 74 templateDir: "appview/pages", 75 - logger: slog.Default().With("component", "pages"), 75 + logger: logger, 76 76 } 77 77 78 78 if p.dev {
+1 -3
appview/pipelines/pipelines.go
··· 16 16 "tangled.org/core/appview/reporesolver" 17 17 "tangled.org/core/eventconsumer" 18 18 "tangled.org/core/idresolver" 19 - "tangled.org/core/log" 20 19 "tangled.org/core/rbac" 21 20 spindlemodel "tangled.org/core/spindle/models" 22 21 ··· 45 44 db *db.DB, 46 45 config *config.Config, 47 46 enforcer *rbac.Enforcer, 47 + logger *slog.Logger, 48 48 ) *Pipelines { 49 - logger := log.New("pipelines") 50 - 51 49 return &Pipelines{ 52 50 oauth: oauth, 53 51 repoResolver: repoResolver,
+4
appview/pulls/pulls.go
··· 6 6 "errors" 7 7 "fmt" 8 8 "log" 9 + "log/slog" 9 10 "net/http" 10 11 "slices" 11 12 "sort" ··· 46 47 config *config.Config 47 48 notifier notify.Notifier 48 49 enforcer *rbac.Enforcer 50 + logger *slog.Logger 49 51 } 50 52 51 53 func New( ··· 57 59 config *config.Config, 58 60 notifier notify.Notifier, 59 61 enforcer *rbac.Enforcer, 62 + logger *slog.Logger, 60 63 ) *Pulls { 61 64 return &Pulls{ 62 65 oauth: oauth, ··· 67 70 config: config, 68 71 notifier: notifier, 69 72 enforcer: enforcer, 73 + logger: logger, 70 74 } 71 75 } 72 76
+14 -11
appview/repo/index.go
··· 3 3 import ( 4 4 "errors" 5 5 "fmt" 6 - "log" 6 + "log/slog" 7 7 "net/http" 8 8 "net/url" 9 9 "slices" ··· 31 31 ) 32 32 33 33 func (rp *Repo) RepoIndex(w http.ResponseWriter, r *http.Request) { 34 + l := rp.logger.With("handler", "RepoIndex") 35 + 34 36 ref := chi.URLParam(r, "ref") 35 37 ref, _ = url.PathUnescape(ref) 36 38 37 39 f, err := rp.repoResolver.Resolve(r) 38 40 if err != nil { 39 - log.Println("failed to fully resolve repo", err) 41 + l.Error("failed to fully resolve repo", "err", err) 40 42 return 41 43 } 42 44 ··· 56 58 result, err := rp.buildIndexResponse(r.Context(), xrpcc, f, ref) 57 59 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 58 60 if errors.Is(xrpcerr, xrpcclient.ErrXrpcUnsupported) { 59 - log.Println("failed to call XRPC repo.index", err) 61 + l.Error("failed to call XRPC repo.index", "err", err) 60 62 rp.pages.RepoIndexPage(w, pages.RepoIndexParams{ 61 63 LoggedInUser: user, 62 64 NeedsKnotUpgrade: true, ··· 66 68 } 67 69 68 70 rp.pages.Error503(w) 69 - log.Println("failed to build index response", err) 71 + l.Error("failed to build index response", "err", err) 70 72 return 71 73 } 72 74 ··· 119 121 emails := uniqueEmails(commitsTrunc) 120 122 emailToDidMap, err := db.GetEmailToDid(rp.db, emails, true) 121 123 if err != nil { 122 - log.Println("failed to get email to did map", err) 124 + l.Error("failed to get email to did map", "err", err) 123 125 } 124 126 125 127 vc, err := commitverify.GetVerifiedObjectCommits(rp.db, emailToDidMap, commitsTrunc) 126 128 if err != nil { 127 - log.Println(err) 129 + l.Error("failed to GetVerifiedObjectCommits", "err", err) 128 130 } 129 131 130 132 // TODO: a bit dirty 131 - languageInfo, err := rp.getLanguageInfo(r.Context(), f, xrpcc, result.Ref, ref == "") 133 + languageInfo, err := rp.getLanguageInfo(r.Context(), l, f, xrpcc, result.Ref, ref == "") 132 134 if err != nil { 133 - log.Printf("failed to compute language percentages: %s", err) 135 + l.Warn("failed to compute language percentages", "err", err) 134 136 // non-fatal 135 137 } 136 138 ··· 140 142 } 141 143 pipelines, err := getPipelineStatuses(rp.db, repoInfo, shas) 142 144 if err != nil { 143 - log.Printf("failed to fetch pipeline statuses: %s", err) 145 + l.Error("failed to fetch pipeline statuses", "err", err) 144 146 // non-fatal 145 147 } 146 148 ··· 162 164 163 165 func (rp *Repo) getLanguageInfo( 164 166 ctx context.Context, 167 + l *slog.Logger, 165 168 f *reporesolver.ResolvedRepo, 166 169 xrpcc *indigoxrpc.Client, 167 170 currentRef string, ··· 180 183 ls, err := tangled.RepoLanguages(ctx, xrpcc, currentRef, repo) 181 184 if err != nil { 182 185 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 183 - log.Println("failed to call XRPC repo.languages", xrpcerr) 186 + l.Error("failed to call XRPC repo.languages", "err", xrpcerr) 184 187 return nil, xrpcerr 185 188 } 186 189 return nil, err ··· 210 213 err = db.UpdateRepoLanguages(tx, f.RepoAt(), currentRef, langs) 211 214 if err != nil { 212 215 // non-fatal 213 - log.Println("failed to cache lang results", err) 216 + l.Error("failed to cache lang results", "err", err) 214 217 } 215 218 216 219 err = tx.Commit()
+130 -92
appview/repo/repo.go
··· 7 7 "errors" 8 8 "fmt" 9 9 "io" 10 - "log" 11 10 "log/slog" 12 11 "net/http" 13 12 "net/url" ··· 90 89 } 91 90 92 91 func (rp *Repo) DownloadArchive(w http.ResponseWriter, r *http.Request) { 92 + l := rp.logger.With("handler", "DownloadArchive") 93 + 93 94 ref := chi.URLParam(r, "ref") 94 95 ref, _ = url.PathUnescape(ref) 95 96 96 97 f, err := rp.repoResolver.Resolve(r) 97 98 if err != nil { 98 - log.Println("failed to get repo and knot", err) 99 + l.Error("failed to get repo and knot", "err", err) 99 100 return 100 101 } 101 102 ··· 111 112 repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 112 113 archiveBytes, err := tangled.RepoArchive(r.Context(), xrpcc, "tar.gz", "", ref, repo) 113 114 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 114 - log.Println("failed to call XRPC repo.archive", xrpcerr) 115 + l.Error("failed to call XRPC repo.archive", "err", xrpcerr) 115 116 rp.pages.Error503(w) 116 117 return 117 118 } ··· 128 129 } 129 130 130 131 func (rp *Repo) RepoLog(w http.ResponseWriter, r *http.Request) { 132 + l := rp.logger.With("handler", "RepoLog") 133 + 131 134 f, err := rp.repoResolver.Resolve(r) 132 135 if err != nil { 133 - log.Println("failed to fully resolve repo", err) 136 + l.Error("failed to fully resolve repo", "err", err) 134 137 return 135 138 } 136 139 ··· 165 168 repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 166 169 xrpcBytes, err := tangled.RepoLog(r.Context(), xrpcc, cursor, limit, "", ref, repo) 167 170 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 168 - log.Println("failed to call XRPC repo.log", xrpcerr) 171 + l.Error("failed to call XRPC repo.log", "err", xrpcerr) 169 172 rp.pages.Error503(w) 170 173 return 171 174 } 172 175 173 176 var xrpcResp types.RepoLogResponse 174 177 if err := json.Unmarshal(xrpcBytes, &xrpcResp); err != nil { 175 - log.Println("failed to decode XRPC response", err) 178 + l.Error("failed to decode XRPC response", "err", err) 176 179 rp.pages.Error503(w) 177 180 return 178 181 } 179 182 180 183 tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo) 181 184 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 182 - log.Println("failed to call XRPC repo.tags", xrpcerr) 185 + l.Error("failed to call XRPC repo.tags", "err", xrpcerr) 183 186 rp.pages.Error503(w) 184 187 return 185 188 } ··· 196 199 197 200 branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 198 201 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 199 - log.Println("failed to call XRPC repo.branches", xrpcerr) 202 + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) 200 203 rp.pages.Error503(w) 201 204 return 202 205 } ··· 214 217 215 218 emailToDidMap, err := db.GetEmailToDid(rp.db, uniqueEmails(xrpcResp.Commits), true) 216 219 if err != nil { 217 - log.Println("failed to fetch email to did mapping", err) 220 + l.Error("failed to fetch email to did mapping", "err", err) 218 221 } 219 222 220 223 vc, err := commitverify.GetVerifiedObjectCommits(rp.db, emailToDidMap, xrpcResp.Commits) 221 224 if err != nil { 222 - log.Println(err) 225 + l.Error("failed to GetVerifiedObjectCommits", "err", err) 223 226 } 224 227 225 228 repoInfo := f.RepoInfo(user) ··· 230 233 } 231 234 pipelines, err := getPipelineStatuses(rp.db, repoInfo, shas) 232 235 if err != nil { 233 - log.Println(err) 236 + l.Error("failed to getPipelineStatuses", "err", err) 234 237 // non-fatal 235 238 } 236 239 ··· 246 249 } 247 250 248 251 func (rp *Repo) RepoDescriptionEdit(w http.ResponseWriter, r *http.Request) { 252 + l := rp.logger.With("handler", "RepoDescriptionEdit") 253 + 249 254 f, err := rp.repoResolver.Resolve(r) 250 255 if err != nil { 251 - log.Println("failed to get repo and knot", err) 256 + l.Error("failed to get repo and knot", "err", err) 252 257 w.WriteHeader(http.StatusBadRequest) 253 258 return 254 259 } ··· 260 265 } 261 266 262 267 func (rp *Repo) RepoDescription(w http.ResponseWriter, r *http.Request) { 268 + l := rp.logger.With("handler", "RepoDescription") 269 + 263 270 f, err := rp.repoResolver.Resolve(r) 264 271 if err != nil { 265 - log.Println("failed to get repo and knot", err) 272 + l.Error("failed to get repo and knot", "err", err) 266 273 w.WriteHeader(http.StatusBadRequest) 267 274 return 268 275 } ··· 270 277 repoAt := f.RepoAt() 271 278 rkey := repoAt.RecordKey().String() 272 279 if rkey == "" { 273 - log.Println("invalid aturi for repo", err) 280 + l.Error("invalid aturi for repo", "err", err) 274 281 w.WriteHeader(http.StatusInternalServerError) 275 282 return 276 283 } ··· 287 294 newDescription := r.FormValue("description") 288 295 client, err := rp.oauth.AuthorizedClient(r) 289 296 if err != nil { 290 - log.Println("failed to get client") 297 + l.Error("failed to get client") 291 298 rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.") 292 299 return 293 300 } ··· 295 302 // optimistic update 296 303 err = db.UpdateDescription(rp.db, string(repoAt), newDescription) 297 304 if err != nil { 298 - log.Println("failed to perferom update-description query", err) 305 + l.Error("failed to perform update-description query", "err", err) 299 306 rp.pages.Notice(w, "repo-notice", "Failed to update description, try again later.") 300 307 return 301 308 } ··· 324 331 }) 325 332 326 333 if err != nil { 327 - log.Println("failed to perferom update-description query", err) 334 + l.Error("failed to perferom update-description query", "err", err) 328 335 // failed to get record 329 336 rp.pages.Notice(w, "repo-notice", "Failed to update description, unable to save to PDS.") 330 337 return ··· 341 348 } 342 349 343 350 func (rp *Repo) RepoCommit(w http.ResponseWriter, r *http.Request) { 351 + l := rp.logger.With("handler", "RepoCommit") 352 + 344 353 f, err := rp.repoResolver.Resolve(r) 345 354 if err != nil { 346 - log.Println("failed to fully resolve repo", err) 355 + l.Error("failed to fully resolve repo", "err", err) 347 356 return 348 357 } 349 358 ref := chi.URLParam(r, "ref") ··· 371 380 repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 372 381 xrpcBytes, err := tangled.RepoDiff(r.Context(), xrpcc, ref, repo) 373 382 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 374 - log.Println("failed to call XRPC repo.diff", xrpcerr) 383 + l.Error("failed to call XRPC repo.diff", "err", xrpcerr) 375 384 rp.pages.Error503(w) 376 385 return 377 386 } 378 387 379 388 var result types.RepoCommitResponse 380 389 if err := json.Unmarshal(xrpcBytes, &result); err != nil { 381 - log.Println("failed to decode XRPC response", err) 390 + l.Error("failed to decode XRPC response", "err", err) 382 391 rp.pages.Error503(w) 383 392 return 384 393 } 385 394 386 395 emailToDidMap, err := db.GetEmailToDid(rp.db, []string{result.Diff.Commit.Committer.Email, result.Diff.Commit.Author.Email}, true) 387 396 if err != nil { 388 - log.Println("failed to get email to did mapping:", err) 397 + l.Error("failed to get email to did mapping", "err", err) 389 398 } 390 399 391 400 vc, err := commitverify.GetVerifiedCommits(rp.db, emailToDidMap, []types.NiceDiff{*result.Diff}) 392 401 if err != nil { 393 - log.Println(err) 402 + l.Error("failed to GetVerifiedCommits", "err", err) 394 403 } 395 404 396 405 user := rp.oauth.GetUser(r) 397 406 repoInfo := f.RepoInfo(user) 398 407 pipelines, err := getPipelineStatuses(rp.db, repoInfo, []string{result.Diff.Commit.This}) 399 408 if err != nil { 400 - log.Println(err) 409 + l.Error("failed to getPipelineStatuses", "err", err) 401 410 // non-fatal 402 411 } 403 412 var pipeline *models.Pipeline ··· 417 426 } 418 427 419 428 func (rp *Repo) RepoTree(w http.ResponseWriter, r *http.Request) { 429 + l := rp.logger.With("handler", "RepoTree") 430 + 420 431 f, err := rp.repoResolver.Resolve(r) 421 432 if err != nil { 422 - log.Println("failed to fully resolve repo", err) 433 + l.Error("failed to fully resolve repo", "err", err) 423 434 return 424 435 } 425 436 ··· 444 455 repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 445 456 xrpcResp, err := tangled.RepoTree(r.Context(), xrpcc, treePath, ref, repo) 446 457 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 447 - log.Println("failed to call XRPC repo.tree", xrpcerr) 458 + l.Error("failed to call XRPC repo.tree", "err", xrpcerr) 448 459 rp.pages.Error503(w) 449 460 return 450 461 } ··· 519 530 } 520 531 521 532 func (rp *Repo) RepoTags(w http.ResponseWriter, r *http.Request) { 533 + l := rp.logger.With("handler", "RepoTags") 534 + 522 535 f, err := rp.repoResolver.Resolve(r) 523 536 if err != nil { 524 - log.Println("failed to get repo and knot", err) 537 + l.Error("failed to get repo and knot", "err", err) 525 538 return 526 539 } 527 540 ··· 537 550 repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 538 551 xrpcBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo) 539 552 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 540 - log.Println("failed to call XRPC repo.tags", xrpcerr) 553 + l.Error("failed to call XRPC repo.tags", "err", xrpcerr) 541 554 rp.pages.Error503(w) 542 555 return 543 556 } 544 557 545 558 var result types.RepoTagsResponse 546 559 if err := json.Unmarshal(xrpcBytes, &result); err != nil { 547 - log.Println("failed to decode XRPC response", err) 560 + l.Error("failed to decode XRPC response", "err", err) 548 561 rp.pages.Error503(w) 549 562 return 550 563 } 551 564 552 565 artifacts, err := db.GetArtifact(rp.db, db.FilterEq("repo_at", f.RepoAt())) 553 566 if err != nil { 554 - log.Println("failed grab artifacts", err) 567 + l.Error("failed grab artifacts", "err", err) 555 568 return 556 569 } 557 570 ··· 588 601 } 589 602 590 603 func (rp *Repo) RepoBranches(w http.ResponseWriter, r *http.Request) { 604 + l := rp.logger.With("handler", "RepoBranches") 605 + 591 606 f, err := rp.repoResolver.Resolve(r) 592 607 if err != nil { 593 - log.Println("failed to get repo and knot", err) 608 + l.Error("failed to get repo and knot", "err", err) 594 609 return 595 610 } 596 611 ··· 606 621 repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 607 622 xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 608 623 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 609 - log.Println("failed to call XRPC repo.branches", xrpcerr) 624 + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) 610 625 rp.pages.Error503(w) 611 626 return 612 627 } 613 628 614 629 var result types.RepoBranchesResponse 615 630 if err := json.Unmarshal(xrpcBytes, &result); err != nil { 616 - log.Println("failed to decode XRPC response", err) 631 + l.Error("failed to decode XRPC response", "err", err) 617 632 rp.pages.Error503(w) 618 633 return 619 634 } ··· 629 644 } 630 645 631 646 func (rp *Repo) DeleteBranch(w http.ResponseWriter, r *http.Request) { 647 + l := rp.logger.With("handler", "DeleteBranch") 648 + 632 649 f, err := rp.repoResolver.Resolve(r) 633 650 if err != nil { 634 - log.Println("failed to get repo and knot", err) 651 + l.Error("failed to get repo and knot", "err", err) 635 652 return 636 653 } 637 654 638 655 noticeId := "delete-branch-error" 639 656 fail := func(msg string, err error) { 640 - log.Println(msg, "err", err) 657 + l.Error(msg, "err", err) 641 658 rp.pages.Notice(w, noticeId, msg) 642 659 } 643 660 ··· 670 687 fail(fmt.Sprintf("Failed to delete branch: %s", err), err) 671 688 return 672 689 } 673 - log.Println("deleted branch from knot", "branch", branch, "repo", f.RepoAt()) 690 + l.Error("deleted branch from knot", "branch", branch, "repo", f.RepoAt()) 674 691 675 692 rp.pages.HxRefresh(w) 676 693 } 677 694 678 695 func (rp *Repo) RepoBlob(w http.ResponseWriter, r *http.Request) { 696 + l := rp.logger.With("handler", "RepoBlob") 697 + 679 698 f, err := rp.repoResolver.Resolve(r) 680 699 if err != nil { 681 - log.Println("failed to get repo and knot", err) 700 + l.Error("failed to get repo and knot", "err", err) 682 701 return 683 702 } 684 703 ··· 700 719 repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Repo.Name) 701 720 resp, err := tangled.RepoBlob(r.Context(), xrpcc, filePath, false, ref, repo) 702 721 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 703 - log.Println("failed to call XRPC repo.blob", xrpcerr) 722 + l.Error("failed to call XRPC repo.blob", "err", xrpcerr) 704 723 rp.pages.Error503(w) 705 724 return 706 725 } ··· 800 819 } 801 820 802 821 func (rp *Repo) RepoBlobRaw(w http.ResponseWriter, r *http.Request) { 822 + l := rp.logger.With("handler", "RepoBlobRaw") 823 + 803 824 f, err := rp.repoResolver.Resolve(r) 804 825 if err != nil { 805 - log.Println("failed to get repo and knot", err) 826 + l.Error("failed to get repo and knot", err) 806 827 w.WriteHeader(http.StatusBadRequest) 807 828 return 808 829 } ··· 834 855 835 856 req, err := http.NewRequest("GET", blobURL, nil) 836 857 if err != nil { 837 - log.Println("failed to create request", err) 858 + l.Error("failed to create request", "err", err) 838 859 return 839 860 } 840 861 ··· 846 867 client := &http.Client{} 847 868 resp, err := client.Do(req) 848 869 if err != nil { 849 - log.Println("failed to reach knotserver", err) 870 + l.Error("failed to reach knotserver", "err", err) 850 871 rp.pages.Error503(w) 851 872 return 852 873 } ··· 859 880 } 860 881 861 882 if resp.StatusCode != http.StatusOK { 862 - log.Printf("knotserver returned non-OK status for raw blob %s: %d", blobURL, resp.StatusCode) 883 + l.Error("knotserver returned non-OK status for raw blob", "url", blobURL, "statuscode", resp.StatusCode) 863 884 w.WriteHeader(resp.StatusCode) 864 885 _, _ = io.Copy(w, resp.Body) 865 886 return ··· 868 889 contentType := resp.Header.Get("Content-Type") 869 890 body, err := io.ReadAll(resp.Body) 870 891 if err != nil { 871 - log.Printf("error reading response body from knotserver: %v", err) 892 + l.Error("error reading response body from knotserver", "err", err) 872 893 w.WriteHeader(http.StatusInternalServerError) 873 894 return 874 895 } ··· 1443 1464 db.FilterContains("scope", subject.Collection().String()), 1444 1465 ) 1445 1466 if err != nil { 1446 - log.Println("failed to fetch label defs", err) 1467 + l.Error("failed to fetch label defs", "err", err) 1447 1468 return 1448 1469 } 1449 1470 ··· 1454 1475 1455 1476 states, err := db.GetLabels(rp.db, db.FilterEq("subject", subject)) 1456 1477 if err != nil { 1457 - log.Println("failed to build label state", err) 1478 + l.Error("failed to build label state", "err", err) 1458 1479 return 1459 1480 } 1460 1481 state := states[subject] ··· 1491 1512 db.FilterContains("scope", subject.Collection().String()), 1492 1513 ) 1493 1514 if err != nil { 1494 - log.Println("failed to fetch labels", err) 1515 + l.Error("failed to fetch labels", "err", err) 1495 1516 return 1496 1517 } 1497 1518 ··· 1502 1523 1503 1524 states, err := db.GetLabels(rp.db, db.FilterEq("subject", subject)) 1504 1525 if err != nil { 1505 - log.Println("failed to build label state", err) 1526 + l.Error("failed to build label state", "err", err) 1506 1527 return 1507 1528 } 1508 1529 state := states[subject] ··· 1649 1670 1650 1671 func (rp *Repo) DeleteRepo(w http.ResponseWriter, r *http.Request) { 1651 1672 user := rp.oauth.GetUser(r) 1673 + l := rp.logger.With("handler", "DeleteRepo") 1652 1674 1653 1675 noticeId := "operation-error" 1654 1676 f, err := rp.repoResolver.Resolve(r) 1655 1677 if err != nil { 1656 - log.Println("failed to get repo and knot", err) 1678 + l.Error("failed to get repo and knot", "err", err) 1657 1679 return 1658 1680 } 1659 1681 1660 1682 // remove record from pds 1661 1683 atpClient, err := rp.oauth.AuthorizedClient(r) 1662 1684 if err != nil { 1663 - log.Println("failed to get authorized client", err) 1685 + l.Error("failed to get authorized client", "err", err) 1664 1686 return 1665 1687 } 1666 1688 _, err = comatproto.RepoDeleteRecord(r.Context(), atpClient, &comatproto.RepoDeleteRecord_Input{ ··· 1669 1691 Rkey: f.Rkey, 1670 1692 }) 1671 1693 if err != nil { 1672 - log.Printf("failed to delete record: %s", err) 1694 + l.Error("failed to delete record", "err", err) 1673 1695 rp.pages.Notice(w, noticeId, "Failed to delete repository from PDS.") 1674 1696 return 1675 1697 } 1676 - log.Println("removed repo record ", f.RepoAt().String()) 1698 + l.Info("removed repo record", "aturi", f.RepoAt().String()) 1677 1699 1678 1700 client, err := rp.oauth.ServiceClient( 1679 1701 r, ··· 1682 1704 oauth.WithDev(rp.config.Core.Dev), 1683 1705 ) 1684 1706 if err != nil { 1685 - log.Println("failed to connect to knot server:", err) 1707 + l.Error("failed to connect to knot server", "err", err) 1686 1708 return 1687 1709 } 1688 1710 ··· 1699 1721 rp.pages.Notice(w, noticeId, err.Error()) 1700 1722 return 1701 1723 } 1702 - log.Println("deleted repo from knot") 1724 + l.Info("deleted repo from knot") 1703 1725 1704 1726 tx, err := rp.db.BeginTx(r.Context(), nil) 1705 1727 if err != nil { 1706 - log.Println("failed to start tx") 1728 + l.Error("failed to start tx") 1707 1729 w.Write(fmt.Append(nil, "failed to add collaborator: ", err)) 1708 1730 return 1709 1731 } ··· 1711 1733 tx.Rollback() 1712 1734 err = rp.enforcer.E.LoadPolicy() 1713 1735 if err != nil { 1714 - log.Println("failed to rollback policies") 1736 + l.Error("failed to rollback policies") 1715 1737 } 1716 1738 }() 1717 1739 ··· 1725 1747 did := c[0] 1726 1748 rp.enforcer.RemoveCollaborator(did, f.Knot, f.DidSlashRepo()) 1727 1749 } 1728 - log.Println("removed collaborators") 1750 + l.Info("removed collaborators") 1729 1751 1730 1752 // remove repo RBAC 1731 1753 err = rp.enforcer.RemoveRepo(f.OwnerDid(), f.Knot, f.DidSlashRepo()) ··· 1740 1762 rp.pages.Notice(w, noticeId, "Failed to update appview") 1741 1763 return 1742 1764 } 1743 - log.Println("removed repo from db") 1765 + l.Info("removed repo from db") 1744 1766 1745 1767 err = tx.Commit() 1746 1768 if err != nil { 1747 - log.Println("failed to commit changes", err) 1769 + l.Error("failed to commit changes", "err", err) 1748 1770 http.Error(w, err.Error(), http.StatusInternalServerError) 1749 1771 return 1750 1772 } 1751 1773 1752 1774 err = rp.enforcer.E.SavePolicy() 1753 1775 if err != nil { 1754 - log.Println("failed to update ACLs", err) 1776 + l.Error("failed to update ACLs", "err", err) 1755 1777 http.Error(w, err.Error(), http.StatusInternalServerError) 1756 1778 return 1757 1779 } ··· 1760 1782 } 1761 1783 1762 1784 func (rp *Repo) SetDefaultBranch(w http.ResponseWriter, r *http.Request) { 1785 + l := rp.logger.With("handler", "SetDefaultBranch") 1786 + 1763 1787 f, err := rp.repoResolver.Resolve(r) 1764 1788 if err != nil { 1765 - log.Println("failed to get repo and knot", err) 1789 + l.Error("failed to get repo and knot", "err", err) 1766 1790 return 1767 1791 } 1768 1792 ··· 1780 1804 oauth.WithDev(rp.config.Core.Dev), 1781 1805 ) 1782 1806 if err != nil { 1783 - log.Println("failed to connect to knot server:", err) 1807 + l.Error("failed to connect to knot server", "err", err) 1784 1808 rp.pages.Notice(w, noticeId, "Failed to connect to knot server.") 1785 1809 return 1786 1810 } ··· 1794 1818 }, 1795 1819 ) 1796 1820 if err := xrpcclient.HandleXrpcErr(xe); err != nil { 1797 - log.Println("xrpc failed", "err", xe) 1821 + l.Error("xrpc failed", "err", xe) 1798 1822 rp.pages.Notice(w, noticeId, err.Error()) 1799 1823 return 1800 1824 } ··· 1809 1833 1810 1834 f, err := rp.repoResolver.Resolve(r) 1811 1835 if err != nil { 1812 - log.Println("failed to get repo and knot", err) 1836 + l.Error("failed to get repo and knot", "err", err) 1813 1837 return 1814 1838 } 1815 1839 1816 1840 if f.Spindle == "" { 1817 - log.Println("empty spindle cannot add/rm secret", err) 1841 + l.Error("empty spindle cannot add/rm secret", "err", err) 1818 1842 return 1819 1843 } 1820 1844 ··· 1831 1855 oauth.WithDev(rp.config.Core.Dev), 1832 1856 ) 1833 1857 if err != nil { 1834 - log.Println("failed to create spindle client", err) 1858 + l.Error("failed to create spindle client", "err", err) 1835 1859 return 1836 1860 } 1837 1861 ··· 1917 1941 } 1918 1942 1919 1943 func (rp *Repo) generalSettings(w http.ResponseWriter, r *http.Request) { 1944 + l := rp.logger.With("handler", "generalSettings") 1945 + 1920 1946 f, err := rp.repoResolver.Resolve(r) 1921 1947 user := rp.oauth.GetUser(r) 1922 1948 ··· 1932 1958 repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 1933 1959 xrpcBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 1934 1960 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 1935 - log.Println("failed to call XRPC repo.branches", xrpcerr) 1961 + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) 1936 1962 rp.pages.Error503(w) 1937 1963 return 1938 1964 } 1939 1965 1940 1966 var result types.RepoBranchesResponse 1941 1967 if err := json.Unmarshal(xrpcBytes, &result); err != nil { 1942 - log.Println("failed to decode XRPC response", err) 1968 + l.Error("failed to decode XRPC response", "err", err) 1943 1969 rp.pages.Error503(w) 1944 1970 return 1945 1971 } 1946 1972 1947 1973 defaultLabels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", models.DefaultLabelDefs())) 1948 1974 if err != nil { 1949 - log.Println("failed to fetch labels", err) 1975 + l.Error("failed to fetch labels", "err", err) 1950 1976 rp.pages.Error503(w) 1951 1977 return 1952 1978 } 1953 1979 1954 1980 labels, err := db.GetLabelDefinitions(rp.db, db.FilterIn("at_uri", f.Repo.Labels)) 1955 1981 if err != nil { 1956 - log.Println("failed to fetch labels", err) 1982 + l.Error("failed to fetch labels", "err", err) 1957 1983 rp.pages.Error503(w) 1958 1984 return 1959 1985 } ··· 2001 2027 } 2002 2028 2003 2029 func (rp *Repo) accessSettings(w http.ResponseWriter, r *http.Request) { 2030 + l := rp.logger.With("handler", "accessSettings") 2031 + 2004 2032 f, err := rp.repoResolver.Resolve(r) 2005 2033 user := rp.oauth.GetUser(r) 2006 2034 2007 2035 repoCollaborators, err := f.Collaborators(r.Context()) 2008 2036 if err != nil { 2009 - log.Println("failed to get collaborators", err) 2037 + l.Error("failed to get collaborators", "err", err) 2010 2038 } 2011 2039 2012 2040 rp.pages.RepoAccessSettings(w, pages.RepoAccessSettingsParams{ ··· 2019 2047 } 2020 2048 2021 2049 func (rp *Repo) pipelineSettings(w http.ResponseWriter, r *http.Request) { 2050 + l := rp.logger.With("handler", "pipelineSettings") 2051 + 2022 2052 f, err := rp.repoResolver.Resolve(r) 2023 2053 user := rp.oauth.GetUser(r) 2024 2054 2025 2055 // all spindles that the repo owner is a member of 2026 2056 spindles, err := rp.enforcer.GetSpindlesForUser(f.OwnerDid()) 2027 2057 if err != nil { 2028 - log.Println("failed to fetch spindles", err) 2058 + l.Error("failed to fetch spindles", "err", err) 2029 2059 return 2030 2060 } 2031 2061 ··· 2038 2068 oauth.WithExp(60), 2039 2069 oauth.WithDev(rp.config.Core.Dev), 2040 2070 ); err != nil { 2041 - log.Println("failed to create spindle client", err) 2071 + l.Error("failed to create spindle client", "err", err) 2042 2072 } else if resp, err := tangled.RepoListSecrets(r.Context(), spindleClient, f.RepoAt().String()); err != nil { 2043 - log.Println("failed to fetch secrets", err) 2073 + l.Error("failed to fetch secrets", "err", err) 2044 2074 } else { 2045 2075 secrets = resp.Secrets 2046 2076 } ··· 2080 2110 } 2081 2111 2082 2112 func (rp *Repo) SyncRepoFork(w http.ResponseWriter, r *http.Request) { 2113 + l := rp.logger.With("handler", "SyncRepoFork") 2114 + 2083 2115 ref := chi.URLParam(r, "ref") 2084 2116 ref, _ = url.PathUnescape(ref) 2085 2117 2086 2118 user := rp.oauth.GetUser(r) 2087 2119 f, err := rp.repoResolver.Resolve(r) 2088 2120 if err != nil { 2089 - log.Printf("failed to resolve source repo: %v", err) 2121 + l.Error("failed to resolve source repo", "err", err) 2090 2122 return 2091 2123 } 2092 2124 ··· 2130 2162 } 2131 2163 2132 2164 func (rp *Repo) ForkRepo(w http.ResponseWriter, r *http.Request) { 2165 + l := rp.logger.With("handler", "ForkRepo") 2166 + 2133 2167 user := rp.oauth.GetUser(r) 2134 2168 f, err := rp.repoResolver.Resolve(r) 2135 2169 if err != nil { 2136 - log.Printf("failed to resolve source repo: %v", err) 2170 + l.Error("failed to resolve source repo", "err", err) 2137 2171 return 2138 2172 } 2139 2173 ··· 2184 2218 ) 2185 2219 if err != nil { 2186 2220 if !errors.Is(err, sql.ErrNoRows) { 2187 - log.Println("error fetching existing repo from db", "err", err) 2221 + l.Error("error fetching existing repo from db", "err", err) 2188 2222 rp.pages.Notice(w, "repo", "Failed to fork this repository. Try again later.") 2189 2223 return 2190 2224 } ··· 2299 2333 2300 2334 err = db.AddRepo(tx, repo) 2301 2335 if err != nil { 2302 - log.Println(err) 2336 + l.Error("failed to AddRepo", "err", err) 2303 2337 rp.pages.Notice(w, "repo", "Failed to save repository information.") 2304 2338 return 2305 2339 } ··· 2308 2342 p, _ := securejoin.SecureJoin(user.Did, forkName) 2309 2343 err = rp.enforcer.AddRepo(user.Did, targetKnot, p) 2310 2344 if err != nil { 2311 - log.Println(err) 2345 + l.Error("failed to add ACLs", "err", err) 2312 2346 rp.pages.Notice(w, "repo", "Failed to set up repository permissions.") 2313 2347 return 2314 2348 } 2315 2349 2316 2350 err = tx.Commit() 2317 2351 if err != nil { 2318 - log.Println("failed to commit changes", err) 2352 + l.Error("failed to commit changes", "err", err) 2319 2353 http.Error(w, err.Error(), http.StatusInternalServerError) 2320 2354 return 2321 2355 } 2322 2356 2323 2357 err = rp.enforcer.E.SavePolicy() 2324 2358 if err != nil { 2325 - log.Println("failed to update ACLs", err) 2359 + l.Error("failed to update ACLs", "err", err) 2326 2360 http.Error(w, err.Error(), http.StatusInternalServerError) 2327 2361 return 2328 2362 } ··· 2358 2392 } 2359 2393 2360 2394 func (rp *Repo) RepoCompareNew(w http.ResponseWriter, r *http.Request) { 2395 + l := rp.logger.With("handler", "RepoCompareNew") 2396 + 2361 2397 user := rp.oauth.GetUser(r) 2362 2398 f, err := rp.repoResolver.Resolve(r) 2363 2399 if err != nil { 2364 - log.Println("failed to get repo and knot", err) 2400 + l.Error("failed to get repo and knot", "err", err) 2365 2401 return 2366 2402 } 2367 2403 ··· 2377 2413 repo := fmt.Sprintf("%s/%s", f.OwnerDid(), f.Name) 2378 2414 branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 2379 2415 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 2380 - log.Println("failed to call XRPC repo.branches", xrpcerr) 2416 + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) 2381 2417 rp.pages.Error503(w) 2382 2418 return 2383 2419 } 2384 2420 2385 2421 var branchResult types.RepoBranchesResponse 2386 2422 if err := json.Unmarshal(branchBytes, &branchResult); err != nil { 2387 - log.Println("failed to decode XRPC branches response", err) 2423 + l.Error("failed to decode XRPC branches response", "err", err) 2388 2424 rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2389 2425 return 2390 2426 } ··· 2414 2450 2415 2451 tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo) 2416 2452 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 2417 - log.Println("failed to call XRPC repo.tags", xrpcerr) 2453 + l.Error("failed to call XRPC repo.tags", "err", xrpcerr) 2418 2454 rp.pages.Error503(w) 2419 2455 return 2420 2456 } 2421 2457 2422 2458 var tags types.RepoTagsResponse 2423 2459 if err := json.Unmarshal(tagBytes, &tags); err != nil { 2424 - log.Println("failed to decode XRPC tags response", err) 2460 + l.Error("failed to decode XRPC tags response", "err", err) 2425 2461 rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2426 2462 return 2427 2463 } ··· 2439 2475 } 2440 2476 2441 2477 func (rp *Repo) RepoCompare(w http.ResponseWriter, r *http.Request) { 2478 + l := rp.logger.With("handler", "RepoCompare") 2479 + 2442 2480 user := rp.oauth.GetUser(r) 2443 2481 f, err := rp.repoResolver.Resolve(r) 2444 2482 if err != nil { 2445 - log.Println("failed to get repo and knot", err) 2483 + l.Error("failed to get repo and knot", "err", err) 2446 2484 return 2447 2485 } 2448 2486 ··· 2469 2507 head, _ = url.PathUnescape(head) 2470 2508 2471 2509 if base == "" || head == "" { 2472 - log.Printf("invalid comparison") 2510 + l.Error("invalid comparison") 2473 2511 rp.pages.Error404(w) 2474 2512 return 2475 2513 } ··· 2487 2525 2488 2526 branchBytes, err := tangled.RepoBranches(r.Context(), xrpcc, "", 0, repo) 2489 2527 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 2490 - log.Println("failed to call XRPC repo.branches", xrpcerr) 2528 + l.Error("failed to call XRPC repo.branches", "err", xrpcerr) 2491 2529 rp.pages.Error503(w) 2492 2530 return 2493 2531 } 2494 2532 2495 2533 var branches types.RepoBranchesResponse 2496 2534 if err := json.Unmarshal(branchBytes, &branches); err != nil { 2497 - log.Println("failed to decode XRPC branches response", err) 2535 + l.Error("failed to decode XRPC branches response", "err", err) 2498 2536 rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2499 2537 return 2500 2538 } 2501 2539 2502 2540 tagBytes, err := tangled.RepoTags(r.Context(), xrpcc, "", 0, repo) 2503 2541 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 2504 - log.Println("failed to call XRPC repo.tags", xrpcerr) 2542 + l.Error("failed to call XRPC repo.tags", "err", xrpcerr) 2505 2543 rp.pages.Error503(w) 2506 2544 return 2507 2545 } 2508 2546 2509 2547 var tags types.RepoTagsResponse 2510 2548 if err := json.Unmarshal(tagBytes, &tags); err != nil { 2511 - log.Println("failed to decode XRPC tags response", err) 2549 + l.Error("failed to decode XRPC tags response", "err", err) 2512 2550 rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2513 2551 return 2514 2552 } 2515 2553 2516 2554 compareBytes, err := tangled.RepoCompare(r.Context(), xrpcc, repo, base, head) 2517 2555 if xrpcerr := xrpcclient.HandleXrpcErr(err); xrpcerr != nil { 2518 - log.Println("failed to call XRPC repo.compare", xrpcerr) 2556 + l.Error("failed to call XRPC repo.compare", "err", xrpcerr) 2519 2557 rp.pages.Error503(w) 2520 2558 return 2521 2559 } 2522 2560 2523 2561 var formatPatch types.RepoFormatPatchResponse 2524 2562 if err := json.Unmarshal(compareBytes, &formatPatch); err != nil { 2525 - log.Println("failed to decode XRPC compare response", err) 2563 + l.Error("failed to decode XRPC compare response", "err", err) 2526 2564 rp.pages.Notice(w, "compare-error", "Failed to produce comparison. Try again later.") 2527 2565 return 2528 2566 }
+1 -1
appview/signup/signup.go
··· 62 62 disallowed := make(map[string]bool) 63 63 64 64 if filepath == "" { 65 - logger.Debug("no disallowed nicknames file configured") 65 + logger.Warn("no disallowed nicknames file configured") 66 66 return disallowed 67 67 } 68 68
+3 -1
appview/state/knotstream.go
··· 25 25 ) 26 26 27 27 func Knotstream(ctx context.Context, c *config.Config, d *db.DB, enforcer *rbac.Enforcer, posthog posthog.Client) (*ec.Consumer, error) { 28 + logger := log.FromContext(ctx) 29 + logger = log.SubLogger(logger, "knotstream") 30 + 28 31 knots, err := db.GetRegistrations( 29 32 d, 30 33 db.FilterIsNot("registered", "null"), ··· 39 42 srcs[s] = struct{}{} 40 43 } 41 44 42 - logger := log.New("knotstream") 43 45 cache := cache.New(c.Redis.Addr) 44 46 cursorStore := cursor.NewRedisCursorStore(cache) 45 47
+7 -4
appview/state/login.go
··· 2 2 3 3 import ( 4 4 "fmt" 5 - "log" 6 5 "net/http" 7 6 "strings" 8 7 ··· 10 9 ) 11 10 12 11 func (s *State) Login(w http.ResponseWriter, r *http.Request) { 12 + l := s.logger.With("handler", "Login") 13 + 13 14 switch r.Method { 14 15 case http.MethodGet: 15 16 returnURL := r.URL.Query().Get("return_url") ··· 32 33 33 34 // basic handle validation 34 35 if !strings.Contains(handle, ".") { 35 - log.Println("invalid handle format", "raw", handle) 36 + l.Error("invalid handle format", "raw", handle) 36 37 s.pages.Notice( 37 38 w, 38 39 "login-msg", ··· 52 53 } 53 54 54 55 func (s *State) Logout(w http.ResponseWriter, r *http.Request) { 56 + l := s.logger.With("handler", "Logout") 57 + 55 58 err := s.oauth.DeleteSession(w, r) 56 59 if err != nil { 57 - log.Println("failed to logout", "err", err) 60 + l.Error("failed to logout", "err", err) 58 61 } else { 59 - log.Println("logged out successfully") 62 + l.Info("logged out successfully") 60 63 } 61 64 62 65 s.pages.HxRedirect(w, "/login")
+59 -13
appview/state/router.go
··· 205 205 } 206 206 207 207 func (s *State) SpindlesRouter() http.Handler { 208 - logger := log.New("spindles") 208 + logger := log.SubLogger(s.logger, "spindles") 209 209 210 210 spindles := &spindles.Spindles{ 211 211 Db: s.db, ··· 221 221 } 222 222 223 223 func (s *State) KnotsRouter() http.Handler { 224 - logger := log.New("knots") 224 + logger := log.SubLogger(s.logger, "knots") 225 225 226 226 knots := &knots.Knots{ 227 227 Db: s.db, ··· 238 238 } 239 239 240 240 func (s *State) StringsRouter(mw *middleware.Middleware) http.Handler { 241 - logger := log.New("strings") 241 + logger := log.SubLogger(s.logger, "strings") 242 242 243 243 strs := &avstrings.Strings{ 244 244 Db: s.db, ··· 253 253 } 254 254 255 255 func (s *State) IssuesRouter(mw *middleware.Middleware) http.Handler { 256 - issues := issues.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier, s.validator) 256 + issues := issues.New( 257 + s.oauth, 258 + s.repoResolver, 259 + s.pages, 260 + s.idResolver, 261 + s.db, 262 + s.config, 263 + s.notifier, 264 + s.validator, 265 + log.SubLogger(s.logger, "issues"), 266 + ) 257 267 return issues.Router(mw) 258 268 } 259 269 260 270 func (s *State) PullsRouter(mw *middleware.Middleware) http.Handler { 261 - pulls := pulls.New(s.oauth, s.repoResolver, s.pages, s.idResolver, s.db, s.config, s.notifier, s.enforcer) 271 + pulls := pulls.New( 272 + s.oauth, 273 + s.repoResolver, 274 + s.pages, 275 + s.idResolver, 276 + s.db, 277 + s.config, 278 + s.notifier, 279 + s.enforcer, 280 + log.SubLogger(s.logger, "pulls"), 281 + ) 262 282 return pulls.Router(mw) 263 283 } 264 284 265 285 func (s *State) RepoRouter(mw *middleware.Middleware) http.Handler { 266 - logger := log.New("repo") 267 - repo := repo.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.notifier, s.enforcer, logger, s.validator) 286 + repo := repo.New( 287 + s.oauth, 288 + s.repoResolver, 289 + s.pages, 290 + s.spindlestream, 291 + s.idResolver, 292 + s.db, 293 + s.config, 294 + s.notifier, 295 + s.enforcer, 296 + log.SubLogger(s.logger, "repo"), 297 + s.validator, 298 + ) 268 299 return repo.Router(mw) 269 300 } 270 301 271 302 func (s *State) PipelinesRouter(mw *middleware.Middleware) http.Handler { 272 - pipes := pipelines.New(s.oauth, s.repoResolver, s.pages, s.spindlestream, s.idResolver, s.db, s.config, s.enforcer) 303 + pipes := pipelines.New( 304 + s.oauth, 305 + s.repoResolver, 306 + s.pages, 307 + s.spindlestream, 308 + s.idResolver, 309 + s.db, 310 + s.config, 311 + s.enforcer, 312 + log.SubLogger(s.logger, "pipelines"), 313 + ) 273 314 return pipes.Router(mw) 274 315 } 275 316 276 317 func (s *State) LabelsRouter(mw *middleware.Middleware) http.Handler { 277 - ls := labels.New(s.oauth, s.pages, s.db, s.validator, s.enforcer) 318 + ls := labels.New( 319 + s.oauth, 320 + s.pages, 321 + s.db, 322 + s.validator, 323 + s.enforcer, 324 + log.SubLogger(s.logger, "labels"), 325 + ) 278 326 return ls.Router(mw) 279 327 } 280 328 281 329 func (s *State) NotificationsRouter(mw *middleware.Middleware) http.Handler { 282 - notifs := notifications.New(s.db, s.oauth, s.pages) 330 + notifs := notifications.New(s.db, s.oauth, s.pages, log.SubLogger(s.logger, "notifications")) 283 331 return notifs.Router(mw) 284 332 } 285 333 286 334 func (s *State) SignupRouter() http.Handler { 287 - logger := log.New("signup") 288 - 289 - sig := signup.New(s.config, s.db, s.posthog, s.idResolver, s.pages, logger) 335 + sig := signup.New(s.config, s.db, s.posthog, s.idResolver, s.pages, log.SubLogger(s.logger, "signup")) 290 336 return sig.Router() 291 337 }
+3 -1
appview/state/spindlestream.go
··· 22 22 ) 23 23 24 24 func Spindlestream(ctx context.Context, c *config.Config, d *db.DB, enforcer *rbac.Enforcer) (*ec.Consumer, error) { 25 + logger := log.FromContext(ctx) 26 + logger = log.SubLogger(logger, "spindlestream") 27 + 25 28 spindles, err := db.GetSpindles( 26 29 d, 27 30 db.FilterIsNot("verified", "null"), ··· 36 39 srcs[src] = struct{}{} 37 40 } 38 41 39 - logger := log.New("spindlestream") 40 42 cache := cache.New(c.Redis.Addr) 41 43 cursorStore := cursor.NewRedisCursorStore(cache) 42 44
+15 -19
appview/state/state.go
··· 5 5 "database/sql" 6 6 "errors" 7 7 "fmt" 8 - "log" 9 8 "log/slog" 10 9 "net/http" 11 10 "strings" ··· 13 12 14 13 "tangled.org/core/api/tangled" 15 14 "tangled.org/core/appview" 16 - "tangled.org/core/appview/cache" 17 - "tangled.org/core/appview/cache/session" 18 15 "tangled.org/core/appview/config" 19 16 "tangled.org/core/appview/db" 20 17 "tangled.org/core/appview/models" ··· 29 26 "tangled.org/core/eventconsumer" 30 27 "tangled.org/core/idresolver" 31 28 "tangled.org/core/jetstream" 29 + "tangled.org/core/log" 32 30 tlog "tangled.org/core/log" 33 31 "tangled.org/core/rbac" 34 32 "tangled.org/core/tid" ··· 48 46 oauth *oauth.OAuth 49 47 enforcer *rbac.Enforcer 50 48 pages *pages.Pages 51 - sess *session.SessionStore 52 49 idResolver *idresolver.Resolver 53 50 posthog posthog.Client 54 51 jc *jetstream.JetstreamClient ··· 61 58 } 62 59 63 60 func Make(ctx context.Context, config *config.Config) (*State, error) { 64 - d, err := db.Make(config.Core.DbPath) 61 + logger := tlog.FromContext(ctx) 62 + 63 + d, err := db.Make(ctx, config.Core.DbPath) 65 64 if err != nil { 66 65 return nil, fmt.Errorf("failed to create db: %w", err) 67 66 } ··· 73 72 74 73 res, err := idresolver.RedisResolver(config.Redis.ToURL()) 75 74 if err != nil { 76 - log.Printf("failed to create redis resolver: %v", err) 75 + logger.Error("failed to create redis resolver", "err", err) 77 76 res = idresolver.DefaultResolver() 78 77 } 79 78 ··· 82 81 return nil, fmt.Errorf("failed to create posthog client: %w", err) 83 82 } 84 83 85 - pages := pages.NewPages(config, res) 86 - cache := cache.New(config.Redis.Addr) 87 - sess := session.New(cache) 88 - oauth2, err := oauth.New(config, posthog, d, enforcer, res) 84 + pages := pages.NewPages(config, res, log.SubLogger(logger, "pages")) 85 + oauth, err := oauth.New(config, posthog, d, enforcer, res) 89 86 if err != nil { 90 87 return nil, fmt.Errorf("failed to start oauth handler: %w", err) 91 88 } ··· 112 109 tangled.LabelOpNSID, 113 110 }, 114 111 nil, 115 - slog.Default(), 112 + tlog.SubLogger(logger, "jetstream"), 116 113 wrapper, 117 114 false, 118 115 ··· 133 130 Enforcer: enforcer, 134 131 IdResolver: res, 135 132 Config: config, 136 - Logger: tlog.New("ingester"), 133 + Logger: log.SubLogger(logger, "ingester"), 137 134 Validator: validator, 138 135 } 139 136 err = jc.StartJetstream(ctx, ingester.Ingest()) ··· 167 164 state := &State{ 168 165 d, 169 166 notifier, 170 - oauth2, 167 + oauth, 171 168 enforcer, 172 169 pages, 173 - sess, 174 170 res, 175 171 posthog, 176 172 jc, ··· 178 174 repoResolver, 179 175 knotstream, 180 176 spindlestream, 181 - slog.Default(), 177 + logger, 182 178 validator, 183 179 } 184 180 ··· 277 273 } 278 274 timeline, err := db.MakeTimeline(s.db, 50, userDid, filtered) 279 275 if err != nil { 280 - log.Println(err) 276 + s.logger.Error("failed to make timeline", "err", err) 281 277 s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.") 282 278 } 283 279 284 280 repos, err := db.GetTopStarredReposLastWeek(s.db) 285 281 if err != nil { 286 - log.Println(err) 282 + s.logger.Error("failed to get top starred repos", "err", err) 287 283 s.pages.Notice(w, "topstarredrepos", "Unable to load.") 288 284 return 289 285 } ··· 344 340 345 341 timeline, err := db.MakeTimeline(s.db, 5, "", filtered) 346 342 if err != nil { 347 - log.Println(err) 343 + s.logger.Error("failed to make timeline", "err", err) 348 344 s.pages.Notice(w, "timeline", "Uh oh! Failed to load timeline.") 349 345 return 350 346 } 351 347 352 348 repos, err := db.GetTopStarredReposLastWeek(s.db) 353 349 if err != nil { 354 - log.Println(err) 350 + s.logger.Error("failed to get top starred repos", "err", err) 355 351 s.pages.Notice(w, "topstarredrepos", "Unable to load.") 356 352 return 357 353 }
+14 -9
cmd/appview/main.go
··· 2 2 3 3 import ( 4 4 "context" 5 - "log" 6 - "log/slog" 7 5 "net/http" 8 6 "os" 9 7 10 8 "tangled.org/core/appview/config" 11 9 "tangled.org/core/appview/state" 10 + tlog "tangled.org/core/log" 12 11 ) 13 12 14 13 func main() { 15 - slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, nil))) 16 - 17 14 ctx := context.Background() 15 + logger := tlog.New("appview") 16 + ctx = tlog.IntoContext(ctx, logger) 18 17 19 18 c, err := config.LoadConfig(ctx) 20 19 if err != nil { 21 - log.Println("failed to load config", "error", err) 20 + logger.Error("failed to load config", "error", err) 22 21 return 23 22 } 24 23 25 24 state, err := state.Make(ctx, c) 26 25 defer func() { 27 - log.Println(state.Close()) 26 + if err := state.Close(); err != nil { 27 + logger.Error("failed to close state", "err", err) 28 + } 28 29 }() 29 30 30 31 if err != nil { 31 - log.Fatal(err) 32 + logger.Error("failed to start appview", "err", err) 33 + os.Exit(-1) 32 34 } 33 35 34 - log.Println("starting server on", c.Core.ListenAddr) 35 - log.Println(http.ListenAndServe(c.Core.ListenAddr, state.Router())) 36 + logger.Info("starting server", "address", c.Core.ListenAddr) 37 + 38 + if err := http.ListenAndServe(c.Core.ListenAddr, state.Router()); err != nil { 39 + logger.Error("failed to start appview", "err", err) 40 + } 36 41 }
+9 -3
cmd/spindle/main.go
··· 2 2 3 3 import ( 4 4 "context" 5 + "log/slog" 5 6 "os" 6 7 7 - "tangled.org/core/log" 8 + tlog "tangled.org/core/log" 8 9 "tangled.org/core/spindle" 9 10 _ "tangled.org/core/tid" 10 11 ) 11 12 12 13 func main() { 13 - ctx := log.NewContext(context.Background(), "spindle") 14 + logger := tlog.New("spindl3") 15 + slog.SetDefault(logger) 16 + 17 + ctx := context.Background() 18 + ctx = tlog.IntoContext(ctx, logger) 19 + 14 20 err := spindle.Run(ctx) 15 21 if err != nil { 16 - log.FromContext(ctx).Error("error running spindle", "error", err) 22 + logger.Error("error running spindle", "error", err) 17 23 os.Exit(-1) 18 24 } 19 25 }
+13
go.mod
··· 60 60 github.com/ProtonMail/go-crypto v1.3.0 // indirect 61 61 github.com/alecthomas/repr v0.4.0 // indirect 62 62 github.com/anmitsu/go-shlex v0.0.0-20200514113438-38f4b401e2be // indirect 63 + github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect 63 64 github.com/aymerick/douceur v0.2.0 // indirect 64 65 github.com/beorn7/perks v1.0.1 // indirect 65 66 github.com/bmatcuk/doublestar/v4 v4.7.1 // indirect 66 67 github.com/casbin/govaluate v1.3.0 // indirect 67 68 github.com/cenkalti/backoff/v4 v4.3.0 // indirect 68 69 github.com/cespare/xxhash/v2 v2.3.0 // indirect 70 + github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc // indirect 71 + github.com/charmbracelet/lipgloss v1.1.0 // indirect 72 + github.com/charmbracelet/log v0.4.2 // indirect 73 + github.com/charmbracelet/x/ansi v0.8.0 // indirect 74 + github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd // indirect 75 + github.com/charmbracelet/x/term v0.2.1 // indirect 69 76 github.com/cloudflare/circl v1.6.2-0.20250618153321-aa837fd1539d // indirect 70 77 github.com/containerd/errdefs v1.0.0 // indirect 71 78 github.com/containerd/errdefs/pkg v0.3.0 // indirect ··· 84 91 github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 // indirect 85 92 github.com/go-git/go-billy/v5 v5.6.2 // indirect 86 93 github.com/go-jose/go-jose/v3 v3.0.4 // indirect 94 + github.com/go-logfmt/logfmt v0.6.0 // indirect 87 95 github.com/go-logr/logr v1.4.3 // indirect 88 96 github.com/go-logr/stdr v1.2.2 // indirect 89 97 github.com/go-redis/cache/v9 v9.0.0 // indirect ··· 126 134 github.com/lestrrat-go/httprc v1.0.6 // indirect 127 135 github.com/lestrrat-go/iter v1.0.2 // indirect 128 136 github.com/lestrrat-go/option v1.0.1 // indirect 137 + github.com/lucasb-eyer/go-colorful v1.2.0 // indirect 129 138 github.com/mattn/go-isatty v0.0.20 // indirect 139 + github.com/mattn/go-runewidth v0.0.16 // indirect 130 140 github.com/minio/sha256-simd v1.0.1 // indirect 131 141 github.com/mitchellh/mapstructure v1.5.0 // indirect 132 142 github.com/moby/docker-image-spec v1.3.1 // indirect ··· 134 144 github.com/moby/term v0.5.2 // indirect 135 145 github.com/morikuni/aec v1.0.0 // indirect 136 146 github.com/mr-tron/base58 v1.2.0 // indirect 147 + github.com/muesli/termenv v0.16.0 // indirect 137 148 github.com/multiformats/go-base32 v0.1.0 // indirect 138 149 github.com/multiformats/go-base36 v0.2.0 // indirect 139 150 github.com/multiformats/go-multibase v0.2.0 // indirect ··· 152 163 github.com/prometheus/client_model v0.6.2 // indirect 153 164 github.com/prometheus/common v0.64.0 // indirect 154 165 github.com/prometheus/procfs v0.16.1 // indirect 166 + github.com/rivo/uniseg v0.4.7 // indirect 155 167 github.com/ryanuber/go-glob v1.0.0 // indirect 156 168 github.com/segmentio/asm v1.2.0 // indirect 157 169 github.com/sergi/go-diff v1.3.2-0.20230802210424-5b0b94c5c0d3 // indirect ··· 160 172 github.com/vmihailenco/msgpack/v5 v5.4.1 // indirect 161 173 github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 162 174 github.com/wyatt915/treeblood v0.1.15 // indirect 175 + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect 163 176 gitlab.com/staticnoise/goldmark-callout v0.0.0-20240609120641-6366b799e4ab // indirect 164 177 gitlab.com/yawning/secp256k1-voi v0.0.0-20230925100816-f2616030848b // indirect 165 178 gitlab.com/yawning/tuplehash v0.0.0-20230713102510-df83abbf9a02 // indirect
+27
go.sum
··· 19 19 github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs= 20 20 github.com/avast/retry-go/v4 v4.6.1 h1:VkOLRubHdisGrHnTu89g08aQEWEgRU7LVEop3GbIcMk= 21 21 github.com/avast/retry-go/v4 v4.6.1/go.mod h1:V6oF8njAwxJ5gRo1Q7Cxab24xs5NCWZBeaHHBklR8mA= 22 + github.com/aymanbagabas/go-osc52/v2 v2.0.1 h1:HwpRHbFMcZLEVr42D4p7XBqjyuxQH5SMiErDT4WkJ2k= 23 + github.com/aymanbagabas/go-osc52/v2 v2.0.1/go.mod h1:uYgXzlJ7ZpABp8OJ+exZzJJhRNQ2ASbcXHWsFqH8hp8= 22 24 github.com/aymerick/douceur v0.2.0 h1:Mv+mAeH1Q+n9Fr+oyamOlAkUNPWPlA8PPGR0QAaYuPk= 23 25 github.com/aymerick/douceur v0.2.0/go.mod h1:wlT5vV2O3h55X9m7iVYN0TBM0NH/MmbLnd30/FjWUq4= 24 26 github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM= ··· 48 50 github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 49 51 github.com/cespare/xxhash/v2 v2.3.0 h1:UL815xU9SqsFlibzuggzjXhog7bL6oX9BbNZnL2UFvs= 50 52 github.com/cespare/xxhash/v2 v2.3.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= 53 + github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc h1:4pZI35227imm7yK2bGPcfpFEmuY1gc2YSTShr4iJBfs= 54 + github.com/charmbracelet/colorprofile v0.2.3-0.20250311203215-f60798e515dc/go.mod h1:X4/0JoqgTIPSFcRA/P6INZzIuyqdFY5rm8tb41s9okk= 55 + github.com/charmbracelet/lipgloss v1.1.0 h1:vYXsiLHVkK7fp74RkV7b2kq9+zDLoEU4MZoFqR/noCY= 56 + github.com/charmbracelet/lipgloss v1.1.0/go.mod h1:/6Q8FR2o+kj8rz4Dq0zQc3vYf7X+B0binUUBwA0aL30= 57 + github.com/charmbracelet/log v0.4.2 h1:hYt8Qj6a8yLnvR+h7MwsJv/XvmBJXiueUcI3cIxsyig= 58 + github.com/charmbracelet/log v0.4.2/go.mod h1:qifHGX/tc7eluv2R6pWIpyHDDrrb/AG71Pf2ysQu5nw= 59 + github.com/charmbracelet/x/ansi v0.8.0 h1:9GTq3xq9caJW8ZrBTe0LIe2fvfLR/bYXKTx2llXn7xE= 60 + github.com/charmbracelet/x/ansi v0.8.0/go.mod h1:wdYl/ONOLHLIVmQaxbIYEC/cRKOQyjTkowiI4blgS9Q= 61 + github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd h1:vy0GVL4jeHEwG5YOXDmi86oYw2yuYUGqz6a8sLwg0X8= 62 + github.com/charmbracelet/x/cellbuf v0.0.13-0.20250311204145-2c3ea96c31dd/go.mod h1:xe0nKWGd3eJgtqZRaN9RjMtK7xUYchjzPr7q6kcvCCs= 63 + github.com/charmbracelet/x/term v0.2.1 h1:AQeHeLZ1OqSXhrAWpYUtZyX1T3zVxfpZuEQMIQaGIAQ= 64 + github.com/charmbracelet/x/term v0.2.1/go.mod h1:oQ4enTYFV7QN4m0i9mzHrViD7TQKvNEEkHUMCmsxdUg= 51 65 github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= 52 66 github.com/chzyer/readline v0.0.0-20180603132655-2972be24d48e/go.mod h1:nSuG5e5PlCu98SY8svDHJxuZscDgtXS6KTTbou5AhLI= 53 67 github.com/chzyer/test v0.0.0-20180213035817-a1ea475d72b1/go.mod h1:Q3SI9o4m/ZMnBNeIyt5eFwwo7qiLfzFZmjNmxjkiQlU= ··· 120 134 github.com/go-git/go-git-fixtures/v5 v5.0.0-20241203230421-0753e18f8f03/go.mod h1:hMKrMnUE4W0SJ7bFyM00dyz/HoknZoptGWzrj6M+dEM= 121 135 github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= 122 136 github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= 137 + github.com/go-logfmt/logfmt v0.6.0 h1:wGYYu3uicYdqXVgoYbvnkrPVXkuLM1p1ifugDMEdRi4= 138 + github.com/go-logfmt/logfmt v0.6.0/go.mod h1:WYhtIu8zTZfxdn5+rREduYbwxfcBr/Vr6KEVveWlfTs= 123 139 github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 124 140 github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= 125 141 github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= ··· 276 292 github.com/lestrrat-go/jwx/v2 v2.1.6/go.mod h1:Y722kU5r/8mV7fYDifjug0r8FK8mZdw0K0GpJw/l8pU= 277 293 github.com/lestrrat-go/option v1.0.1 h1:oAzP2fvZGQKWkvHa1/SAcFolBEca1oN+mQ7eooNBEYU= 278 294 github.com/lestrrat-go/option v1.0.1/go.mod h1:5ZHFbivi4xwXxhxY9XHDe2FHo6/Z7WWmtT7T5nBBp3I= 295 + github.com/lucasb-eyer/go-colorful v1.2.0 h1:1nnpGOrhyZZuNyfu1QjKiUICQ74+3FNCN69Aj6K7nkY= 296 + github.com/lucasb-eyer/go-colorful v1.2.0/go.mod h1:R4dSotOR9KMtayYi1e77YzuveK+i7ruzyGqttikkLy0= 279 297 github.com/mattn/go-colorable v0.1.14 h1:9A9LHSqF/7dyVVX6g0U9cwm9pG3kP9gSzcuIPHPsaIE= 280 298 github.com/mattn/go-colorable v0.1.14/go.mod h1:6LmQG8QLFO4G5z1gPvYEzlUgJ2wF+stgPZH1UqBm1s8= 281 299 github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= 282 300 github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= 301 + github.com/mattn/go-runewidth v0.0.16 h1:E5ScNMtiwvlvB5paMFdw9p4kSQzbXFikJ5SQO6TULQc= 302 + github.com/mattn/go-runewidth v0.0.16/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w= 283 303 github.com/mattn/go-sqlite3 v1.14.24 h1:tpSp2G2KyMnnQu99ngJ47EIkWVmliIizyZBfPrBWDRM= 284 304 github.com/mattn/go-sqlite3 v1.14.24/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= 285 305 github.com/microcosm-cc/bluemonday v1.0.27 h1:MpEUotklkwCSLeH+Qdx1VJgNqLlpY2KXwXFM08ygZfk= ··· 300 320 github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc= 301 321 github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= 302 322 github.com/mr-tron/base58 v1.2.0/go.mod h1:BinMc/sQntlIE1frQmRFPUoPA1Zkr8VRgBdjWI2mNwc= 323 + github.com/muesli/termenv v0.16.0 h1:S5AlUN9dENB57rsbnkPyfdGuWIlkmzJjbFf0Tf5FWUc= 324 + github.com/muesli/termenv v0.16.0/go.mod h1:ZRfOIKPFDYQoDFF4Olj7/QJbW60Ol/kL1pU3VfY/Cnk= 303 325 github.com/multiformats/go-base32 v0.1.0 h1:pVx9xoSPqEIQG8o+UbAe7DNi51oej1NtK+aGkbLYxPE= 304 326 github.com/multiformats/go-base32 v0.1.0/go.mod h1:Kj3tFY6zNr+ABYMqeUNeGvkIC/UYgtWibDcT0rExnbI= 305 327 github.com/multiformats/go-base36 v0.2.0 h1:lFsAbNOGeKtuKozrtBsAkSVhv1p9D0/qedU9rQyccr0= ··· 377 399 github.com/redis/go-redis/v9 v9.7.3/go.mod h1:bGUrSggJ9X9GUmZpZNEOQKaANxSGgOEBRltRTZHSvrA= 378 400 github.com/resend/resend-go/v2 v2.15.0 h1:B6oMEPf8IEQwn2Ovx/9yymkESLDSeNfLFaNMw+mzHhE= 379 401 github.com/resend/resend-go/v2 v2.15.0/go.mod h1:3YCb8c8+pLiqhtRFXTyFwlLvfjQtluxOr9HEh2BwCkQ= 402 + github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc= 403 + github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= 404 + github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= 380 405 github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= 381 406 github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= 382 407 github.com/rogpeppe/go-internal v1.14.1 h1:UQB4HGPB6osV0SQTLymcB4TgvyWu6ZyliaW0tI/otEQ= ··· 434 459 github.com/wyatt915/goldmark-treeblood v0.0.0-20250825231212-5dcbdb2f4b57/go.mod h1:BxSCWByWSRSuembL3cDG1IBUbkBoO/oW/6tF19aA4hs= 435 460 github.com/wyatt915/treeblood v0.1.15 h1:3KZ3o2LpcKZAzOLqMoW9qeUzKEaKArKpbcPpTkNfQC8= 436 461 github.com/wyatt915/treeblood v0.1.15/go.mod h1:i7+yhhmzdDP17/97pIsOSffw74EK/xk+qJ0029cSXUY= 462 + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e h1:JVG44RsyaB9T2KIHavMF/ppJZNG9ZpyihvCd0w101no= 463 + github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e/go.mod h1:RbqR21r5mrJuqunuUZ/Dhy/avygyECGrLceyNeo4LiM= 437 464 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 438 465 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= 439 466 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
+1 -1
jetstream/jetstream.go
··· 114 114 115 115 sched := sequential.NewScheduler(j.ident, logger, j.withDidFilter(processFunc)) 116 116 117 - client, err := client.NewClient(j.cfg, log.New("jetstream"), sched) 117 + client, err := client.NewClient(j.cfg, logger, sched) 118 118 if err != nil { 119 119 return fmt.Errorf("failed to create jetstream client: %w", err) 120 120 }
+39
nix/gomod2nix.toml
··· 29 29 [mod."github.com/avast/retry-go/v4"] 30 30 version = "v4.6.1" 31 31 hash = "sha256-PeZc8k4rDV64+k8nZt/oy1YNVbLevltXP3ZD1jf6Z6k=" 32 + [mod."github.com/aymanbagabas/go-osc52/v2"] 33 + version = "v2.0.1" 34 + hash = "sha256-6Bp0jBZ6npvsYcKZGHHIUSVSTAMEyieweAX2YAKDjjg=" 32 35 [mod."github.com/aymerick/douceur"] 33 36 version = "v0.2.0" 34 37 hash = "sha256-NiBX8EfOvLXNiK3pJaZX4N73YgfzdrzRXdiBFe3X3sE=" ··· 63 66 [mod."github.com/cespare/xxhash/v2"] 64 67 version = "v2.3.0" 65 68 hash = "sha256-7hRlwSR+fos1kx4VZmJ/7snR7zHh8ZFKX+qqqqGcQpY=" 69 + [mod."github.com/charmbracelet/colorprofile"] 70 + version = "v0.2.3-0.20250311203215-f60798e515dc" 71 + hash = "sha256-D9E/bMOyLXAUVOHA1/6o3i+vVmLfwIMOWib6sU7A6+Q=" 72 + [mod."github.com/charmbracelet/lipgloss"] 73 + version = "v1.1.0" 74 + hash = "sha256-RHsRT2EZ1nDOElxAK+6/DC9XAaGVjDTgPvRh3pyCfY4=" 75 + [mod."github.com/charmbracelet/log"] 76 + version = "v0.4.2" 77 + hash = "sha256-3w1PCM/c4JvVEh2d0sMfv4C77Xs1bPa1Ea84zdynC7I=" 78 + [mod."github.com/charmbracelet/x/ansi"] 79 + version = "v0.8.0" 80 + hash = "sha256-/YyDkGrULV2BtnNk3ojeSl0nUWQwIfIdW7WJuGbAZas=" 81 + [mod."github.com/charmbracelet/x/cellbuf"] 82 + version = "v0.0.13-0.20250311204145-2c3ea96c31dd" 83 + hash = "sha256-XAhCOt8qJ2vR77lH1ez0IVU1/2CaLTq9jSmrHVg5HHU=" 84 + [mod."github.com/charmbracelet/x/term"] 85 + version = "v0.2.1" 86 + hash = "sha256-VBkCZLI90PhMasftGw3403IqoV7d3E5WEGAIVrN5xQM=" 66 87 [mod."github.com/cloudflare/circl"] 67 88 version = "v1.6.2-0.20250618153321-aa837fd1539d" 68 89 hash = "sha256-0s/i/XmMcuvPQ+qK9OIU5KxwYZyLVXRtdlYvIXRJT3Y=" ··· 145 166 [mod."github.com/go-jose/go-jose/v3"] 146 167 version = "v3.0.4" 147 168 hash = "sha256-RrLHCu9l6k0XVobdZQJ9Sx/VTQcWjrdLR5BEG7yXTEQ=" 169 + [mod."github.com/go-logfmt/logfmt"] 170 + version = "v0.6.0" 171 + hash = "sha256-RtIG2qARd5sT10WQ7F3LR8YJhS8exs+KiuUiVf75bWg=" 148 172 [mod."github.com/go-logr/logr"] 149 173 version = "v1.4.3" 150 174 hash = "sha256-Nnp/dEVNMxLp3RSPDHZzGbI8BkSNuZMX0I0cjWKXXLA=" ··· 298 322 [mod."github.com/lestrrat-go/option"] 299 323 version = "v1.0.1" 300 324 hash = "sha256-jVcIYYVsxElIS/l2akEw32vdEPR8+anR6oeT1FoYULI=" 325 + [mod."github.com/lucasb-eyer/go-colorful"] 326 + version = "v1.2.0" 327 + hash = "sha256-Gg9dDJFCTaHrKHRR1SrJgZ8fWieJkybljybkI9x0gyE=" 301 328 [mod."github.com/mattn/go-isatty"] 302 329 version = "v0.0.20" 303 330 hash = "sha256-qhw9hWtU5wnyFyuMbKx+7RB8ckQaFQ8D+8GKPkN3HHQ=" 331 + [mod."github.com/mattn/go-runewidth"] 332 + version = "v0.0.16" 333 + hash = "sha256-NC+ntvwIpqDNmXb7aixcg09il80ygq6JAnW0Gb5b/DQ=" 304 334 [mod."github.com/mattn/go-sqlite3"] 305 335 version = "v1.14.24" 306 336 hash = "sha256-taGKFZFQlR5++5b2oZ1dYS3RERKv6yh1gniNWhb4egg=" ··· 328 358 [mod."github.com/mr-tron/base58"] 329 359 version = "v1.2.0" 330 360 hash = "sha256-8FzMu3kHUbBX10pUdtGf59Ag7BNupx8ZHeUaodR1/Vk=" 361 + [mod."github.com/muesli/termenv"] 362 + version = "v0.16.0" 363 + hash = "sha256-hGo275DJlyLtcifSLpWnk8jardOksdeX9lH4lBeE3gI=" 331 364 [mod."github.com/multiformats/go-base32"] 332 365 version = "v0.1.0" 333 366 hash = "sha256-O2IM7FB+Y9MkDdZztyQL5F8oEnmON2Yew7XkotQziio=" ··· 394 427 [mod."github.com/resend/resend-go/v2"] 395 428 version = "v2.15.0" 396 429 hash = "sha256-1lMoxuMLQXaNWFKadS6rpztAKwvIl3/LWMXqw7f5WYg=" 430 + [mod."github.com/rivo/uniseg"] 431 + version = "v0.4.7" 432 + hash = "sha256-rDcdNYH6ZD8KouyyiZCUEy8JrjOQoAkxHBhugrfHjFo=" 397 433 [mod."github.com/ryanuber/go-glob"] 398 434 version = "v1.0.0" 399 435 hash = "sha256-YkMl1utwUhi3E0sHK23ISpAsPyj4+KeXyXKoFYGXGVY=" ··· 440 476 [mod."github.com/wyatt915/treeblood"] 441 477 version = "v0.1.15" 442 478 hash = "sha256-hb99exdkoY2Qv8WdDxhwgPXGbEYimUr6wFtPXEvcO9g=" 479 + [mod."github.com/xo/terminfo"] 480 + version = "v0.0.0-20220910002029-abceb7e1c41e" 481 + hash = "sha256-GyCDxxMQhXA3Pi/TsWXpA8cX5akEoZV7CFx4RO3rARU=" 443 482 [mod."github.com/yuin/goldmark"] 444 483 version = "v1.7.13" 445 484 hash = "sha256-vBCxZrPYPc8x/nvAAv3Au59dCCyfS80Vw3/a9EXK7TE="
+5 -4
xrpc/serviceauth/service_auth.go
··· 9 9 10 10 "github.com/bluesky-social/indigo/atproto/auth" 11 11 "tangled.org/core/idresolver" 12 + "tangled.org/core/log" 12 13 xrpcerr "tangled.org/core/xrpc/errors" 13 14 ) 14 15 ··· 22 23 23 24 func NewServiceAuth(logger *slog.Logger, resolver *idresolver.Resolver, audienceDid string) *ServiceAuth { 24 25 return &ServiceAuth{ 25 - logger: logger, 26 + logger: log.SubLogger(logger, "serviceauth"), 26 27 resolver: resolver, 27 28 audienceDid: audienceDid, 28 29 } ··· 30 31 31 32 func (sa *ServiceAuth) VerifyServiceAuth(next http.Handler) http.Handler { 32 33 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 33 - l := sa.logger.With("url", r.URL) 34 - 35 34 token := r.Header.Get("Authorization") 36 35 token = strings.TrimPrefix(token, "Bearer ") 37 36 ··· 42 41 43 42 did, err := s.Validate(r.Context(), token, nil) 44 43 if err != nil { 45 - l.Error("signature verification failed", "err", err) 44 + sa.logger.Error("signature verification failed", "err", err) 46 45 writeError(w, xrpcerr.AuthError(err), http.StatusForbidden) 47 46 return 48 47 } 48 + 49 + sa.logger.Debug("valid signature", ActorDid, did) 49 50 50 51 r = r.WithContext( 51 52 context.WithValue(r.Context(), ActorDid, did),