feat(egress): replace log bool with integer log levels (0/1/2)
Level 0 (off, default): no stderr output beyond boot line. Level 1 (blocks): each block/warn emitted as JSON with reason and request context (host, method, path, response_status for inbound). Level 2 (full): level-1 events + egress_request and egress_response JSON lines for every forwarded connection. Block logging at level 1+ replaces the previous plain-text stderr write. DLP warn logging is also gated on level 1+. All block call sites now pass _req_ctx(flow) so the blocked request is visible in the log entry. Boot message shows log level label (off/blocks/full). Adds PRD 0053 documenting wire format, manifest format, and all log event shapes. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -346,21 +346,44 @@ class TestConfigShape(unittest.TestCase):
|
||||
"bottle": "dev"}},
|
||||
})
|
||||
|
||||
def test_log_defaults_false(self):
|
||||
def test_log_defaults_zero(self):
|
||||
b = _bottle([])
|
||||
self.assertFalse(b.egress.Log)
|
||||
self.assertEqual(0, b.egress.Log)
|
||||
|
||||
def test_log_true_accepted(self):
|
||||
def test_log_level_1_accepted(self):
|
||||
b = Manifest.from_json_obj({
|
||||
"bottles": {"dev": {"egress": {"log": True, "routes": []}}},
|
||||
"bottles": {"dev": {"egress": {"log": 1, "routes": []}}},
|
||||
"agents": {"demo": {"skills": [], "prompt": "", "bottle": "dev"}},
|
||||
}).bottles["dev"]
|
||||
self.assertTrue(b.egress.Log)
|
||||
self.assertEqual(1, b.egress.Log)
|
||||
|
||||
def test_log_non_bool_rejected(self):
|
||||
def test_log_level_2_accepted(self):
|
||||
b = Manifest.from_json_obj({
|
||||
"bottles": {"dev": {"egress": {"log": 2, "routes": []}}},
|
||||
"agents": {"demo": {"skills": [], "prompt": "", "bottle": "dev"}},
|
||||
}).bottles["dev"]
|
||||
self.assertEqual(2, b.egress.Log)
|
||||
|
||||
def test_log_invalid_level_rejected(self):
|
||||
with self.assertRaises(ManifestError):
|
||||
Manifest.from_json_obj({
|
||||
"bottles": {"dev": {"egress": {"log": "yes"}}},
|
||||
"bottles": {"dev": {"egress": {"log": 3}}},
|
||||
"agents": {"demo": {"skills": [], "prompt": "",
|
||||
"bottle": "dev"}},
|
||||
})
|
||||
|
||||
def test_log_bool_rejected(self):
|
||||
with self.assertRaises(ManifestError):
|
||||
Manifest.from_json_obj({
|
||||
"bottles": {"dev": {"egress": {"log": True}}},
|
||||
"agents": {"demo": {"skills": [], "prompt": "",
|
||||
"bottle": "dev"}},
|
||||
})
|
||||
|
||||
def test_log_string_rejected(self):
|
||||
with self.assertRaises(ManifestError):
|
||||
Manifest.from_json_obj({
|
||||
"bottles": {"dev": {"egress": {"log": "full"}}},
|
||||
"agents": {"demo": {"skills": [], "prompt": "",
|
||||
"bottle": "dev"}},
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user