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:
wood chen 2024-12-01 00:03:26 +08:00
parent fd9c616aa2
commit 83e0226e41
2 changed files with 59 additions and 22 deletions

View File

@ -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]
} }
} }
} }

View File

@ -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>