修复bug及添加日志打印

This commit is contained in:
2026-07-28 10:36:32 +08:00
parent ea36e1155f
commit 8a48af6a3b
9 changed files with 1292 additions and 12 deletions

View File

@@ -104,7 +104,7 @@ func (s *Server) Handler() http.Handler {
mux.Handle("GET /api/admin/history/batches/{id}", s.requireAdmin(http.HandlerFunc(s.adminHistoryBatch)))
mux.Handle("GET /api/admin/history/summary", s.requireAdmin(http.HandlerFunc(s.adminHistorySummary)))
mux.Handle("GET /api/admin/history/export.csv", s.requireAdmin(http.HandlerFunc(s.adminHistoryExport)))
return s.recoverPanic(s.requestID(s.accessLog(s.securityHeaders(mux))))
return s.requestID(s.accessLog(s.recoverPanic(s.securityHeaders(mux))))
}
func (s *Server) health(w http.ResponseWriter, _ *http.Request) {
@@ -144,32 +144,84 @@ func (s *Server) requestID(next http.Handler) http.Handler {
type statusRecorder struct {
http.ResponseWriter
status int
status int
wroteHeader bool
body *logBodyCapture
}
func (r *statusRecorder) WriteHeader(status int) {
if r.wroteHeader {
return
}
r.status = status
r.wroteHeader = true
r.ResponseWriter.WriteHeader(status)
}
func (r *statusRecorder) Flush() {
if flusher, ok := r.ResponseWriter.(http.Flusher); ok {
flusher.Flush()
func (r *statusRecorder) Write(value []byte) (int, error) {
if !r.wroteHeader {
r.WriteHeader(http.StatusOK)
}
n, err := r.ResponseWriter.Write(value)
if n > 0 && r.body != nil {
_, _ = r.body.Write(value[:n])
}
return n, err
}
func (r *statusRecorder) Unwrap() http.ResponseWriter {
return r.ResponseWriter
}
func (r *statusRecorder) responseStarted() bool {
return r.wroteHeader
}
type flushStatusRecorder struct {
*statusRecorder
}
func (r *flushStatusRecorder) Flush() {
if !r.wroteHeader {
r.WriteHeader(http.StatusOK)
}
r.ResponseWriter.(http.Flusher).Flush()
}
func (s *Server) accessLog(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
started := s.now()
recorder := &statusRecorder{ResponseWriter: w, status: http.StatusOK}
next.ServeHTTP(recorder, r)
s.logger.Info("http request",
var requestBody *logBodyCapture
var responseBody *logBodyCapture
if shouldCaptureLogBody(r) {
requestBody = &logBodyCapture{}
responseBody = &logBodyCapture{}
if r.Body != nil {
r.Body = &logCaptureReadCloser{ReadCloser: r.Body, capture: requestBody}
}
}
recorder := &statusRecorder{ResponseWriter: w, status: http.StatusOK, body: responseBody}
var responseWriter http.ResponseWriter = recorder
if _, ok := w.(http.Flusher); ok {
responseWriter = &flushStatusRecorder{statusRecorder: recorder}
}
next.ServeHTTP(responseWriter, r)
attributes := []any{
"request_id", requestID(r.Context()),
"method", r.Method,
"path", r.URL.Path,
"path", logPath(r),
"status", recorder.status,
"duration_ms", time.Since(started).Milliseconds(),
)
}
if isImportantLogRoute(r) {
if request := requestLogDetails(r, requestBody); request != nil {
attributes = append(attributes, "request", request)
}
if response := responseLogDetails(r, recorder); response != nil {
attributes = append(attributes, "response", response)
}
}
s.logger.Info("http request", attributes...)
})
}
@@ -187,7 +239,19 @@ func (s *Server) recoverPanic(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
defer func() {
if recovered := recover(); recovered != nil {
s.logger.Error("panic recovered", "request_id", requestID(r.Context()), "error", recovered, "stack", string(debug.Stack()))
responseStarted := false
if state, ok := w.(interface{ responseStarted() bool }); ok {
responseStarted = state.responseStarted()
}
s.logger.Error("panic recovered",
"request_id", requestID(r.Context()),
"error", recovered,
"response_started", responseStarted,
"stack", string(debug.Stack()),
)
if responseStarted {
return
}
writeError(w, fmt.Errorf("panic: %v", recovered))
}
}()