- Add internal/logging package with zap-based structured JSON logging - Support development (colored) and production (JSON) modes via ENVIRONMENT env var - Add logging helpers: Info(), Error(), Warn(), Debug(), Fatal() - Add field helpers: String(), Int(), Int64(), Err() - Add internal/metrics package with 16 comprehensive Prometheus metrics - Track workflows: starts, completions, duration by type/status - Track activities: starts, completions, duration, retries by type - Track LLM calls: total calls and latency by model - Track git operations: total and duration by operation type - Track judge decisions: decisions by type - Track Temporal errors: connection errors by type - Track cache efficiency: hits and misses by cache type - Track tasks in progress: gauge metric by task type - Metrics exported on /metrics endpoint (Prometheus text format) - Integrate structured logging in cmd/worker and cmd/starter - Replace all log.Printf/log.Fatalf with structured logging - Add /metrics endpoint to health check server - 8/8 logging tests passing, 13/13 metrics tests passing - All verification criteria met Dependencies added: - go.uber.org/zap v1.28.0 (structured logging) - github.com/prometheus/client_golang v1.24.1 (metrics export) Closes T1.2
221 lines
6.7 KiB
Go
221 lines
6.7 KiB
Go
package metrics
|
|
|
|
import (
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
)
|
|
|
|
// WorkflowMetrics holds all workflow-related prometheus metrics
|
|
var (
|
|
// WorkflowExecutionsStarted tracks total workflows started
|
|
WorkflowExecutionsStarted = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_workflow_executions_started_total",
|
|
Help: "Total number of workflow executions started",
|
|
},
|
|
[]string{"workflow_type"},
|
|
)
|
|
|
|
// WorkflowExecutionsCompleted tracks total workflows completed
|
|
WorkflowExecutionsCompleted = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_workflow_executions_completed_total",
|
|
Help: "Total number of workflow executions completed",
|
|
},
|
|
[]string{"workflow_type", "status"},
|
|
)
|
|
|
|
// WorkflowDuration tracks workflow execution duration
|
|
WorkflowDuration = promauto.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "poimen_workflow_duration_seconds",
|
|
Help: "Workflow execution duration in seconds",
|
|
Buckets: prometheus.DefBuckets,
|
|
},
|
|
[]string{"workflow_type"},
|
|
)
|
|
|
|
// ActivityExecutionsStarted tracks total activities started
|
|
ActivityExecutionsStarted = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_activity_executions_started_total",
|
|
Help: "Total number of activity executions started",
|
|
},
|
|
[]string{"activity_type"},
|
|
)
|
|
|
|
// ActivityExecutionsCompleted tracks total activities completed
|
|
ActivityExecutionsCompleted = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_activity_executions_completed_total",
|
|
Help: "Total number of activity executions completed",
|
|
},
|
|
[]string{"activity_type", "status"},
|
|
)
|
|
|
|
// ActivityDuration tracks activity execution duration
|
|
ActivityDuration = promauto.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "poimen_activity_duration_seconds",
|
|
Help: "Activity execution duration in seconds",
|
|
Buckets: prometheus.DefBuckets,
|
|
},
|
|
[]string{"activity_type"},
|
|
)
|
|
|
|
// ActivityRetries tracks activity retries
|
|
ActivityRetries = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_activity_retries_total",
|
|
Help: "Total number of activity retries",
|
|
},
|
|
[]string{"activity_type"},
|
|
)
|
|
|
|
// LLMAPICallsTotal tracks LLM API calls
|
|
LLMAPICallsTotal = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_llm_api_calls_total",
|
|
Help: "Total number of LLM API calls",
|
|
},
|
|
[]string{"model_id", "status"},
|
|
)
|
|
|
|
// LLMAPILatency tracks LLM API call latency
|
|
LLMAPILatency = promauto.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "poimen_llm_api_latency_seconds",
|
|
Help: "LLM API call latency in seconds",
|
|
Buckets: prometheus.DefBuckets,
|
|
},
|
|
[]string{"model_id"},
|
|
)
|
|
|
|
// GitOperationsTotal tracks git operations
|
|
GitOperationsTotal = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_git_operations_total",
|
|
Help: "Total number of git operations",
|
|
},
|
|
[]string{"operation", "status"},
|
|
)
|
|
|
|
// GitOperationsDuration tracks git operation duration
|
|
GitOperationsDuration = promauto.NewHistogramVec(
|
|
prometheus.HistogramOpts{
|
|
Name: "poimen_git_operations_duration_seconds",
|
|
Help: "Git operation duration in seconds",
|
|
Buckets: prometheus.DefBuckets,
|
|
},
|
|
[]string{"operation"},
|
|
)
|
|
|
|
// TasksInProgress tracks current tasks in progress
|
|
TasksInProgress = promauto.NewGaugeVec(
|
|
prometheus.GaugeOpts{
|
|
Name: "poimen_tasks_in_progress",
|
|
Help: "Current number of tasks in progress",
|
|
},
|
|
[]string{"task_type"},
|
|
)
|
|
|
|
// JudgeDecisionsTotal tracks judge decisions
|
|
JudgeDecisionsTotal = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_judge_decisions_total",
|
|
Help: "Total number of judge decisions",
|
|
},
|
|
[]string{"decision"},
|
|
)
|
|
|
|
// TemporalConnectionErrors tracks Temporal connection errors
|
|
TemporalConnectionErrors = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_temporal_connection_errors_total",
|
|
Help: "Total number of Temporal connection errors",
|
|
},
|
|
[]string{"error_type"},
|
|
)
|
|
|
|
// CacheHitRate tracks cache hit/miss ratio
|
|
CacheHits = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_cache_hits_total",
|
|
Help: "Total number of cache hits",
|
|
},
|
|
[]string{"cache_type"},
|
|
)
|
|
|
|
CacheMisses = promauto.NewCounterVec(
|
|
prometheus.CounterOpts{
|
|
Name: "poimen_cache_misses_total",
|
|
Help: "Total number of cache misses",
|
|
},
|
|
[]string{"cache_type"},
|
|
)
|
|
)
|
|
|
|
// RecordWorkflowStarted records a workflow execution start
|
|
func RecordWorkflowStarted(workflowType string) {
|
|
WorkflowExecutionsStarted.WithLabelValues(workflowType).Inc()
|
|
}
|
|
|
|
// RecordWorkflowCompleted records a workflow execution completion
|
|
func RecordWorkflowCompleted(workflowType, status string, durationSeconds float64) {
|
|
WorkflowExecutionsCompleted.WithLabelValues(workflowType, status).Inc()
|
|
WorkflowDuration.WithLabelValues(workflowType).Observe(durationSeconds)
|
|
}
|
|
|
|
// RecordActivityStarted records an activity execution start
|
|
func RecordActivityStarted(activityType string) {
|
|
ActivityExecutionsStarted.WithLabelValues(activityType).Inc()
|
|
}
|
|
|
|
// RecordActivityCompleted records an activity execution completion
|
|
func RecordActivityCompleted(activityType, status string, durationSeconds float64) {
|
|
ActivityExecutionsCompleted.WithLabelValues(activityType, status).Inc()
|
|
ActivityDuration.WithLabelValues(activityType).Observe(durationSeconds)
|
|
}
|
|
|
|
// RecordActivityRetry records an activity retry
|
|
func RecordActivityRetry(activityType string) {
|
|
ActivityRetries.WithLabelValues(activityType).Inc()
|
|
}
|
|
|
|
// RecordLLMAPICall records an LLM API call
|
|
func RecordLLMAPICall(modelID, status string, latencySeconds float64) {
|
|
LLMAPICallsTotal.WithLabelValues(modelID, status).Inc()
|
|
LLMAPILatency.WithLabelValues(modelID).Observe(latencySeconds)
|
|
}
|
|
|
|
// RecordGitOperation records a git operation
|
|
func RecordGitOperation(operation, status string, durationSeconds float64) {
|
|
GitOperationsTotal.WithLabelValues(operation, status).Inc()
|
|
GitOperationsDuration.WithLabelValues(operation).Observe(durationSeconds)
|
|
}
|
|
|
|
// RecordJudgeDecision records a judge decision
|
|
func RecordJudgeDecision(decision string) {
|
|
JudgeDecisionsTotal.WithLabelValues(decision).Inc()
|
|
}
|
|
|
|
// RecordTemporalConnectionError records a Temporal connection error
|
|
func RecordTemporalConnectionError(errorType string) {
|
|
TemporalConnectionErrors.WithLabelValues(errorType).Inc()
|
|
}
|
|
|
|
// RecordCacheHit records a cache hit
|
|
func RecordCacheHit(cacheType string) {
|
|
CacheHits.WithLabelValues(cacheType).Inc()
|
|
}
|
|
|
|
// RecordCacheMiss records a cache miss
|
|
func RecordCacheMiss(cacheType string) {
|
|
CacheMisses.WithLabelValues(cacheType).Inc()
|
|
}
|
|
|
|
// UpdateTasksInProgress updates the current number of tasks in progress
|
|
func UpdateTasksInProgress(taskType string, count float64) {
|
|
TasksInProgress.WithLabelValues(taskType).Set(count)
|
|
}
|