Add Prometheus metrics for connections, firewall, L7, and bytes transferred

Instrument mc-proxy with prometheus/client_golang. New internal/metrics/
package defines counters, gauges, and histograms for connection totals,
active connections, firewall blocks by reason, backend dial latency,
bytes transferred, L7 HTTP status codes, and L7 policy blocks. Optional
[metrics] config section starts a scrape endpoint. Firewall gains
BlockedWithReason() to report block cause. L7 handler wraps
ResponseWriter to record status codes per hostname.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-25 18:05:25 -07:00
parent 42c7fffc3e
commit ffc31f7d55
16 changed files with 439 additions and 32 deletions

View File

@@ -13,7 +13,7 @@ func TestPolicyMiddlewareNoPolicies(t *testing.T) {
w.WriteHeader(200)
})
handler := PolicyMiddleware(nil, next)
handler := PolicyMiddleware(nil, "test.example.com", next)
req := httptest.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
@@ -35,7 +35,7 @@ func TestPolicyBlockUserAgentMatch(t *testing.T) {
policies := []PolicyRule{
{Type: "block_user_agent", Value: "BadBot"},
}
handler := PolicyMiddleware(policies, next)
handler := PolicyMiddleware(policies, "test.example.com", next)
req := httptest.NewRequest("GET", "/", nil)
req.Header.Set("User-Agent", "Mozilla/5.0 BadBot/1.0")
@@ -57,7 +57,7 @@ func TestPolicyBlockUserAgentNoMatch(t *testing.T) {
policies := []PolicyRule{
{Type: "block_user_agent", Value: "BadBot"},
}
handler := PolicyMiddleware(policies, next)
handler := PolicyMiddleware(policies, "test.example.com", next)
req := httptest.NewRequest("GET", "/", nil)
req.Header.Set("User-Agent", "Mozilla/5.0 GoodBrowser/1.0")
@@ -82,7 +82,7 @@ func TestPolicyRequireHeaderPresent(t *testing.T) {
policies := []PolicyRule{
{Type: "require_header", Value: "X-API-Key"},
}
handler := PolicyMiddleware(policies, next)
handler := PolicyMiddleware(policies, "test.example.com", next)
req := httptest.NewRequest("GET", "/", nil)
req.Header.Set("X-API-Key", "secret")
@@ -105,7 +105,7 @@ func TestPolicyRequireHeaderAbsent(t *testing.T) {
policies := []PolicyRule{
{Type: "require_header", Value: "X-API-Key"},
}
handler := PolicyMiddleware(policies, next)
handler := PolicyMiddleware(policies, "test.example.com", next)
req := httptest.NewRequest("GET", "/", nil)
w := httptest.NewRecorder()
@@ -125,7 +125,7 @@ func TestPolicyMultipleRules(t *testing.T) {
{Type: "block_user_agent", Value: "BadBot"},
{Type: "require_header", Value: "X-Token"},
}
handler := PolicyMiddleware(policies, next)
handler := PolicyMiddleware(policies, "test.example.com", next)
// Blocked by UA even though header is present.
req := httptest.NewRequest("GET", "/", nil)