Monorepo for Tangled
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

appview/state: replace log package with structured slog logging

Replace all log.Println/log.Printf calls across follow.go, star.go,
reaction.go, gfi.go, and profile.go with s.logger.Error/Warn/Info using
structured key-value pairs. Each handler opens with a child logger via
s.logger.With("handler", "FuncName"). Firehose-idempotent delete failures
(follow, star, reaction) use Warn; all other failures use Error.

Signed-off-by: Matías Insaurralde <matias@insaurral.de>

authored by

Matías Insaurralde and committed by tangled.org 209a6808 5b01f997

+66 -61
+13 -13
appview/state/follow.go
··· 1 1 package state 2 2 3 3 import ( 4 - "log" 5 4 "net/http" 6 5 "time" 7 6 ··· 15 14 ) 16 15 17 16 func (s *State) Follow(w http.ResponseWriter, r *http.Request) { 17 + l := s.logger.With("handler", "Follow") 18 18 currentUser := s.oauth.GetMultiAccountUser(r) 19 19 20 20 subject := r.URL.Query().Get("subject") 21 21 if subject == "" { 22 - log.Println("invalid form") 22 + l.Warn("invalid form") 23 23 return 24 24 } 25 25 26 26 subjectIdent, err := s.idResolver.ResolveIdent(r.Context(), subject) 27 27 if err != nil { 28 - log.Println("failed to follow, invalid did") 28 + l.Error("failed to follow, invalid did", "subject", subject, "err", err) 29 29 return 30 30 } 31 31 32 32 if currentUser.Active.Did == subjectIdent.DID.String() { 33 - log.Println("cant follow or unfollow yourself") 33 + l.Warn("cant follow or unfollow yourself") 34 34 return 35 35 } 36 36 37 37 client, err := s.oauth.AuthorizedClient(r) 38 38 if err != nil { 39 - log.Println("failed to authorize client") 39 + l.Error("failed to authorize client", "err", err) 40 40 return 41 41 } 42 42 ··· 55 55 }}, 56 56 }) 57 57 if err != nil { 58 - log.Println("failed to create atproto record", err) 58 + l.Error("failed to create atproto record", "err", err) 59 59 return 60 60 } 61 61 62 - log.Println("created atproto record: ", resp.Uri) 62 + l.Info("created atproto record", "uri", resp.Uri) 63 63 64 64 follow := &models.Follow{ 65 65 UserDid: currentUser.Active.Did, ··· 69 69 70 70 err = db.AddFollow(s.db, follow) 71 71 if err != nil { 72 - log.Println("failed to follow", err) 72 + l.Error("failed to follow", "err", err) 73 73 return 74 74 } 75 75 ··· 77 77 78 78 followStats, err := db.GetFollowerFollowingCount(s.db, subjectIdent.DID.String()) 79 79 if err != nil { 80 - log.Println("failed to get follow stats", err) 80 + l.Error("failed to get follow stats", "err", err) 81 81 } 82 82 83 83 s.pages.FollowFragment(w, pages.FollowFragmentParams{ ··· 91 91 // find the record in the db 92 92 follow, err := db.GetFollow(s.db, currentUser.Active.Did, subjectIdent.DID.String()) 93 93 if err != nil { 94 - log.Println("failed to get follow relationship") 94 + l.Error("failed to get follow relationship", "err", err) 95 95 return 96 96 } 97 97 ··· 102 102 }) 103 103 104 104 if err != nil { 105 - log.Println("failed to unfollow") 105 + l.Error("failed to unfollow", "err", err) 106 106 return 107 107 } 108 108 109 109 err = db.DeleteFollowByRkey(s.db, currentUser.Active.Did, follow.Rkey) 110 110 if err != nil { 111 - log.Println("failed to delete follow from DB") 111 + l.Warn("failed to delete follow from DB", "err", err) 112 112 // this is not an issue, the firehose event might have already done this 113 113 } 114 114 115 115 followStats, err := db.GetFollowerFollowingCount(s.db, subjectIdent.DID.String()) 116 116 if err != nil { 117 - log.Println("failed to get follow stats", err) 117 + l.Error("failed to get follow stats", "err", err) 118 118 } 119 119 120 120 s.pages.FollowFragment(w, pages.FollowFragmentParams{
+5 -5
appview/state/gfi.go
··· 1 1 package state 2 2 3 3 import ( 4 - "log" 5 4 "net/http" 6 5 "sort" 7 6 ··· 15 14 ) 16 15 17 16 func (s *State) GoodFirstIssues(w http.ResponseWriter, r *http.Request) { 17 + l := s.logger.With("handler", "GoodFirstIssues") 18 18 user := s.oauth.GetMultiAccountUser(r) 19 19 20 20 page := pagination.FromContext(r.Context()) ··· 23 23 24 24 gfiLabelDef, err := db.GetLabelDefinition(s.db, orm.FilterEq("at_uri", goodFirstIssueLabel)) 25 25 if err != nil { 26 - log.Println("failed to get gfi label def", err) 26 + l.Error("failed to get gfi label def", "err", err) 27 27 s.pages.Error500(w) 28 28 return 29 29 } 30 30 31 31 repoLabels, err := db.GetRepoLabels(s.db, orm.FilterEq("label_at", goodFirstIssueLabel)) 32 32 if err != nil { 33 - log.Println("failed to get repo labels", err) 33 + l.Error("failed to get repo labels", "err", err) 34 34 s.pages.Error503(w) 35 35 return 36 36 } ··· 60 60 orm.FilterEq("open", 1), 61 61 ) 62 62 if err != nil { 63 - log.Println("failed to get issues", err) 63 + l.Error("failed to get issues", "err", err) 64 64 s.pages.Error503(w) 65 65 return 66 66 } ··· 135 135 if len(uriList) > 0 { 136 136 allLabelDefs, err = db.GetLabelDefinitions(s.db, orm.FilterIn("at_uri", uriList)) 137 137 if err != nil { 138 - log.Println("failed to fetch labels", err) 138 + l.Error("failed to fetch labels", "err", err) 139 139 } 140 140 } 141 141 }
+23 -18
appview/state/profile.go
··· 3 3 import ( 4 4 "context" 5 5 "fmt" 6 - "log" 7 6 "net/http" 8 7 "slices" 9 8 "strings" ··· 418 417 419 418 followStatsMap, err := db.GetFollowerFollowingCounts(s.db, followDids) 420 419 if err != nil { 421 - log.Printf("getting follow counts for %s: %s", followDids, err) 420 + l.Error("getting follow counts", "followDids", followDids, "err", err) 422 421 } 423 422 424 423 loggedInUserFollowing := make(map[string]struct{}) ··· 637 636 } 638 637 639 638 func (s *State) UpdateProfileBio(w http.ResponseWriter, r *http.Request) { 639 + l := s.logger.With("handler", "UpdateProfileBio") 640 640 user := s.oauth.GetMultiAccountUser(r) 641 641 642 642 err := r.ParseForm() 643 643 if err != nil { 644 - log.Println("invalid profile update form", err) 644 + l.Error("invalid profile update form", "err", err) 645 645 s.pages.Notice(w, "update-profile", "Invalid form.") 646 646 return 647 647 } 648 648 649 649 profile, err := db.GetProfile(s.db, user.Active.Did) 650 650 if err != nil { 651 - log.Printf("getting profile data for %s: %s", user.Active.Did, err) 651 + l.Error("getting profile data", "did", user.Active.Did, "err", err) 652 652 } 653 653 if profile == nil { 654 654 profile = &models.Profile{Did: user.Active.Did} ··· 691 691 profile.Stats[1].Kind = models.ParseVanityStatKind(stat1) 692 692 693 693 if err := db.ValidateProfile(s.db, profile); err != nil { 694 - log.Println("invalid profile", err) 694 + l.Error("invalid profile", "err", err) 695 695 s.pages.Notice(w, "update-profile", err.Error()) 696 696 return 697 697 } ··· 700 700 } 701 701 702 702 func (s *State) UpdateProfilePins(w http.ResponseWriter, r *http.Request) { 703 + l := s.logger.With("handler", "UpdateProfilePins") 703 704 user := s.oauth.GetMultiAccountUser(r) 704 705 705 706 err := r.ParseForm() 706 707 if err != nil { 707 - log.Println("invalid profile update form", err) 708 + l.Error("invalid profile update form", "err", err) 708 709 s.pages.Notice(w, "update-profile", "Invalid form.") 709 710 return 710 711 } 711 712 712 713 profile, err := db.GetProfile(s.db, user.Active.Did) 713 714 if err != nil { 714 - log.Printf("getting profile data for %s: %s", user.Active.Did, err) 715 + l.Error("getting profile data", "did", user.Active.Did, "err", err) 715 716 } 716 717 if profile == nil { 717 718 profile = &models.Profile{Did: user.Active.Did} ··· 721 722 var pinnedRepos [6]string 722 723 for key, values := range r.Form { 723 724 if i >= 6 { 724 - log.Println("invalid pin update form", err) 725 + l.Warn("too many pinned repos") 725 726 s.pages.Notice(w, "update-profile", "Only 6 repositories can be pinned at a time.") 726 727 return 727 728 } ··· 736 737 } 737 738 738 739 func (s *State) updateProfile(profile *models.Profile, w http.ResponseWriter, r *http.Request) { 740 + l := s.logger.With("handler", "updateProfile") 739 741 user := s.oauth.GetMultiAccountUser(r) 740 742 tx, err := s.db.BeginTx(r.Context(), nil) 741 743 if err != nil { 742 - log.Println("failed to start transaction", err) 744 + l.Error("failed to start transaction", "err", err) 743 745 s.pages.Notice(w, "update-profile", "Failed to update profile, try again later.") 744 746 return 745 747 } 746 748 747 749 client, err := s.oauth.AuthorizedClient(r) 748 750 if err != nil { 749 - log.Println("failed to get authorized client", err) 751 + l.Error("failed to get authorized client", "err", err) 750 752 s.pages.Notice(w, "update-profile", "Failed to update profile, try again later.") 751 753 return 752 754 } ··· 792 794 SwapRecord: cid, 793 795 }) 794 796 if err != nil { 795 - log.Println("failed to update profile", err) 797 + l.Error("failed to update profile on PDS", "err", err) 796 798 s.pages.Notice(w, "update-profile", "Failed to update PDS, try again later.") 797 799 return 798 800 } 799 801 800 802 err = db.UpsertProfile(tx, profile) 801 803 if err != nil { 802 - log.Println("failed to update profile", err) 804 + l.Error("failed to update profile in DB", "err", err) 803 805 s.pages.Notice(w, "update-profile", "Failed to update profile, try again later.") 804 806 return 805 807 } ··· 810 812 } 811 813 812 814 func (s *State) EditBioFragment(w http.ResponseWriter, r *http.Request) { 815 + l := s.logger.With("handler", "EditBioFragment") 813 816 user := s.oauth.GetMultiAccountUser(r) 814 817 815 818 profile, err := db.GetProfile(s.db, user.Active.Did) 816 819 if err != nil { 817 - log.Printf("getting profile data for %s: %s", user.Active.Did, err) 820 + l.Error("getting profile data", "did", user.Active.Did, "err", err) 818 821 } 819 822 if profile == nil { 820 823 profile = &models.Profile{Did: user.Active.Did} ··· 834 837 } 835 838 836 839 func (s *State) EditPinsFragment(w http.ResponseWriter, r *http.Request) { 840 + l := s.logger.With("handler", "EditPinsFragment") 837 841 user := s.oauth.GetMultiAccountUser(r) 838 842 839 843 profile, err := db.GetProfile(s.db, user.Active.Did) 840 844 if err != nil { 841 - log.Printf("getting profile data for %s: %s", user.Active.Did, err) 845 + l.Error("getting profile data", "did", user.Active.Did, "err", err) 842 846 } 843 847 if profile == nil { 844 848 profile = &models.Profile{Did: user.Active.Did} ··· 846 850 847 851 repos, err := db.GetRepos(s.db, orm.FilterEq("did", user.Active.Did)) 848 852 if err != nil { 849 - log.Printf("getting repos for %s: %s", user.Active.Did, err) 853 + l.Error("getting repos", "did", user.Active.Did, "err", err) 850 854 } 851 855 852 856 collaboratingRepos, err := db.CollaboratingIn(s.db, user.Active.Did) 853 857 if err != nil { 854 - log.Printf("getting collaborating repos for %s: %s", user.Active.Did, err) 858 + l.Error("getting collaborating repos", "did", user.Active.Did, "err", err) 855 859 } 856 860 857 861 allRepos := []pages.PinnedRepo{} ··· 1071 1075 } 1072 1076 1073 1077 func (s *State) UpdateProfilePunchcardSetting(w http.ResponseWriter, r *http.Request) { 1078 + l := s.logger.With("handler", "UpdateProfilePunchcardSetting") 1074 1079 err := r.ParseForm() 1075 1080 if err != nil { 1076 - log.Println("invalid profile update form", err) 1081 + l.Error("invalid profile update form", "err", err) 1077 1082 return 1078 1083 } 1079 1084 user := s.oauth.GetUser(r) ··· 1090 1095 1091 1096 err = db.UpsertPunchcardPreference(s.db, user.Did, hideMine, hideOthers) 1092 1097 if err != nil { 1093 - log.Println("failed to update punchcard preferences", err) 1098 + l.Error("failed to update punchcard preferences", "err", err) 1094 1099 return 1095 1100 } 1096 1101
+13 -13
appview/state/reaction.go
··· 1 1 package state 2 2 3 3 import ( 4 - "log" 5 4 "net/http" 6 5 "time" 7 6 ··· 17 16 ) 18 17 19 18 func (s *State) React(w http.ResponseWriter, r *http.Request) { 19 + l := s.logger.With("handler", "React") 20 20 currentUser := s.oauth.GetMultiAccountUser(r) 21 21 22 22 subject := r.URL.Query().Get("subject") 23 23 if subject == "" { 24 - log.Println("invalid form") 24 + l.Warn("invalid form") 25 25 return 26 26 } 27 27 28 28 subjectUri, err := syntax.ParseATURI(subject) 29 29 if err != nil { 30 - log.Println("invalid form") 30 + l.Warn("invalid form", "subject", subject, "err", err) 31 31 return 32 32 } 33 33 34 34 reactionKind, ok := models.ParseReactionKind(r.URL.Query().Get("kind")) 35 35 if !ok { 36 - log.Println("invalid reaction kind") 36 + l.Warn("invalid reaction kind", "kind", r.URL.Query().Get("kind")) 37 37 return 38 38 } 39 39 40 40 client, err := s.oauth.AuthorizedClient(r) 41 41 if err != nil { 42 - log.Println("failed to authorize client", err) 42 + l.Error("failed to authorize client", "err", err) 43 43 return 44 44 } 45 45 ··· 60 60 }, 61 61 }) 62 62 if err != nil { 63 - log.Println("failed to create atproto record", err) 63 + l.Error("failed to create atproto record", "err", err) 64 64 return 65 65 } 66 66 67 67 err = db.AddReaction(s.db, currentUser.Active.Did, subjectUri, reactionKind, rkey) 68 68 if err != nil { 69 - log.Println("failed to react", err) 69 + l.Error("failed to react", "err", err) 70 70 return 71 71 } 72 72 73 73 reactionMap, err := db.GetReactionMap(s.db, 20, subjectUri) 74 74 if err != nil { 75 - log.Println("failed to get reactions for ", subjectUri) 75 + l.Error("failed to get reactions", "subjectUri", subjectUri, "err", err) 76 76 } 77 77 78 - log.Println("created atproto record: ", resp.Uri) 78 + l.Info("created atproto record", "uri", resp.Uri) 79 79 80 80 s.pages.ThreadReactionFragment(w, pages.ThreadReactionFragmentParams{ 81 81 ThreadAt: subjectUri, ··· 89 89 case http.MethodDelete: 90 90 reaction, err := db.GetReaction(s.db, currentUser.Active.Did, subjectUri, reactionKind) 91 91 if err != nil { 92 - log.Println("failed to get reaction relationship for", currentUser.Active.Did, subjectUri) 92 + l.Error("failed to get reaction relationship", "did", currentUser.Active.Did, "subjectUri", subjectUri, "err", err) 93 93 return 94 94 } 95 95 ··· 100 100 }) 101 101 102 102 if err != nil { 103 - log.Println("failed to remove reaction") 103 + l.Error("failed to remove reaction", "err", err) 104 104 return 105 105 } 106 106 107 107 err = db.DeleteReactionByRkey(s.db, currentUser.Active.Did, reaction.Rkey) 108 108 if err != nil { 109 - log.Println("failed to delete reaction from DB") 109 + l.Warn("failed to delete reaction from DB", "err", err) 110 110 // this is not an issue, the firehose event might have already done this 111 111 } 112 112 113 113 reactionMap, err := db.GetReactionMap(s.db, 20, subjectUri) 114 114 if err != nil { 115 - log.Println("failed to get reactions for ", subjectUri) 115 + l.Error("failed to get reactions", "subjectUri", subjectUri, "err", err) 116 116 return 117 117 } 118 118
+12 -12
appview/state/star.go
··· 1 1 package state 2 2 3 3 import ( 4 - "log" 5 4 "net/http" 6 5 "time" 7 6 ··· 17 16 ) 18 17 19 18 func (s *State) Star(w http.ResponseWriter, r *http.Request) { 19 + l := s.logger.With("handler", "Star") 20 20 currentUser := s.oauth.GetMultiAccountUser(r) 21 21 22 22 subject := r.URL.Query().Get("subject") 23 23 if subject == "" { 24 - log.Println("invalid form") 24 + l.Warn("invalid form") 25 25 return 26 26 } 27 27 28 28 subjectUri, err := syntax.ParseATURI(subject) 29 29 if err != nil { 30 - log.Println("invalid form") 30 + l.Warn("invalid form", "subject", subject, "err", err) 31 31 return 32 32 } 33 33 34 34 client, err := s.oauth.AuthorizedClient(r) 35 35 if err != nil { 36 - log.Println("failed to authorize client", err) 36 + l.Error("failed to authorize client", "err", err) 37 37 return 38 38 } 39 39 ··· 59 59 Record: &lexutil.LexiconTypeDecoder{Val: starRecord}, 60 60 }) 61 61 if err != nil { 62 - log.Println("failed to create atproto record", err) 62 + l.Error("failed to create atproto record", "err", err) 63 63 return 64 64 } 65 - log.Println("created atproto record: ", resp.Uri) 65 + l.Info("created atproto record", "uri", resp.Uri) 66 66 67 67 star := &models.Star{ 68 68 Did: currentUser.Active.Did, ··· 72 72 73 73 err = db.AddStar(s.db, star) 74 74 if err != nil { 75 - log.Println("failed to star", err) 75 + l.Error("failed to star", "err", err) 76 76 return 77 77 } 78 78 79 79 starCount, err := db.GetStarCount(s.db, subjectUri) 80 80 if err != nil { 81 - log.Println("failed to get star count for ", subjectUri) 81 + l.Error("failed to get star count", "subjectUri", subjectUri, "err", err) 82 82 } 83 83 84 84 s.notifier.NewStar(r.Context(), star) ··· 94 94 // find the record in the db 95 95 star, err := db.GetStar(s.db, currentUser.Active.Did, subjectUri) 96 96 if err != nil { 97 - log.Println("failed to get star relationship") 97 + l.Error("failed to get star relationship", "err", err) 98 98 return 99 99 } 100 100 ··· 105 105 }) 106 106 107 107 if err != nil { 108 - log.Println("failed to unstar") 108 + l.Error("failed to unstar", "err", err) 109 109 return 110 110 } 111 111 112 112 err = db.DeleteStarByRkey(s.db, currentUser.Active.Did, star.Rkey) 113 113 if err != nil { 114 - log.Println("failed to delete star from DB") 114 + l.Warn("failed to delete star from DB", "err", err) 115 115 // this is not an issue, the firehose event might have already done this 116 116 } 117 117 118 118 starCount, err := db.GetStarCount(s.db, subjectUri) 119 119 if err != nil { 120 - log.Println("failed to get star count for ", subjectUri) 120 + l.Error("failed to get star count", "subjectUri", subjectUri, "err", err) 121 121 return 122 122 } 123 123