// 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() }