railiance-telemetry/scripts/prometheus_export.py
tegwick b6d0f78f93 Complete local Prometheus mapping and record live acceptance blockers
Assistant: codex
Assistant-Model: gpt-6-astra
Assistant-Session: 01a0e6f1-443f-7783-9920-a16b2ffc467f
2026-09-28 09:42:04 +02:00

55 lines
2.2 KiB
Python

#!/usr/bin/env python3
"""Render a validated S3 report as Prometheus text; no listener or delivery."""
import argparse
from datetime import datetime, timezone
import json
from pathlib import Path
import sys
from platform_event import translate
from receiver import STATES, contract_check, instant, read_json
def labels(values):
def escape(value):
return value.replace('\\', '\\\\').replace('\n', '\\n').replace('"', '\\"')
return '{' + ','.join(f'{key}="{escape(value)}"' for key, value in values.items()) + '}'
def render(report, contract, now):
contract_check(contract)
event = translate(report, contract)
observed = instant(event['observed_at']).timestamp()
if not 0 <= now.timestamp() - observed <= contract['max_event_age_seconds']:
raise ValueError('stale or future report')
identity = dict(stream=contract['stream'], producer=contract['producer'])
lines = ['# HELP railiance_assurance_state Producer classification, one hot per signal.',
'# TYPE railiance_assurance_state gauge']
for signal, state in sorted(event['states'].items()):
for candidate in sorted(STATES):
key = labels(dict(identity, signal=signal, state=candidate))
lines.append(f'railiance_assurance_state{key} {int(state == candidate)}')
lines.extend([
'# HELP railiance_assurance_observed_timestamp_seconds Original producer evaluation time.',
'# TYPE railiance_assurance_observed_timestamp_seconds gauge',
f'railiance_assurance_observed_timestamp_seconds{labels(identity)} {observed}',
])
return '\n'.join(lines) + '\n'
def main():
parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument('--contract', required=True, type=Path)
parser.add_argument('report', type=Path)
args = parser.parse_args()
try:
output = render(read_json(args.report), read_json(args.contract), datetime.now(timezone.utc))
except (OSError, ValueError, KeyError, TypeError, AttributeError):
print(json.dumps({'status': 'rejected', 'error': 'invalid-or-expired-report'}), file=sys.stderr)
return 2
sys.stdout.write(output)
return 0
if __name__ == '__main__':
sys.exit(main())