Files
Test 59a1eeed85 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
2026-08-23 16:33:49 -07:00

112 lines
2.5 KiB
Go

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