mirror of
https://github.com/woodchen-ink/random-api-go.git
synced 2025-07-18 13:52:02 +08:00
feat(monitoring, public): enhance metrics logging and display
- Added a new function to format latency metrics in both Go and JavaScript for improved readability. - Updated the LogRequest function to parse and store only the domain of the referer, enhancing data clarity. - Modified the recent requests and top referers display logic in the HTML to improve performance and maintainability. - Ensured that the recent requests are displayed in a more user-friendly format, including formatted latency values.
This commit is contained in:
parent
fd9c616aa2
commit
83e0226e41
@ -1,6 +1,8 @@
|
|||||||
package monitoring
|
package monitoring
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
"net/url"
|
||||||
"runtime"
|
"runtime"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
@ -88,13 +90,31 @@ func CollectMetrics() *SystemMetrics {
|
|||||||
return &metrics
|
return &metrics
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func formatLatency(microseconds float64) string {
|
||||||
|
if microseconds < 1000 {
|
||||||
|
return fmt.Sprintf("%.2fµs", microseconds)
|
||||||
|
}
|
||||||
|
if microseconds < 1000000 {
|
||||||
|
return fmt.Sprintf("%.2fms", microseconds/1000)
|
||||||
|
}
|
||||||
|
return fmt.Sprintf("%.2fs", microseconds/1000000)
|
||||||
|
}
|
||||||
|
|
||||||
func LogRequest(log RequestLog) {
|
func LogRequest(log RequestLog) {
|
||||||
mu.Lock()
|
mu.Lock()
|
||||||
defer mu.Unlock()
|
defer mu.Unlock()
|
||||||
|
|
||||||
metrics.RequestCount++
|
metrics.RequestCount++
|
||||||
metrics.StatusCodes[log.StatusCode]++
|
metrics.StatusCodes[log.StatusCode]++
|
||||||
metrics.TopReferers[log.Referer]++
|
|
||||||
|
// 处理 referer,只保留域名
|
||||||
|
if log.Referer != "direct" {
|
||||||
|
if parsedURL, err := url.Parse(log.Referer); err == nil {
|
||||||
|
metrics.TopReferers[parsedURL.Host]++
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
metrics.TopReferers["direct"]++
|
||||||
|
}
|
||||||
|
|
||||||
// 只记录 API 请求
|
// 只记录 API 请求
|
||||||
if strings.HasPrefix(log.Path, "/pic/") || strings.HasPrefix(log.Path, "/video/") {
|
if strings.HasPrefix(log.Path, "/pic/") || strings.HasPrefix(log.Path, "/video/") {
|
||||||
@ -105,10 +125,10 @@ func LogRequest(log RequestLog) {
|
|||||||
metrics.PathLatencies[log.Path] = log.Latency
|
metrics.PathLatencies[log.Path] = log.Latency
|
||||||
}
|
}
|
||||||
|
|
||||||
// 保存最近请求记录
|
// 保存最近请求记录,插入到开头
|
||||||
metrics.RecentRequests = append(metrics.RecentRequests, log)
|
metrics.RecentRequests = append([]RequestLog{log}, metrics.RecentRequests...)
|
||||||
if len(metrics.RecentRequests) > 100 {
|
if len(metrics.RecentRequests) > 100 {
|
||||||
metrics.RecentRequests = metrics.RecentRequests[1:]
|
metrics.RecentRequests = metrics.RecentRequests[:100]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -218,6 +218,39 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function updateMetricsDisplay(metrics) {
|
function updateMetricsDisplay(metrics) {
|
||||||
|
// 格式化延迟显示
|
||||||
|
function formatLatency(microseconds) {
|
||||||
|
if (microseconds < 1000) {
|
||||||
|
return `${microseconds.toFixed(2)}µs`;
|
||||||
|
}
|
||||||
|
if (microseconds < 1000000) {
|
||||||
|
return `${(microseconds/1000).toFixed(2)}ms`;
|
||||||
|
}
|
||||||
|
return `${(microseconds/1000000).toFixed(2)}s`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 最近请求
|
||||||
|
const recentRequestsHtml = metrics.recent_requests.map(req => `
|
||||||
|
<tr>
|
||||||
|
<td>${new Date(req.time).toLocaleString()}</td>
|
||||||
|
<td>${req.path}</td>
|
||||||
|
<td>${req.method}</td>
|
||||||
|
<td>${req.status_code}</td>
|
||||||
|
<td>${formatLatency(req.latency)}</td>
|
||||||
|
</tr>
|
||||||
|
`).join('');
|
||||||
|
|
||||||
|
// 热门引用来源
|
||||||
|
const topReferersHtml = Object.entries(metrics.top_referers)
|
||||||
|
.sort(([, a], [, b]) => b - a)
|
||||||
|
.slice(0, 10)
|
||||||
|
.map(([referer, count]) => `
|
||||||
|
<div class="referer-item">
|
||||||
|
<span class="referer">${referer}</span>
|
||||||
|
<span class="count">${count}</span>
|
||||||
|
</div>
|
||||||
|
`).join('');
|
||||||
|
|
||||||
const metricsHtml = `
|
const metricsHtml = `
|
||||||
<div class="metrics-container">
|
<div class="metrics-container">
|
||||||
<div class="metrics-section">
|
<div class="metrics-section">
|
||||||
@ -273,15 +306,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
${metrics.recent_requests.slice(0, 10).map(req => `
|
${recentRequestsHtml}
|
||||||
<tr>
|
|
||||||
<td>${new Date(req.time).toLocaleString()}</td>
|
|
||||||
<td>${req.path}</td>
|
|
||||||
<td>${req.method}</td>
|
|
||||||
<td>${req.status_code}</td>
|
|
||||||
<td>${req.latency.toFixed(2)}ms</td>
|
|
||||||
</tr>
|
|
||||||
`).join('')}
|
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
@ -290,15 +315,7 @@
|
|||||||
<div class="metrics-section">
|
<div class="metrics-section">
|
||||||
<h3>热门引用来源</h3>
|
<h3>热门引用来源</h3>
|
||||||
<div class="top-referers">
|
<div class="top-referers">
|
||||||
${Object.entries(metrics.top_referers)
|
${topReferersHtml}
|
||||||
.sort(([,a], [,b]) => b - a)
|
|
||||||
.slice(0, 10)
|
|
||||||
.map(([referer, count]) => `
|
|
||||||
<div class="referer-item">
|
|
||||||
<span class="referer">${referer || '直接访问'}</span>
|
|
||||||
<span class="count">${count}</span>
|
|
||||||
</div>
|
|
||||||
`).join('')}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user