feat(T1.2): implement structured logging and Prometheus metrics
- 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
This commit is contained in:
@@ -0,0 +1,111 @@
|
||||
package metrics
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestRecordWorkflowStarted(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordWorkflowStarted("TestWorkflow")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordWorkflowCompleted(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordWorkflowCompleted("TestWorkflow", "success", 1.5)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordActivityStarted(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordActivityStarted("TestActivity")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordActivityCompleted(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordActivityCompleted("TestActivity", "success", 0.5)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordActivityRetry(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordActivityRetry("TestActivity")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordLLMAPICall(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordLLMAPICall("claude-opus", "success", 2.0)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordGitOperation(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordGitOperation("clone", "success", 5.0)
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordJudgeDecision(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordJudgeDecision("approve")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordTemporalConnectionError(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordTemporalConnectionError("connection_timeout")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordCacheHit(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordCacheHit("llm_response")
|
||||
})
|
||||
}
|
||||
|
||||
func TestRecordCacheMiss(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
RecordCacheMiss("llm_response")
|
||||
})
|
||||
}
|
||||
|
||||
func TestUpdateTasksInProgress(t *testing.T) {
|
||||
// Should not panic
|
||||
assert.NotPanics(t, func() {
|
||||
UpdateTasksInProgress("T0", 5.0)
|
||||
})
|
||||
}
|
||||
|
||||
// TestMetricsExist verifies all metrics are registered
|
||||
func TestMetricsExist(t *testing.T) {
|
||||
assert.NotNil(t, WorkflowExecutionsStarted)
|
||||
assert.NotNil(t, WorkflowExecutionsCompleted)
|
||||
assert.NotNil(t, WorkflowDuration)
|
||||
assert.NotNil(t, ActivityExecutionsStarted)
|
||||
assert.NotNil(t, ActivityExecutionsCompleted)
|
||||
assert.NotNil(t, ActivityDuration)
|
||||
assert.NotNil(t, ActivityRetries)
|
||||
assert.NotNil(t, LLMAPICallsTotal)
|
||||
assert.NotNil(t, LLMAPILatency)
|
||||
assert.NotNil(t, GitOperationsTotal)
|
||||
assert.NotNil(t, GitOperationsDuration)
|
||||
assert.NotNil(t, TasksInProgress)
|
||||
assert.NotNil(t, JudgeDecisionsTotal)
|
||||
assert.NotNil(t, TemporalConnectionErrors)
|
||||
assert.NotNil(t, CacheHits)
|
||||
assert.NotNil(t, CacheMisses)
|
||||
}
|
||||
Reference in New Issue
Block a user