Weighs the soul of incoming HTTP requests to stop AI crawlers
at main 59 lines 1.5 kB view raw
1package internal 2 3import ( 4 "fmt" 5 "log" 6 "log/slog" 7 "net/http" 8 "os" 9 "strings" 10) 11 12func InitSlog(level string) { 13 var programLevel slog.Level 14 if err := (&programLevel).UnmarshalText([]byte(level)); err != nil { 15 fmt.Fprintf(os.Stderr, "invalid log level %s: %v, using info\n", level, err) 16 programLevel = slog.LevelInfo 17 } 18 19 leveler := &slog.LevelVar{} 20 leveler.Set(programLevel) 21 22 h := slog.NewJSONHandler(os.Stderr, &slog.HandlerOptions{ 23 AddSource: true, 24 Level: leveler, 25 }) 26 slog.SetDefault(slog.New(h)) 27} 28 29func GetRequestLogger(r *http.Request) *slog.Logger { 30 return slog.With( 31 "user_agent", r.UserAgent(), 32 "accept_language", r.Header.Get("Accept-Language"), 33 "priority", r.Header.Get("Priority"), 34 "x-forwarded-for", 35 r.Header.Get("X-Forwarded-For"), 36 "x-real-ip", r.Header.Get("X-Real-Ip"), 37 ) 38} 39 40// ErrorLogFilter is used to suppress "context canceled" logs from the http server when a request is canceled (e.g., when a client disconnects). 41type ErrorLogFilter struct { 42 Unwrap *log.Logger 43} 44 45func (elf *ErrorLogFilter) Write(p []byte) (n int, err error) { 46 logMessage := string(p) 47 if strings.Contains(logMessage, "context canceled") { 48 return len(p), nil // Suppress the log by doing nothing 49 } 50 if elf.Unwrap != nil { 51 return elf.Unwrap.Writer().Write(p) 52 } 53 return len(p), nil 54} 55 56func GetFilteredHTTPLogger() *log.Logger { 57 stdErrLogger := log.New(os.Stderr, "", log.LstdFlags) // essentially what the default logger is. 58 return log.New(&ErrorLogFilter{Unwrap: stdErrLogger}, "", 0) 59}