Files
verdande/internal/httpapi/errorlog_handlers.go
T

48 lines
1.7 KiB
Go
Raw Normal View History

package httpapi
import (
"net/http"
"time"
)
// What has gone wrong lately, kept where a restart cannot take it.
//
// The panel's watcher reports "HTTP 5xx, twice, at 11:49" — which is enough to
// know something broke and nothing at all to act on. The line that explains it is
// in the container's log, and a Rune's container is replaced on every restart, so
// by the time anybody looks the explanation is gone. These rows are the same
// information written somewhere that survives.
type serverErrorJSON struct {
ID string `json:"id"`
At string `json:"at"`
Method string `json:"method"`
Path string `json:"path"`
Status int `json:"status"`
// What the handler was doing, in its own words — "list projects", "move task".
What string `json:"what"`
Message string `json:"message"`
// Who was asking, when there was somebody: a fault only one account hits is a
// different problem from one everybody hits.
UserName string `json:"user_name,omitempty"`
// RequestID ties the row back to the log line, for whoever still has it.
RequestID string `json:"request_id,omitempty"`
}
func (s *Server) handleListErrors(w http.ResponseWriter, r *http.Request) {
errs, err := s.db.ListErrors(r.Context(), parseLimit(r.URL.Query().Get("limit"), 100, 500))
if err != nil {
s.internal(w, r, "list errors", err)
return
}
out := make([]serverErrorJSON, 0, len(errs))
for _, e := range errs {
out = append(out, serverErrorJSON{
ID: e.ID, At: e.At.Format(time.RFC3339), Method: e.Method, Path: e.Path,
Status: e.Status, What: e.What, Message: e.Message,
UserName: e.UserName, RequestID: e.RequestID,
})
}
writeJSON(w, http.StatusOK, map[string]any{"errors": out})
}