forked from tangled.org/core
Monorepo for Tangled

appview: state: setup metrics middleware

anirudh.fi 5c8b5c1f 44f2b1f5

verified
Changed files
+32 -4
appview
cmd
appview
+1
appview/config.go
··· 17 CamoSharedSecret string `env:"TANGLED_CAMO_SHARED_SECRET"` 18 AvatarSharedSecret string `env:"TANGLED_AVATAR_SHARED_SECRET"` 19 AvatarHost string `env:"TANGLED_AVATAR_HOST, default=https://avatar.tangled.sh"` 20 } 21 22 func LoadConfig(ctx context.Context) (*Config, error) {
··· 17 CamoSharedSecret string `env:"TANGLED_CAMO_SHARED_SECRET"` 18 AvatarSharedSecret string `env:"TANGLED_AVATAR_SHARED_SECRET"` 19 AvatarHost string `env:"TANGLED_AVATAR_HOST, default=https://avatar.tangled.sh"` 20 + EnableTelemetry bool `env:"TANGLED_TELEMETRY_ENABLED, default=false"` 21 } 22 23 func LoadConfig(ctx context.Context) (*Config, error) {
+6 -1
appview/state/router.go
··· 13 func (s *State) Router() http.Handler { 14 router := chi.NewRouter() 15 16 router.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) { 17 pat := chi.URLParam(r, "*") 18 if strings.HasPrefix(pat, "did:") || strings.HasPrefix(pat, "@") { ··· 48 49 func (s *State) UserRouter() http.Handler { 50 r := chi.NewRouter() 51 - 52 // strip @ from user 53 r.Use(StripLeadingAt) 54
··· 13 func (s *State) Router() http.Handler { 14 router := chi.NewRouter() 15 16 + if s.t != nil { 17 + // top-level telemetry middleware 18 + // router.Use(s.t.RequestDuration()) 19 + // router.Use(s.t.RequestInFlight()) 20 + } 21 + 22 router.HandleFunc("/*", func(w http.ResponseWriter, r *http.Request) { 23 pat := chi.URLParam(r, "*") 24 if strings.HasPrefix(pat, "did:") || strings.HasPrefix(pat, "@") { ··· 54 55 func (s *State) UserRouter() http.Handler { 56 r := chi.NewRouter() 57 // strip @ from user 58 r.Use(StripLeadingAt) 59
+21 -1
appview/state/state.go
··· 9 "log" 10 "log/slog" 11 "net/http" 12 "strings" 13 "time" 14 ··· 24 "tangled.sh/tangled.sh/core/appview/pages" 25 "tangled.sh/tangled.sh/core/jetstream" 26 "tangled.sh/tangled.sh/core/rbac" 27 ) 28 29 type State struct { ··· 34 pages *pages.Pages 35 resolver *appview.Resolver 36 jc *jetstream.JetstreamClient 37 config *appview.Config 38 } 39 40 - func Make(config *appview.Config) (*State, error) { 41 d, err := db.Make(config.DbPath) 42 if err != nil { 43 return nil, err ··· 59 60 resolver := appview.NewResolver() 61 62 wrapper := db.DbWrapper{d} 63 jc, err := jetstream.NewJetstreamClient( 64 config.JetstreamEndpoint, ··· 77 return nil, fmt.Errorf("failed to start jetstream watcher: %w", err) 78 } 79 80 state := &State{ 81 d, 82 auth, ··· 85 pgs, 86 resolver, 87 jc, 88 config, 89 } 90
··· 9 "log" 10 "log/slog" 11 "net/http" 12 + "runtime/debug" 13 "strings" 14 "time" 15 ··· 25 "tangled.sh/tangled.sh/core/appview/pages" 26 "tangled.sh/tangled.sh/core/jetstream" 27 "tangled.sh/tangled.sh/core/rbac" 28 + "tangled.sh/tangled.sh/core/telemetry" 29 ) 30 31 type State struct { ··· 36 pages *pages.Pages 37 resolver *appview.Resolver 38 jc *jetstream.JetstreamClient 39 + t *telemetry.Telemetry 40 config *appview.Config 41 } 42 43 + func Make(ctx context.Context, config *appview.Config) (*State, error) { 44 d, err := db.Make(config.DbPath) 45 if err != nil { 46 return nil, err ··· 62 63 resolver := appview.NewResolver() 64 65 + bi, ok := debug.ReadBuildInfo() 66 + var version string 67 + if ok { 68 + version = bi.Main.Version 69 + } else { 70 + version = "v0.0.0-unknown" 71 + } 72 + 73 wrapper := db.DbWrapper{d} 74 jc, err := jetstream.NewJetstreamClient( 75 config.JetstreamEndpoint, ··· 88 return nil, fmt.Errorf("failed to start jetstream watcher: %w", err) 89 } 90 91 + var tele *telemetry.Telemetry 92 + if config.EnableTelemetry { 93 + tele, err = telemetry.NewTelemetry(ctx, "appview", version, config.Dev) 94 + if err != nil { 95 + return nil, fmt.Errorf("failed to setup telemetry: %w", err) 96 + } 97 + } 98 + 99 state := &State{ 100 d, 101 auth, ··· 104 pgs, 105 resolver, 106 jc, 107 + tele, 108 config, 109 } 110
+4 -2
cmd/appview/main.go
··· 14 func main() { 15 slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, nil))) 16 17 - c, err := appview.LoadConfig(context.Background()) 18 if err != nil { 19 log.Println("failed to load config", "error", err) 20 return 21 } 22 23 - state, err := state.Make(c) 24 25 if err != nil { 26 log.Fatal(err)
··· 14 func main() { 15 slog.SetDefault(slog.New(slog.NewTextHandler(os.Stdout, nil))) 16 17 + ctx := context.Background() 18 + 19 + c, err := appview.LoadConfig(ctx) 20 if err != nil { 21 log.Println("failed to load config", "error", err) 22 return 23 } 24 25 + state, err := state.Make(ctx, c) 26 27 if err != nil { 28 log.Fatal(err)