This commit is contained in:
137
metrics.go
Normal file
137
metrics.go
Normal file
@@ -0,0 +1,137 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"time"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/prometheus/client_golang/prometheus"
|
||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||
)
|
||||
|
||||
var (
|
||||
// HTTP request metrics
|
||||
httpRequestsTotal = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "http_requests_total",
|
||||
Help: "Total number of HTTP requests",
|
||||
},
|
||||
[]string{"method", "endpoint", "status_code"},
|
||||
)
|
||||
|
||||
// HTTP request duration metrics
|
||||
httpRequestDuration = prometheus.NewHistogramVec(
|
||||
prometheus.HistogramOpts{
|
||||
Name: "http_request_duration_seconds",
|
||||
Help: "HTTP request duration in seconds",
|
||||
Buckets: prometheus.DefBuckets,
|
||||
},
|
||||
[]string{"method", "endpoint"},
|
||||
)
|
||||
|
||||
// API endpoint specific metrics
|
||||
apiRequestsTotal = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "api_requests_total",
|
||||
Help: "Total number of API requests by endpoint",
|
||||
},
|
||||
[]string{"endpoint", "method"},
|
||||
)
|
||||
|
||||
// Database operation metrics
|
||||
dbOperationsTotal = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "db_operations_total",
|
||||
Help: "Total number of database operations",
|
||||
},
|
||||
[]string{"operation", "table"},
|
||||
)
|
||||
|
||||
// Authentication metrics
|
||||
authAttemptsTotal = prometheus.NewCounterVec(
|
||||
prometheus.CounterOpts{
|
||||
Name: "auth_attempts_total",
|
||||
Help: "Total number of authentication attempts",
|
||||
},
|
||||
[]string{"type", "status"},
|
||||
)
|
||||
)
|
||||
|
||||
// InitMetrics initializes Prometheus metrics
|
||||
func InitMetrics() {
|
||||
// Register all metrics
|
||||
prometheus.MustRegister(httpRequestsTotal)
|
||||
prometheus.MustRegister(httpRequestDuration)
|
||||
prometheus.MustRegister(apiRequestsTotal)
|
||||
prometheus.MustRegister(dbOperationsTotal)
|
||||
prometheus.MustRegister(authAttemptsTotal)
|
||||
}
|
||||
|
||||
// StartMetricsServer starts the metrics server on a separate port
|
||||
func StartMetricsServer(port string) {
|
||||
// Create a new HTTP server for metrics
|
||||
metricsMux := http.NewServeMux()
|
||||
metricsMux.Handle("/metrics", promhttp.Handler())
|
||||
|
||||
// Add health check for metrics server
|
||||
metricsMux.HandleFunc("/health", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write([]byte("Metrics server is healthy"))
|
||||
})
|
||||
|
||||
server := &http.Server{
|
||||
Addr: "localhost:" + port,
|
||||
Handler: metricsMux,
|
||||
ReadTimeout: 5 * time.Second,
|
||||
WriteTimeout: 10 * time.Second,
|
||||
}
|
||||
|
||||
go func() {
|
||||
log.Printf("📈 Metrics server starting on http://localhost:%s/metrics", port)
|
||||
if err := server.ListenAndServe(); err != nil && err != http.ErrServerClosed {
|
||||
log.Printf("❌ Metrics server failed to start: %v", err)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// MetricsMiddleware is a Gin middleware to collect HTTP metrics
|
||||
func MetricsMiddleware() gin.HandlerFunc {
|
||||
return func(c *gin.Context) {
|
||||
start := time.Now()
|
||||
path := c.FullPath()
|
||||
method := c.Request.Method
|
||||
|
||||
// Process request
|
||||
c.Next()
|
||||
|
||||
// Calculate duration
|
||||
duration := time.Since(start).Seconds()
|
||||
statusCode := strconv.Itoa(c.Writer.Status())
|
||||
|
||||
// Record metrics
|
||||
httpRequestsTotal.WithLabelValues(method, path, statusCode).Inc()
|
||||
httpRequestDuration.WithLabelValues(method, path).Observe(duration)
|
||||
|
||||
// Record API-specific metrics for API routes
|
||||
if c.Request.URL.Path[:4] == "/api" {
|
||||
apiRequestsTotal.WithLabelValues(path, method).Inc()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// RecordAPICall records a specific API endpoint call
|
||||
func RecordAPICall(endpoint, method string) {
|
||||
apiRequestsTotal.WithLabelValues(endpoint, method).Inc()
|
||||
}
|
||||
|
||||
// RecordDBOperation records a database operation
|
||||
func RecordDBOperation(operation, table string) {
|
||||
dbOperationsTotal.WithLabelValues(operation, table).Inc()
|
||||
}
|
||||
|
||||
// RecordAuthAttempt records an authentication attempt
|
||||
func RecordAuthAttempt(authType, status string) {
|
||||
authAttemptsTotal.WithLabelValues(authType, status).Inc()
|
||||
}
|
||||
Reference in New Issue
Block a user