Initial Commit
This commit is contained in:
72
reporter/main.py
Normal file
72
reporter/main.py
Normal file
@ -0,0 +1,72 @@
|
||||
import os
|
||||
import subprocess
|
||||
import csv
|
||||
import io
|
||||
from flask import Flask, jsonify
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
# Config
|
||||
NODE_ID = os.environ.get("NODE_ID", "unknown-node")
|
||||
PUBLIC_IP = os.environ.get("PUBLIC_IP", "unknown-ip")
|
||||
BIND_IP = os.environ.get("BIND_IP", "127.0.0.1")
|
||||
CHRONY_HOST = "127.0.0.1"
|
||||
|
||||
def run_chronyc(command):
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["chronyc", "-h", CHRONY_HOST, "-c"] + command,
|
||||
capture_output=True, text=True, timeout=2, check=True
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except Exception as e:
|
||||
print(f"Error running 'chronyc {command}': {e}")
|
||||
return None
|
||||
|
||||
def parse_tracking():
|
||||
raw_csv = run_chronyc(["tracking"])
|
||||
if not raw_csv: return {"Error": "Could not run tracking command"}
|
||||
try:
|
||||
reader = csv.reader(io.StringIO(raw_csv))
|
||||
headers = [
|
||||
"Reference ID", "Ref Source IP", "Stratum", "Ref time (UTC)", "System time",
|
||||
"Last offset", "RMS offset", "Frequency", "Residual freq",
|
||||
"Skew", "Root delay", "Root dispersion", "Update interval", "Leap status"
|
||||
]
|
||||
values = next(reader)
|
||||
return dict(zip(headers, values))
|
||||
except Exception as e:
|
||||
return {"Error": f"Failed to parse tracking CSV: {e}", "RawData": raw_csv}
|
||||
|
||||
def parse_sources():
|
||||
raw_csv = run_chronyc(["sources"])
|
||||
if not raw_csv: return []
|
||||
try:
|
||||
reader = csv.reader(io.StringIO(raw_csv))
|
||||
# --- FIX: Add 10th header 'Std Dev' ---
|
||||
headers = [
|
||||
"Mode", "State", "Name/IP address", "Stratum", "Poll", "Reach",
|
||||
"LastRx", "Last sample", "Last sample original", "Std Dev" # Was: Last sample error
|
||||
]
|
||||
sources_list = []
|
||||
for row in reader:
|
||||
if row: sources_list.append(dict(zip(headers, row)))
|
||||
return sources_list
|
||||
except Exception as e:
|
||||
print(f"Error parsing sources: {e}")
|
||||
return []
|
||||
|
||||
@app.route('/fragment.json')
|
||||
def get_fragment():
|
||||
tracking_data = parse_tracking()
|
||||
sources_data = parse_sources()
|
||||
return jsonify({
|
||||
"node_id": NODE_ID,
|
||||
"public_ip": PUBLIC_IP,
|
||||
"report_generated_time": subprocess.run(["date", "-u", "+%Y-%m-%dT%H:%M:%SZ"], capture_output=True, text=True).stdout.strip(),
|
||||
"tracking": tracking_data,
|
||||
"sources": sources_data
|
||||
})
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host=BIND_IP, port=9898)
|
||||
Reference in New Issue
Block a user