You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
210 lines
5.2 KiB
Go
210 lines
5.2 KiB
Go
// Package metrics provides Prometheus metrics for the KnowFoolery application.
|
|
package metrics
|
|
|
|
import (
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
)
|
|
|
|
// Config holds the configuration for metrics.
|
|
type Config struct {
|
|
ServiceName string
|
|
Enabled bool
|
|
Registry prometheus.Registerer
|
|
}
|
|
|
|
// DefaultConfig returns a default configuration.
|
|
func DefaultConfig() Config {
|
|
return Config{
|
|
ServiceName: "knowfoolery",
|
|
Enabled: true,
|
|
}
|
|
}
|
|
|
|
// Metrics holds all Prometheus metrics for the application.
|
|
type Metrics struct {
|
|
config Config
|
|
|
|
// HTTP metrics
|
|
HTTPRequestsTotal *prometheus.CounterVec
|
|
HTTPRequestDuration *prometheus.HistogramVec
|
|
|
|
// Database metrics
|
|
DBConnectionsActive *prometheus.GaugeVec
|
|
DBQueryDuration *prometheus.HistogramVec
|
|
DBErrors *prometheus.CounterVec
|
|
|
|
// Cache metrics
|
|
CacheOperations *prometheus.CounterVec
|
|
CacheKeyCount *prometheus.GaugeVec
|
|
|
|
// Authentication metrics
|
|
AuthAttempts *prometheus.CounterVec
|
|
TokenOperations *prometheus.CounterVec
|
|
|
|
// Game metrics
|
|
GamesStarted *prometheus.CounterVec
|
|
GamesCompleted *prometheus.CounterVec
|
|
SessionDuration *prometheus.HistogramVec
|
|
QuestionsAsked *prometheus.CounterVec
|
|
AnswersSubmitted *prometheus.CounterVec
|
|
HintsRequested *prometheus.CounterVec
|
|
ScoreDistribution *prometheus.HistogramVec
|
|
}
|
|
|
|
// NewMetrics creates a new Metrics instance with all metrics registered.
|
|
func NewMetrics(config Config) *Metrics {
|
|
registry := config.Registry
|
|
if registry == nil {
|
|
registry = prometheus.DefaultRegisterer
|
|
}
|
|
auto := promauto.With(registry)
|
|
|
|
m := &Metrics{config: config}
|
|
|
|
// HTTP metrics
|
|
m.HTTPRequestsTotal = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "http_requests_total",
|
|
Help: "Total number of HTTP requests",
|
|
},
|
|
[]string{"method", "endpoint", "status_code", "service"},
|
|
)
|
|
|
|
m.HTTPRequestDuration = auto.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "http_request_duration_seconds",
|
|
Help: "HTTP request duration",
|
|
Buckets: prometheus.DefBuckets,
|
|
},
|
|
[]string{"method", "endpoint", "service"},
|
|
)
|
|
|
|
// Database metrics
|
|
m.DBConnectionsActive = auto.NewGaugeVec(
|
|
prometheus.GaugeOpts{
|
|
Name: "db_connections_active",
|
|
Help: "Number of active database connections",
|
|
},
|
|
[]string{"database", "service"},
|
|
)
|
|
|
|
m.DBQueryDuration = auto.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "db_query_duration_seconds",
|
|
Help: "Database query duration",
|
|
Buckets: []float64{0.001, 0.005, 0.01, 0.05, 0.1, 0.5, 1.0, 2.0, 5.0},
|
|
},
|
|
[]string{"query_type", "table", "service"},
|
|
)
|
|
|
|
m.DBErrors = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "db_errors_total",
|
|
Help: "Total number of database errors",
|
|
},
|
|
[]string{"error_type", "service"},
|
|
)
|
|
|
|
// Cache metrics
|
|
m.CacheOperations = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "cache_operations_total",
|
|
Help: "Total number of cache operations",
|
|
},
|
|
[]string{"operation", "result", "service"},
|
|
)
|
|
|
|
m.CacheKeyCount = auto.NewGaugeVec(
|
|
prometheus.GaugeOpts{
|
|
Name: "cache_keys_total",
|
|
Help: "Number of keys in cache",
|
|
},
|
|
[]string{"cache_type", "service"},
|
|
)
|
|
|
|
// Authentication metrics
|
|
m.AuthAttempts = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "authentication_attempts_total",
|
|
Help: "Total authentication attempts",
|
|
},
|
|
[]string{"method", "result", "user_type"},
|
|
)
|
|
|
|
m.TokenOperations = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "token_operations_total",
|
|
Help: "JWT token operations",
|
|
},
|
|
[]string{"operation", "result"},
|
|
)
|
|
|
|
// Game metrics
|
|
m.GamesStarted = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "games_started_total",
|
|
Help: "Total number of games started",
|
|
},
|
|
[]string{"player_type", "platform"},
|
|
)
|
|
|
|
m.GamesCompleted = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "games_completed_total",
|
|
Help: "Total number of games completed",
|
|
},
|
|
[]string{"completion_type", "platform"},
|
|
)
|
|
|
|
m.SessionDuration = auto.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "game_session_duration_seconds",
|
|
Help: "Duration of game sessions",
|
|
Buckets: []float64{60, 300, 600, 900, 1200, 1500, 1800},
|
|
},
|
|
[]string{"completion_type"},
|
|
)
|
|
|
|
m.QuestionsAsked = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "questions_asked_total",
|
|
Help: "Total number of questions asked",
|
|
},
|
|
[]string{"theme", "difficulty"},
|
|
)
|
|
|
|
m.AnswersSubmitted = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "answers_submitted_total",
|
|
Help: "Total number of answers submitted",
|
|
},
|
|
[]string{"theme", "is_correct", "attempt_number", "used_hint"},
|
|
)
|
|
|
|
m.HintsRequested = auto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "hints_requested_total",
|
|
Help: "Total number of hints requested",
|
|
},
|
|
[]string{"theme", "question_difficulty"},
|
|
)
|
|
|
|
m.ScoreDistribution = auto.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "game_scores",
|
|
Help: "Distribution of game scores",
|
|
Buckets: []float64{0, 5, 10, 15, 20, 25, 30, 40, 50, 60, 80, 100},
|
|
},
|
|
[]string{"session_duration_bucket"},
|
|
)
|
|
|
|
return m
|
|
}
|
|
|
|
// ConfigFromEnv creates a Config from environment variables.
|
|
func ConfigFromEnv() Config {
|
|
// TODO: Implement environment variable parsing
|
|
return DefaultConfig()
|
|
}
|