207 lines
5.8 KiB
Go
207 lines
5.8 KiB
Go
|
|
package monitoring
|
|||
|
|
|
|||
|
|
import (
|
|||
|
|
"strconv"
|
|||
|
|
"sync"
|
|||
|
|
"time"
|
|||
|
|
|
|||
|
|
"github.com/prometheus/client_golang/prometheus"
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// Metrics 监控指标
|
|||
|
|
type Metrics struct {
|
|||
|
|
// HTTP请求指标
|
|||
|
|
httpRequestsTotal *prometheus.CounterVec
|
|||
|
|
httpRequestDuration *prometheus.HistogramVec
|
|||
|
|
|
|||
|
|
// 数据库指标
|
|||
|
|
dbQueriesTotal *prometheus.CounterVec
|
|||
|
|
dbQueryDuration *prometheus.HistogramVec
|
|||
|
|
|
|||
|
|
// 用户指标
|
|||
|
|
userRegistrations *prometheus.CounterVec
|
|||
|
|
userLogins *prometheus.CounterVec
|
|||
|
|
activeUsers *prometheus.GaugeVec
|
|||
|
|
|
|||
|
|
// 系统指标
|
|||
|
|
systemMemoryUsage prometheus.Gauge
|
|||
|
|
systemGoroutines prometheus.Gauge
|
|||
|
|
|
|||
|
|
// 私有注册表(测试时互不干扰)
|
|||
|
|
registry *prometheus.Registry
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// globalMetrics 全局单例(生产使用)
|
|||
|
|
var (
|
|||
|
|
globalMetrics *Metrics
|
|||
|
|
globalMetricsOnce sync.Once
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// NewMetrics 创建监控指标(每次创建使用独立 registry,避免重复注册 panic)
|
|||
|
|
func NewMetrics() *Metrics {
|
|||
|
|
reg := prometheus.NewRegistry()
|
|||
|
|
m := &Metrics{registry: reg}
|
|||
|
|
m.httpRequestsTotal = prometheus.NewCounterVec(
|
|||
|
|
prometheus.CounterOpts{
|
|||
|
|
Name: "http_requests_total",
|
|||
|
|
Help: "Total number of HTTP requests",
|
|||
|
|
},
|
|||
|
|
[]string{"method", "path", "status"},
|
|||
|
|
)
|
|||
|
|
m.httpRequestDuration = prometheus.NewHistogramVec(
|
|||
|
|
prometheus.HistogramOpts{
|
|||
|
|
Name: "http_request_duration_seconds",
|
|||
|
|
Help: "HTTP request duration in seconds",
|
|||
|
|
Buckets: prometheus.DefBuckets,
|
|||
|
|
},
|
|||
|
|
[]string{"method", "path"},
|
|||
|
|
)
|
|||
|
|
m.dbQueriesTotal = prometheus.NewCounterVec(
|
|||
|
|
prometheus.CounterOpts{
|
|||
|
|
Name: "db_queries_total",
|
|||
|
|
Help: "Total number of database queries",
|
|||
|
|
},
|
|||
|
|
[]string{"operation", "table"},
|
|||
|
|
)
|
|||
|
|
m.dbQueryDuration = prometheus.NewHistogramVec(
|
|||
|
|
prometheus.HistogramOpts{
|
|||
|
|
Name: "db_query_duration_seconds",
|
|||
|
|
Help: "Database query duration in seconds",
|
|||
|
|
Buckets: prometheus.DefBuckets,
|
|||
|
|
},
|
|||
|
|
[]string{"operation", "table"},
|
|||
|
|
)
|
|||
|
|
m.userRegistrations = prometheus.NewCounterVec(
|
|||
|
|
prometheus.CounterOpts{
|
|||
|
|
Name: "user_registrations_total",
|
|||
|
|
Help: "Total number of user registrations",
|
|||
|
|
},
|
|||
|
|
[]string{"type"},
|
|||
|
|
)
|
|||
|
|
m.userLogins = prometheus.NewCounterVec(
|
|||
|
|
prometheus.CounterOpts{
|
|||
|
|
Name: "user_logins_total",
|
|||
|
|
Help: "Total number of user logins",
|
|||
|
|
},
|
|||
|
|
[]string{"type", "status"},
|
|||
|
|
)
|
|||
|
|
m.activeUsers = prometheus.NewGaugeVec(
|
|||
|
|
prometheus.GaugeOpts{
|
|||
|
|
Name: "active_users",
|
|||
|
|
Help: "Number of active users",
|
|||
|
|
},
|
|||
|
|
[]string{"period"},
|
|||
|
|
)
|
|||
|
|
m.systemMemoryUsage = prometheus.NewGauge(
|
|||
|
|
prometheus.GaugeOpts{
|
|||
|
|
Name: "system_memory_usage_bytes",
|
|||
|
|
Help: "Current memory usage in bytes",
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
m.systemGoroutines = prometheus.NewGauge(
|
|||
|
|
prometheus.GaugeOpts{
|
|||
|
|
Name: "system_goroutines",
|
|||
|
|
Help: "Number of goroutines",
|
|||
|
|
},
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
// 注册到私有 registry
|
|||
|
|
reg.MustRegister(
|
|||
|
|
m.httpRequestsTotal,
|
|||
|
|
m.httpRequestDuration,
|
|||
|
|
m.dbQueriesTotal,
|
|||
|
|
m.dbQueryDuration,
|
|||
|
|
m.userRegistrations,
|
|||
|
|
m.userLogins,
|
|||
|
|
m.activeUsers,
|
|||
|
|
m.systemMemoryUsage,
|
|||
|
|
m.systemGoroutines,
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
return m
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetGlobalMetrics 获取全局单例 Metrics(生产使用,同时注册到默认 registry)
|
|||
|
|
func GetGlobalMetrics() *Metrics {
|
|||
|
|
globalMetricsOnce.Do(func() {
|
|||
|
|
m := NewMetrics()
|
|||
|
|
// 将私有 registry 的指标也注册到默认 registry
|
|||
|
|
prometheus.DefaultRegisterer.Register(m.httpRequestsTotal) //nolint:errcheck
|
|||
|
|
prometheus.DefaultRegisterer.Register(m.httpRequestDuration) //nolint:errcheck
|
|||
|
|
prometheus.DefaultRegisterer.Register(m.dbQueriesTotal) //nolint:errcheck
|
|||
|
|
prometheus.DefaultRegisterer.Register(m.dbQueryDuration) //nolint:errcheck
|
|||
|
|
prometheus.DefaultRegisterer.Register(m.userRegistrations) //nolint:errcheck
|
|||
|
|
prometheus.DefaultRegisterer.Register(m.userLogins) //nolint:errcheck
|
|||
|
|
prometheus.DefaultRegisterer.Register(m.activeUsers) //nolint:errcheck
|
|||
|
|
prometheus.DefaultRegisterer.Register(m.systemMemoryUsage) //nolint:errcheck
|
|||
|
|
prometheus.DefaultRegisterer.Register(m.systemGoroutines) //nolint:errcheck
|
|||
|
|
globalMetrics = m
|
|||
|
|
})
|
|||
|
|
return globalMetrics
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetRegistry 获取私有 Prometheus registry
|
|||
|
|
func (m *Metrics) GetRegistry() *prometheus.Registry {
|
|||
|
|
return m.registry
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IncHTTPRequest 记录HTTP请求
|
|||
|
|
func (m *Metrics) IncHTTPRequest(method, path string, status int) {
|
|||
|
|
m.httpRequestsTotal.WithLabelValues(method, path, strconv.Itoa(status)).Inc()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ObserveHTTPRequestDuration 记录HTTP请求耗时
|
|||
|
|
func (m *Metrics) ObserveHTTPRequestDuration(method, path string, duration time.Duration) {
|
|||
|
|
m.httpRequestDuration.WithLabelValues(method, path).Observe(duration.Seconds())
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IncDBQuery 记录数据库查询
|
|||
|
|
func (m *Metrics) IncDBQuery(operation, table string) {
|
|||
|
|
m.dbQueriesTotal.WithLabelValues(operation, table).Inc()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// ObserveDBQueryDuration 记录数据库查询耗时
|
|||
|
|
func (m *Metrics) ObserveDBQueryDuration(operation, table string, duration time.Duration) {
|
|||
|
|
m.dbQueryDuration.WithLabelValues(operation, table).Observe(duration.Seconds())
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IncUserRegistration 记录用户注册
|
|||
|
|
func (m *Metrics) IncUserRegistration(userType string) {
|
|||
|
|
m.userRegistrations.WithLabelValues(userType).Inc()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// IncUserLogin 记录用户登录
|
|||
|
|
func (m *Metrics) IncUserLogin(loginType, status string) {
|
|||
|
|
m.userLogins.WithLabelValues(loginType, status).Inc()
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// SetActiveUsers 设置活跃用户数
|
|||
|
|
func (m *Metrics) SetActiveUsers(period string, count float64) {
|
|||
|
|
m.activeUsers.WithLabelValues(period).Set(count)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// SetMemoryUsage 设置内存使用量
|
|||
|
|
func (m *Metrics) SetMemoryUsage(bytes float64) {
|
|||
|
|
m.systemMemoryUsage.Set(bytes)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// SetGoroutines 设置协程数
|
|||
|
|
func (m *Metrics) SetGoroutines(count float64) {
|
|||
|
|
m.systemGoroutines.Set(count)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// GetMetrics 获取Prometheus指标收集器
|
|||
|
|
func (m *Metrics) GetMetrics() []prometheus.Collector {
|
|||
|
|
return []prometheus.Collector{
|
|||
|
|
m.httpRequestsTotal,
|
|||
|
|
m.httpRequestDuration,
|
|||
|
|
m.dbQueriesTotal,
|
|||
|
|
m.dbQueryDuration,
|
|||
|
|
m.userRegistrations,
|
|||
|
|
m.userLogins,
|
|||
|
|
m.activeUsers,
|
|||
|
|
m.systemMemoryUsage,
|
|||
|
|
m.systemGoroutines,
|
|||
|
|
}
|
|||
|
|
}
|