mirror of
https://github.com/andwati/telecom-platform.git
synced 2026-10-18 11:02:54 +00:00
334 lines
9.2 KiB
Go
334 lines
9.2 KiB
Go
package metrics
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"time"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
)
|
|
|
|
var (
|
|
// HTTP request metrics
|
|
httpRequestsTotal = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "telecom_http_requests_total",
|
|
Help: "Total number of HTTP requests",
|
|
},
|
|
[]string{"method", "endpoint", "status_code"},
|
|
)
|
|
|
|
httpRequestDuration = prometheus.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "telecom_http_request_duration_seconds",
|
|
Help: "HTTP request duration in seconds",
|
|
Buckets: prometheus.DefBuckets,
|
|
},
|
|
[]string{"method", "endpoint"},
|
|
)
|
|
|
|
// Subscriber metrics
|
|
subscribersTotal = prometheus.NewGauge(
|
|
prometheus.GaugeOpts{
|
|
Name: "telecom_subscribers_total",
|
|
Help: "Total number of subscribers",
|
|
},
|
|
)
|
|
|
|
subscribersActive = prometheus.NewGauge(
|
|
prometheus.GaugeOpts{
|
|
Name: "telecom_subscribers_active",
|
|
Help: "Number of active subscribers",
|
|
},
|
|
)
|
|
|
|
subscribersSuspended = prometheus.NewGauge(
|
|
prometheus.GaugeOpts{
|
|
Name: "telecom_subscribers_suspended",
|
|
Help: "Number of suspended subscribers",
|
|
},
|
|
)
|
|
|
|
// Usage metrics
|
|
dataUsageBytes = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "telecom_data_usage_bytes_total",
|
|
Help: "Total data usage in bytes",
|
|
},
|
|
[]string{"subscriber_id", "direction"},
|
|
)
|
|
|
|
voiceUsageSeconds = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "telecom_voice_usage_seconds_total",
|
|
Help: "Total voice usage in seconds",
|
|
},
|
|
[]string{"subscriber_id"},
|
|
)
|
|
|
|
smsUsageTotal = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "telecom_sms_usage_total",
|
|
Help: "Total SMS count",
|
|
},
|
|
[]string{"subscriber_id"},
|
|
)
|
|
|
|
// Charging metrics
|
|
creditBalance = prometheus.NewGaugeVec(
|
|
prometheus.GaugeOpts{
|
|
Name: "telecom_credit_balance",
|
|
Help: "Subscriber credit balance",
|
|
},
|
|
[]string{"subscriber_id"},
|
|
)
|
|
|
|
paymentTransactionsTotal = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "telecom_payment_transactions_total",
|
|
Help: "Total payment transactions",
|
|
},
|
|
[]string{"status", "gateway"},
|
|
)
|
|
|
|
// System metrics
|
|
activeSessions = prometheus.NewGauge(
|
|
prometheus.GaugeOpts{
|
|
Name: "telecom_active_sessions",
|
|
Help: "Number of active sessions",
|
|
},
|
|
)
|
|
|
|
systemUptime = prometheus.NewGauge(
|
|
prometheus.GaugeOpts{
|
|
Name: "telecom_system_uptime_seconds",
|
|
Help: "System uptime in seconds",
|
|
},
|
|
)
|
|
|
|
// Database metrics
|
|
dbConnectionsActive = prometheus.NewGauge(
|
|
prometheus.GaugeOpts{
|
|
Name: "telecom_db_connections_active",
|
|
Help: "Number of active database connections",
|
|
},
|
|
)
|
|
|
|
dbQueryDuration = prometheus.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "telecom_db_query_duration_seconds",
|
|
Help: "Database query duration in seconds",
|
|
Buckets: prometheus.DefBuckets,
|
|
},
|
|
[]string{"operation"},
|
|
)
|
|
|
|
// Redis metrics
|
|
redisConnectionsActive = prometheus.NewGauge(
|
|
prometheus.GaugeOpts{
|
|
Name: "telecom_redis_connections_active",
|
|
Help: "Number of active Redis connections",
|
|
},
|
|
)
|
|
|
|
redisOperationsTotal = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "telecom_redis_operations_total",
|
|
Help: "Total Redis operations",
|
|
},
|
|
[]string{"operation", "status"},
|
|
)
|
|
|
|
// Chaos engineering metrics
|
|
chaosExperimentsTotal = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "telecom_chaos_experiments_total",
|
|
Help: "Total chaos experiments run",
|
|
},
|
|
[]string{"type", "status"},
|
|
)
|
|
|
|
// eBPF packet gateway metrics
|
|
packetsProcessed = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "telecom_packets_processed_total",
|
|
Help: "Total packets processed by eBPF gateway",
|
|
},
|
|
[]string{"action"},
|
|
)
|
|
|
|
packetsDropped = prometheus.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "telecom_packets_dropped_total",
|
|
Help: "Total packets dropped by eBPF gateway",
|
|
},
|
|
[]string{"reason"},
|
|
)
|
|
)
|
|
|
|
// MetricsCollector handles Prometheus metrics collection
|
|
type MetricsCollector struct {
|
|
startTime time.Time
|
|
}
|
|
|
|
// NewMetricsCollector creates a new metrics collector
|
|
func NewMetricsCollector() *MetricsCollector {
|
|
return &MetricsCollector{
|
|
startTime: time.Now(),
|
|
}
|
|
}
|
|
|
|
// Register registers all metrics with Prometheus
|
|
func (mc *MetricsCollector) Register() {
|
|
prometheus.MustRegister(httpRequestsTotal)
|
|
prometheus.MustRegister(httpRequestDuration)
|
|
prometheus.MustRegister(subscribersTotal)
|
|
prometheus.MustRegister(subscribersActive)
|
|
prometheus.MustRegister(subscribersSuspended)
|
|
prometheus.MustRegister(dataUsageBytes)
|
|
prometheus.MustRegister(voiceUsageSeconds)
|
|
prometheus.MustRegister(smsUsageTotal)
|
|
prometheus.MustRegister(creditBalance)
|
|
prometheus.MustRegister(paymentTransactionsTotal)
|
|
prometheus.MustRegister(activeSessions)
|
|
prometheus.MustRegister(systemUptime)
|
|
prometheus.MustRegister(dbConnectionsActive)
|
|
prometheus.MustRegister(dbQueryDuration)
|
|
prometheus.MustRegister(redisConnectionsActive)
|
|
prometheus.MustRegister(redisOperationsTotal)
|
|
prometheus.MustRegister(chaosExperimentsTotal)
|
|
prometheus.MustRegister(packetsProcessed)
|
|
prometheus.MustRegister(packetsDropped)
|
|
|
|
// Start system uptime goroutine
|
|
go mc.updateSystemMetrics()
|
|
}
|
|
|
|
// updateSystemMetrics updates system-level metrics periodically
|
|
func (mc *MetricsCollector) updateSystemMetrics() {
|
|
ticker := time.NewTicker(10 * time.Second)
|
|
defer ticker.Stop()
|
|
|
|
for range ticker.C {
|
|
systemUptime.Set(time.Since(mc.startTime).Seconds())
|
|
}
|
|
}
|
|
|
|
// HTTPMiddleware returns middleware to track HTTP metrics
|
|
func (mc *MetricsCollector) HTTPMiddleware(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
start := time.Now()
|
|
|
|
// Create a response writer to capture status code
|
|
rw := &responseWriter{ResponseWriter: w, statusCode: 200}
|
|
|
|
// Process request
|
|
next.ServeHTTP(rw, r)
|
|
|
|
// Record metrics
|
|
duration := time.Since(start).Seconds()
|
|
statusCode := rw.statusCode
|
|
|
|
httpRequestsTotal.WithLabelValues(r.Method, r.URL.Path, http.StatusText(statusCode)).Inc()
|
|
httpRequestDuration.WithLabelValues(r.Method, r.URL.Path).Observe(duration)
|
|
})
|
|
}
|
|
|
|
// responseWriter is a wrapper to capture status code
|
|
type responseWriter struct {
|
|
http.ResponseWriter
|
|
statusCode int
|
|
}
|
|
|
|
func (rw *responseWriter) WriteHeader(code int) {
|
|
rw.statusCode = code
|
|
rw.ResponseWriter.WriteHeader(code)
|
|
}
|
|
|
|
// UpdateSubscriberMetrics updates subscriber-related metrics
|
|
func (mc *MetricsCollector) UpdateSubscriberMetrics(total, active, suspended int) {
|
|
subscribersTotal.Set(float64(total))
|
|
subscribersActive.Set(float64(active))
|
|
subscribersSuspended.Set(float64(suspended))
|
|
}
|
|
|
|
// RecordDataUsage records data usage for a subscriber
|
|
func (mc *MetricsCollector) RecordDataUsage(subscriberID string, direction string, bytes int64) {
|
|
dataUsageBytes.WithLabelValues(subscriberID, direction).Add(float64(bytes))
|
|
}
|
|
|
|
// RecordVoiceUsage records voice usage for a subscriber
|
|
func (mc *MetricsCollector) RecordVoiceUsage(subscriberID string, seconds int64) {
|
|
voiceUsageSeconds.WithLabelValues(subscriberID).Add(float64(seconds))
|
|
}
|
|
|
|
// RecordSMSUsage records SMS usage for a subscriber
|
|
func (mc *MetricsCollector) RecordSMSUsage(subscriberID string, count int64) {
|
|
smsUsageTotal.WithLabelValues(subscriberID).Add(float64(count))
|
|
}
|
|
|
|
// UpdateCreditBalance updates credit balance for a subscriber
|
|
func (mc *MetricsCollector) UpdateCreditBalance(subscriberID string, balance float64) {
|
|
creditBalance.WithLabelValues(subscriberID).Set(balance)
|
|
}
|
|
|
|
// RecordPaymentTransaction records a payment transaction
|
|
func (mc *MetricsCollector) RecordPaymentTransaction(status, gateway string) {
|
|
paymentTransactionsTotal.WithLabelValues(status, gateway).Inc()
|
|
}
|
|
|
|
// UpdateActiveSessions updates the active sessions count
|
|
func (mc *MetricsCollector) UpdateActiveSessions(count int) {
|
|
activeSessions.Set(float64(count))
|
|
}
|
|
|
|
// UpdateDBMetrics updates database metrics
|
|
func (mc *MetricsCollector) UpdateDBMetrics(activeConnections int, operation string, duration time.Duration) {
|
|
dbConnectionsActive.Set(float64(activeConnections))
|
|
dbQueryDuration.WithLabelValues(operation).Observe(duration.Seconds())
|
|
}
|
|
|
|
// UpdateRedisMetrics updates Redis metrics
|
|
func (mc *MetricsCollector) UpdateRedisMetrics(activeConnections int, operation, status string) {
|
|
redisConnectionsActive.Set(float64(activeConnections))
|
|
redisOperationsTotal.WithLabelValues(operation, status).Inc()
|
|
}
|
|
|
|
// RecordChaosExperiment records a chaos experiment
|
|
func (mc *MetricsCollector) RecordChaosExperiment(experimentType, status string) {
|
|
chaosExperimentsTotal.WithLabelValues(experimentType, status).Inc()
|
|
}
|
|
|
|
// RecordPacketMetrics records packet processing metrics
|
|
func (mc *MetricsCollector) RecordPacketMetrics(action string, count int64, reason string) {
|
|
if action == "dropped" {
|
|
packetsDropped.WithLabelValues(reason).Add(float64(count))
|
|
} else {
|
|
packetsProcessed.WithLabelValues(action).Add(float64(count))
|
|
}
|
|
}
|
|
|
|
// Handler returns the Prometheus metrics HTTP handler
|
|
func (mc *MetricsCollector) Handler() http.Handler {
|
|
return promhttp.Handler()
|
|
}
|
|
|
|
// StartMetricsServer starts the Prometheus metrics server
|
|
func (mc *MetricsCollector) StartMetricsServer(ctx context.Context, addr string) error {
|
|
mux := http.NewServeMux()
|
|
mux.Handle("/metrics", mc.Handler())
|
|
|
|
server := &http.Server{
|
|
Addr: addr,
|
|
Handler: mux,
|
|
}
|
|
|
|
go func() {
|
|
<-ctx.Done()
|
|
server.Shutdown(context.Background())
|
|
}()
|
|
|
|
return server.ListenAndServe()
|
|
}
|