104 lines
3.2 KiB
Go
104 lines
3.2 KiB
Go
package metrics
|
|
|
|
import (
|
|
"net/http"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
)
|
|
|
|
// MetricsService interface defines the contract for metrics operations
|
|
type MetricsService interface {
|
|
RecordHTTPRequest(method, path string, statusCode int, duration time.Duration)
|
|
RecordDBOperation(operation, table string)
|
|
RecordAuthAttempt(action, result string)
|
|
StartMetricsServer(port string)
|
|
MetricsMiddleware() gin.HandlerFunc
|
|
}
|
|
|
|
// PrometheusMetricsService implements MetricsService using Prometheus
|
|
type PrometheusMetricsService struct {
|
|
httpRequestsTotal *prometheus.CounterVec
|
|
httpRequestDuration *prometheus.HistogramVec
|
|
dbOperationsTotal *prometheus.CounterVec
|
|
authAttemptsTotal *prometheus.CounterVec
|
|
}
|
|
|
|
// NewPrometheusMetricsService creates a new Prometheus metrics service
|
|
func NewPrometheusMetricsService() MetricsService {
|
|
return &PrometheusMetricsService{
|
|
httpRequestsTotal: promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "http_requests_total",
|
|
Help: "Total number of HTTP requests",
|
|
},
|
|
[]string{"method", "path", "status"},
|
|
),
|
|
httpRequestDuration: promauto.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "http_request_duration_seconds",
|
|
Help: "HTTP request duration in seconds",
|
|
Buckets: prometheus.DefBuckets,
|
|
},
|
|
[]string{"method", "path"},
|
|
),
|
|
dbOperationsTotal: promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "db_operations_total",
|
|
Help: "Total number of database operations",
|
|
},
|
|
[]string{"operation", "table"},
|
|
),
|
|
authAttemptsTotal: promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "auth_attempts_total",
|
|
Help: "Total number of authentication attempts",
|
|
},
|
|
[]string{"action", "result"},
|
|
),
|
|
}
|
|
}
|
|
|
|
// RecordHTTPRequest records an HTTP request
|
|
func (m *PrometheusMetricsService) RecordHTTPRequest(method, path string, statusCode int, duration time.Duration) {
|
|
status := strconv.Itoa(statusCode)
|
|
m.httpRequestsTotal.WithLabelValues(method, path, status).Inc()
|
|
m.httpRequestDuration.WithLabelValues(method, path).Observe(duration.Seconds())
|
|
}
|
|
|
|
// RecordDBOperation records a database operation
|
|
func (m *PrometheusMetricsService) RecordDBOperation(operation, table string) {
|
|
m.dbOperationsTotal.WithLabelValues(operation, table).Inc()
|
|
}
|
|
|
|
// RecordAuthAttempt records an authentication attempt
|
|
func (m *PrometheusMetricsService) RecordAuthAttempt(action, result string) {
|
|
m.authAttemptsTotal.WithLabelValues(action, result).Inc()
|
|
}
|
|
|
|
// StartMetricsServer starts the Prometheus metrics server
|
|
func (m *PrometheusMetricsService) StartMetricsServer(port string) {
|
|
http.Handle("/metrics", promhttp.Handler())
|
|
go func() {
|
|
if err := http.ListenAndServe(":"+port, nil); err != nil {
|
|
// Log error but don't fail the application
|
|
}
|
|
}()
|
|
}
|
|
|
|
// MetricsMiddleware creates a Gin middleware for HTTP metrics
|
|
func (m *PrometheusMetricsService) MetricsMiddleware() gin.HandlerFunc {
|
|
return func(c *gin.Context) {
|
|
start := time.Now()
|
|
|
|
c.Next()
|
|
|
|
duration := time.Since(start)
|
|
m.RecordHTTPRequest(c.Request.Method, c.FullPath(), c.Writer.Status(), duration)
|
|
}
|
|
}
|