This commit completes Beat 1 of the SequentialThinkingForCHORUS implementation, providing a functional plaintext skeleton for the age-encrypted wrapper. ## Deliverables ### 1. Main Wrapper Entry Point - `cmd/seqthink-wrapper/main.go`: HTTP server on :8443 - Configuration loading from environment variables - Graceful shutdown handling - MCP server readiness checking with timeout ### 2. MCP Client Package - `pkg/seqthink/mcpclient/client.go`: HTTP client for MCP server - Communicates with MCP server on localhost:8000 - Health check endpoint - Tool call endpoint with 120s timeout ### 3. Proxy Server Package - `pkg/seqthink/proxy/server.go`: HTTP handlers for wrapper - Health and readiness endpoints - Tool call proxy (plaintext for Beat 1) - SSE endpoint placeholder - Metrics endpoint integration ### 4. Observability Package - `pkg/seqthink/observability/logger.go`: Structured logging with zerolog - `pkg/seqthink/observability/metrics.go`: Prometheus metrics - Counters for requests, errors, decrypt/encrypt failures, policy denials - Request duration histogram ### 5. Docker Infrastructure - `deploy/seqthink/Dockerfile`: Multi-stage build - `deploy/seqthink/entrypoint.sh`: Startup orchestration - `deploy/seqthink/mcp_stub.py`: Minimal MCP server for testing ### 6. Build System Integration - Updated `Makefile` with `build-seqthink` target - Uses GOWORK=off and -mod=mod for clean builds - `docker-seqthink` target for container builds ## Testing Successfully builds with: ``` make build-seqthink ``` Binary successfully starts and waits for MCP server connection. ## Next Steps Beat 2 will add: - Age encryption/decryption (pkg/seqthink/ageio) - Content-Type: application/age enforcement - SSE streaming with encrypted frames - Golden tests for crypto round-trips 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
86 lines
2.4 KiB
Go
86 lines
2.4 KiB
Go
package observability
|
|
|
|
import (
|
|
"net/http"
|
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
"github.com/prometheus/client_golang/prometheus/promauto"
|
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
|
)
|
|
|
|
// Metrics holds Prometheus metrics for the wrapper
|
|
type Metrics struct {
|
|
requestsTotal prometheus.Counter
|
|
errorsTotal prometheus.Counter
|
|
decryptFails prometheus.Counter
|
|
encryptFails prometheus.Counter
|
|
policyDenials prometheus.Counter
|
|
requestDuration prometheus.Histogram
|
|
}
|
|
|
|
// InitMetrics initializes Prometheus metrics
|
|
func InitMetrics() *Metrics {
|
|
return &Metrics{
|
|
requestsTotal: promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "seqthink_requests_total",
|
|
Help: "Total number of requests received",
|
|
}),
|
|
errorsTotal: promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "seqthink_errors_total",
|
|
Help: "Total number of errors",
|
|
}),
|
|
decryptFails: promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "seqthink_decrypt_failures_total",
|
|
Help: "Total number of decryption failures",
|
|
}),
|
|
encryptFails: promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "seqthink_encrypt_failures_total",
|
|
Help: "Total number of encryption failures",
|
|
}),
|
|
policyDenials: promauto.NewCounter(prometheus.CounterOpts{
|
|
Name: "seqthink_policy_denials_total",
|
|
Help: "Total number of policy denials",
|
|
}),
|
|
requestDuration: promauto.NewHistogram(prometheus.HistogramOpts{
|
|
Name: "seqthink_request_duration_seconds",
|
|
Help: "Request duration in seconds",
|
|
Buckets: prometheus.DefBuckets,
|
|
}),
|
|
}
|
|
}
|
|
|
|
// IncrementRequests increments the request counter
|
|
func (m *Metrics) IncrementRequests() {
|
|
m.requestsTotal.Inc()
|
|
}
|
|
|
|
// IncrementErrors increments the error counter
|
|
func (m *Metrics) IncrementErrors() {
|
|
m.errorsTotal.Inc()
|
|
}
|
|
|
|
// IncrementDecryptFails increments the decrypt failure counter
|
|
func (m *Metrics) IncrementDecryptFails() {
|
|
m.decryptFails.Inc()
|
|
}
|
|
|
|
// IncrementEncryptFails increments the encrypt failure counter
|
|
func (m *Metrics) IncrementEncryptFails() {
|
|
m.encryptFails.Inc()
|
|
}
|
|
|
|
// IncrementPolicyDenials increments the policy denial counter
|
|
func (m *Metrics) IncrementPolicyDenials() {
|
|
m.policyDenials.Inc()
|
|
}
|
|
|
|
// ObserveRequestDuration records request duration
|
|
func (m *Metrics) ObserveRequestDuration(seconds float64) {
|
|
m.requestDuration.Observe(seconds)
|
|
}
|
|
|
|
// Handler returns the Prometheus metrics HTTP handler
|
|
func (m *Metrics) Handler() http.Handler {
|
|
return promhttp.Handler()
|
|
}
|