Lasa is a stateless proxy that generates a RSS or an Atom feed from a Standard.site publication. lasa.anhgelus.world
rss atom atprotocol standard-site atproto
2
fork

Configure Feed

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

feat(cli): log every request with status code

+60 -27
+18
cmd/internal/command.go
··· 1 1 package internal 2 2 3 + import ( 4 + "flag" 5 + "os" 6 + ) 7 + 3 8 type Command struct { 4 9 Name string 5 10 Usage string 6 11 Callback func([]string) 7 12 } 13 + 14 + func HandleCommands(command string, args []string, cmds []Command, flags *flag.FlagSet, help func()) { 15 + for _, c := range cmds { 16 + if c.Name == command { 17 + flags.Parse(args) 18 + args = flags.Args() 19 + c.Callback(args) 20 + return 21 + } 22 + } 23 + help() 24 + os.Exit(1) 25 + }
+1 -10
cmd/lasa/main.go
··· 42 42 if len(args) > 1 { 43 43 next = args[1:] 44 44 } 45 - for _, c := range commands { 46 - if c.Name == command { 47 - flags.Parse(next) 48 - next = flags.Args() 49 - c.Callback(next) 50 - return 51 - } 52 - } 53 - handleHelp() 54 - os.Exit(1) 45 + internal.HandleCommands(command, next, commands, flags, handleHelp) 55 46 } 56 47 57 48 func handleHelp() {
+6 -4
cmd/lasad/config/config.go
··· 13 13 const DefaultPath = "/etc/lasad.toml" 14 14 15 15 type Config struct { 16 - Domain string `toml:"domain"` 17 - Port uint `toml:"port"` 18 - Cache *Cache `toml:"cache"` 19 - LegalNotice *string `toml:"legal_notice_url"` 16 + Domain string `toml:"domain"` 17 + Port uint `toml:"port"` 18 + Cache *Cache `toml:"cache"` 19 + LegalNotice *string `toml:"legal_notice_url"` 20 + LogNotFound bool `toml:"log_not_found"` 21 + LogBadRequest bool `toml:"log_bad_request"` 20 22 } 21 23 22 24 type Cache struct {
+4
cmd/lasad/default.toml
··· 1 1 domain = "example.org" 2 2 port = 8000 3 3 #legal_notice_url = "https://example.org/legal" 4 + # if you want to log HTTP 404 responses 5 + #log_not_found = true 6 + # if you want to log HTTP 400 responses 7 + #log_bad_request = true 4 8 5 9 # if you are using valkey 6 10 #[cache]
+1 -10
cmd/lasad/main.go
··· 40 40 if len(args) > 1 { 41 41 next = args[1:] 42 42 } 43 - for _, c := range commands { 44 - if c.Name == command { 45 - flags.Parse(next) 46 - next = flags.Args() 47 - c.Callback(next) 48 - return 49 - } 50 - } 51 - handleHelp() 52 - os.Exit(1) 43 + internal.HandleCommands(command, next, commands, flags, handleHelp) 53 44 } 54 45 55 46 func handleHelp() {
+30 -3
cmd/lasad/run.go
··· 132 132 } 133 133 } 134 134 135 + type statusWriter struct { 136 + http.ResponseWriter 137 + code int 138 + } 139 + 140 + func (w *statusWriter) WriteHeader(statusCode int) { 141 + w.ResponseWriter.WriteHeader(statusCode) 142 + w.code = statusCode 143 + } 144 + 135 145 func middlewares(h http.Handler, ctx context.Context) http.Handler { 136 146 return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 137 - slog.Debug("request", "path", r.URL.Path) 147 + status := &statusWriter{w, http.StatusOK} 148 + log := slog.With("uri", r.RequestURI) 138 149 defer func() { 139 150 if err := recover(); err != nil { 140 151 w.WriteHeader(http.StatusInternalServerError) 141 - panic(err) 152 + log.Error("panic!") 142 153 } 143 154 }() 144 - h.ServeHTTP(w, r.WithContext(ctx)) 155 + now := time.Now() 156 + h.ServeHTTP(status, r.WithContext(ctx)) 157 + log = log.With("status", status.code, "duration", time.Since(now)) 158 + if status.code < 400 { 159 + log.Debug("served") 160 + } else if status.code < 500 { 161 + cfg := ctx.Value(keyCfg).(*config.Config) 162 + if (status.code == http.StatusNotFound && cfg.LogNotFound) || 163 + (status.code == http.StatusBadRequest && cfg.LogBadRequest) || 164 + (status.code != http.StatusNotFound && status.code != http.StatusBadRequest) { 165 + log.Warn("invalid request") 166 + } else { 167 + log.Debug("invalid request") 168 + } 169 + } else { 170 + log.Error("error while handling request") 171 + } 145 172 }) 146 173 }