[ADD] Add api
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python3
|
||||
# -*- coding: UTF-8 -*-
|
||||
#-------------------------------------------------------------------------------
|
||||
# Name: check_providers_api.py
|
||||
# Purpose: Flask API to expose check_providers state and history
|
||||
#
|
||||
# Routes:
|
||||
# GET /status -> current state of all providers (from JSON state file)
|
||||
# GET /history -> event history from SQLite
|
||||
# ?provider=NAME -> filter by provider name
|
||||
# ?limit=N -> number of rows (default: 200)
|
||||
# ?transitions=true -> only show up<->down transitions
|
||||
# ?days=N -> limit to last N days (default: 7)
|
||||
#-------------------------------------------------------------------------------
|
||||
|
||||
import os
|
||||
import json
|
||||
import sqlite3
|
||||
|
||||
from flask import Flask, jsonify, request, Response
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
BASE_DIR = '/opt/check_providers'
|
||||
STATE_FILE = os.path.join(BASE_DIR, 'check-providers-state.json')
|
||||
DB_PATH = os.path.join(BASE_DIR, 'check-providers.db')
|
||||
|
||||
|
||||
def get_db():
|
||||
conn = sqlite3.connect(DB_PATH)
|
||||
conn.row_factory = sqlite3.Row
|
||||
return conn
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Routes
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
@app.route('/status')
|
||||
def status():
|
||||
"""Return the current state of all providers from the JSON state file."""
|
||||
try:
|
||||
with open(STATE_FILE) as f:
|
||||
content = f.read()
|
||||
return Response(content, mimetype='application/json')
|
||||
except FileNotFoundError:
|
||||
return jsonify({'error': 'No state file found — is the monitor running?'}), 503
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@app.route('/history')
|
||||
def history():
|
||||
"""
|
||||
Return event history from SQLite.
|
||||
|
||||
Query params:
|
||||
provider : filter by provider name
|
||||
limit : max rows returned (default 200, max 5000)
|
||||
transitions : if 'true', only return up<->down transitions
|
||||
days : only return events from the last N days (default 7)
|
||||
"""
|
||||
provider = request.args.get('provider')
|
||||
limit = min(int(request.args.get('limit', 200)), 5000)
|
||||
only_transitions = request.args.get('transitions', 'false').lower() == 'true'
|
||||
days = int(request.args.get('days', 7))
|
||||
|
||||
query = '''
|
||||
SELECT id, ts, provider, available, rtt, loss, status, transition
|
||||
FROM events
|
||||
'''
|
||||
where, params = [], []
|
||||
|
||||
where.append("ts >= datetime('now', '-{} days')".format(days))
|
||||
|
||||
if provider:
|
||||
where.append('provider = ?')
|
||||
params.append(provider)
|
||||
|
||||
if only_transitions:
|
||||
where.append('transition = 1')
|
||||
|
||||
if where:
|
||||
query += ' WHERE ' + ' AND '.join(where)
|
||||
|
||||
query += ' ORDER BY id DESC LIMIT ?'
|
||||
params.append(limit)
|
||||
|
||||
try:
|
||||
with get_db() as conn:
|
||||
rows = conn.execute(query, params).fetchall()
|
||||
return jsonify([dict(r) for r in rows])
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
@app.route('/history/summary')
|
||||
def history_summary():
|
||||
"""
|
||||
Return per-provider stats: total events, transitions, last seen, avg rtt.
|
||||
|
||||
Query params:
|
||||
days : window in days (default 7)
|
||||
"""
|
||||
days = int(request.args.get('days', 7))
|
||||
query = '''
|
||||
SELECT
|
||||
provider,
|
||||
COUNT(*) AS total_events,
|
||||
SUM(transition) AS total_transitions,
|
||||
SUM(CASE WHEN available=1 THEN 1 ELSE 0 END) AS up_count,
|
||||
SUM(CASE WHEN available=0 THEN 1 ELSE 0 END) AS down_count,
|
||||
ROUND(AVG(rtt), 2) AS avg_rtt,
|
||||
MAX(ts) AS last_seen
|
||||
FROM events
|
||||
WHERE ts >= datetime('now', '-{} days')
|
||||
GROUP BY provider
|
||||
ORDER BY provider
|
||||
'''.format(days)
|
||||
|
||||
try:
|
||||
with get_db() as conn:
|
||||
rows = conn.execute(query).fetchall()
|
||||
return jsonify([dict(r) for r in rows])
|
||||
except Exception as e:
|
||||
return jsonify({'error': str(e)}), 500
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# Entry point
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
if __name__ == '__main__':
|
||||
app.run(host='0.0.0.0', port=5050, debug=False)
|
||||
|
||||
Reference in New Issue
Block a user