79 lines
1.9 KiB
Go
79 lines
1.9 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"log/slog"
|
|
"net/http"
|
|
"strings"
|
|
|
|
chimw "github.com/go-chi/chi/v5/middleware"
|
|
|
|
"litepan/internal/domain"
|
|
)
|
|
|
|
type requestLoggerCtxKey struct{}
|
|
|
|
func (h *Handler) attachRequestLogger(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
log := h.log
|
|
if log == nil {
|
|
log = slog.Default()
|
|
}
|
|
if reqID := chimw.GetReqID(r.Context()); reqID != "" {
|
|
log = log.With("request_id", reqID)
|
|
}
|
|
ctx := context.WithValue(r.Context(), requestLoggerCtxKey{}, log)
|
|
next.ServeHTTP(w, r.WithContext(ctx))
|
|
})
|
|
}
|
|
|
|
func requestLogger(ctx context.Context) *slog.Logger {
|
|
if ctx == nil {
|
|
return slog.Default()
|
|
}
|
|
if log, ok := ctx.Value(requestLoggerCtxKey{}).(*slog.Logger); ok && log != nil {
|
|
return log
|
|
}
|
|
return slog.Default()
|
|
}
|
|
|
|
func logAPIError(r *http.Request, err error) {
|
|
if r == nil || err == nil {
|
|
return
|
|
}
|
|
log := requestLogger(r.Context())
|
|
fields := []any{
|
|
"method", r.Method,
|
|
"path", r.URL.Path,
|
|
"raw_err", err.Error(),
|
|
}
|
|
if raw := strings.TrimSpace(r.URL.RawQuery); raw != "" {
|
|
fields = append(fields, "query", raw)
|
|
}
|
|
if accountID := strings.TrimSpace(r.URL.Query().Get("account_id")); accountID != "" {
|
|
fields = append(fields, "account_id", accountID)
|
|
}
|
|
if ae, ok := domain.AsAppError(err); ok {
|
|
fields = append(fields,
|
|
"status", ae.HTTPStatus(),
|
|
"error_type", ae.Code,
|
|
"message", ae.Message,
|
|
)
|
|
if details := detailsOrNil(ae.Details); details != nil {
|
|
fields = append(fields, "details", details)
|
|
}
|
|
switch ae.Code {
|
|
case domain.CodeInternal, domain.CodeDriverError:
|
|
log.Error("API 请求失败", fields...)
|
|
default:
|
|
log.Warn("API 请求失败", fields...)
|
|
}
|
|
return
|
|
}
|
|
log.Error("API 请求失败", append(fields,
|
|
"status", http.StatusInternalServerError,
|
|
"error_type", domain.CodeInternal,
|
|
"message", "服务内部错误",
|
|
)...)
|
|
}
|