refactor
All checks were successful
continuous-integration/drone/push Build is passing

This commit is contained in:
aovantsev
2025-10-10 19:56:06 +03:00
parent f081c9d947
commit 73ed514a34
30 changed files with 1728 additions and 1020 deletions

View File

@@ -0,0 +1,103 @@
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)
}
}