refactor(handlers, monitoring): improve API request handling and metrics logging

- Refactored HandleAPIRequest to use a result channel for better error handling and response management.
- Updated metrics logging to directly use the full referer instead of just the main domain, enhancing data accuracy.
- Fixed recent requests display in HTML to correctly format timestamps for better readability.
This commit is contained in:
wood chen 2024-12-01 00:37:50 +08:00
parent 2720f6ebf0
commit 1248508302
3 changed files with 22 additions and 23 deletions

View File

@ -28,7 +28,13 @@ func (h *Handlers) HandleAPIRequest(w http.ResponseWriter, r *http.Request) {
ctx, cancel := context.WithTimeout(r.Context(), 10*time.Second)
defer cancel()
done := make(chan struct{})
// 创建一个响应通道,用于传递结果
type result struct {
url string
err error
}
resultChan := make(chan result, 1)
go func() {
start := time.Now()
realIP := utils.GetRealIP(r)
@ -57,7 +63,7 @@ func (h *Handlers) HandleAPIRequest(w http.ResponseWriter, r *http.Request) {
IP: realIP,
Referer: sourceInfo,
})
http.NotFound(w, r)
resultChan <- result{err: fmt.Errorf("not found")}
return
}
@ -78,7 +84,7 @@ func (h *Handlers) HandleAPIRequest(w http.ResponseWriter, r *http.Request) {
IP: realIP,
Referer: sourceInfo,
})
http.NotFound(w, r)
resultChan <- result{err: fmt.Errorf("not found")}
return
}
@ -94,7 +100,7 @@ func (h *Handlers) HandleAPIRequest(w http.ResponseWriter, r *http.Request) {
IP: realIP,
Referer: sourceInfo,
})
http.Error(w, "Failed to fetch content", http.StatusInternalServerError)
resultChan <- result{err: err}
return
}
@ -108,7 +114,7 @@ func (h *Handlers) HandleAPIRequest(w http.ResponseWriter, r *http.Request) {
IP: realIP,
Referer: sourceInfo,
})
http.Error(w, "No content available", http.StatusNotFound)
resultChan <- result{err: fmt.Errorf("no content available")}
return
}
@ -136,14 +142,17 @@ func (h *Handlers) HandleAPIRequest(w http.ResponseWriter, r *http.Request) {
randomURL,
)
http.Redirect(w, r, randomURL, http.StatusFound)
done <- struct{}{}
resultChan <- result{url: randomURL}
}()
// 等待结果或超时
select {
case <-done:
// 请求成功完成
case res := <-resultChan:
if res.err != nil {
http.Error(w, res.err.Error(), http.StatusInternalServerError)
return
}
http.Redirect(w, r, res.url, http.StatusFound)
case <-ctx.Done():
http.Error(w, "Request timeout", http.StatusGatewayTimeout)
}

View File

@ -3,7 +3,6 @@ package monitoring
import (
"encoding/json"
"fmt"
"net/url"
"runtime"
"strings"
"sync"
@ -122,18 +121,9 @@ func LogRequest(log RequestLog) {
metrics.StatusCodes[log.StatusCode]++
// 处理 referer只保留域名
// 直接使用完整的 referer
if log.Referer != "direct" {
if parsedURL, err := url.Parse(log.Referer); err == nil {
// 只保留主域名
parts := strings.Split(parsedURL.Host, ".")
if len(parts) >= 2 {
domain := parts[len(parts)-2] + "." + parts[len(parts)-1]
metrics.TopReferers[domain]++
} else {
metrics.TopReferers[parsedURL.Host]++
}
}
metrics.TopReferers[log.Referer]++
} else {
metrics.TopReferers["直接访问"]++
}

View File

@ -232,7 +232,7 @@
// 最近请求
const recentRequestsHtml = metrics.recent_requests.map(req => `
<tr>
<td>${new Date(req.time).toLocaleString()}</td>
<td>${new Date(req.time * 1000).toLocaleString()}</td>
<td>${req.path}</td>
<td>${req.method}</td>
<td>${req.status_code}</td>