This repository has been archived by the owner on Aug 31, 2020. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 15
/
Copy pathGrafanaDatastoreServer.py
executable file
·101 lines (82 loc) · 3.05 KB
/
GrafanaDatastoreServer.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
#!/usr/bin/env python
import argparse
import redis
import flask
from datetime import timedelta, datetime
import dateutil.parser
from gevent.pywsgi import WSGIServer
from flask import Flask, jsonify
from flask_cors import CORS, cross_origin
app = Flask(__name__)
CORS(app)
REDIS_POOL = None
SCAN_TYPE_SCRIPT = """local cursor, pat, typ, cnt = ARGV[1], ARGV[2], ARGV[3], ARGV[4] or 100
local rep = {}
local res = redis.call('SCAN', cursor, 'MATCH', pat, 'COUNT', cnt)
while #res[2] > 0 do
local k = table.remove(res[2])
local t = redis.call('TYPE', k)
if t['ok'] == typ then
table.insert(rep, k)
end
end
rep = {tonumber(res[1]), rep}
return rep"""
@app.route('/')
@cross_origin()
def hello_world():
return 'OK'
@app.route('/search', methods=["POST", 'GET'])
@cross_origin()
def search():
redis_client = redis.Redis(connection_pool=REDIS_POOL)
result = []
cursor = 0
while True:
cursor, keys = redis_client.eval(SCAN_TYPE_SCRIPT, 0, cursor, "*", "TSDB-TYPE", 100)
result.extend([k.decode("ascii") for k in keys])
if cursor == 0:
break
return jsonify(result)
def process_targets(targets, redis_client):
result = []
for target in targets:
if '*' in target:
result.extend([k.decode('ascii') for k in redis_client.keys(target)])
else:
result.append(target)
return result
@app.route('/query', methods=["POST", 'GET'])
def query():
request = flask.request.get_json()
response = []
# dates 'from' and 'to' are expected to be in UTC, which is what Grafana provides here.
stime = dateutil.parser.parse(request['range']['from']).timestamp() * 1000
etime = dateutil.parser.parse(request['range']['to']).timestamp() * 1000
redis_client = redis.Redis(connection_pool=REDIS_POOL)
targets = process_targets([t['target'] for t in request['targets']], redis_client)
for target in targets:
args = ['ts.range', target, int(stime), int(etime)]
if 'intervalMs' in request and request['intervalMs'] > 0:
args += ['avg', int(request['intervalMs'])]
print(args)
redis_resp = redis_client.execute_command(*args)
datapoints = [(float(x2.decode("ascii")), x1) for x1, x2 in redis_resp]
response.append(dict(target=target, datapoints=datapoints))
return jsonify(response)
@app.route('/annotations')
def annotations():
return jsonify([])
def main():
global REDIS_POOL
parser = argparse.ArgumentParser()
parser.add_argument("--host", help="server address to listen to", default="0.0.0.0")
parser.add_argument("--port", help="port number to listen to", default=8080, type=int)
parser.add_argument("--redis-server", help="redis server address", default="localhost")
parser.add_argument("--redis-port", help="redis server port", default=6379, type=int)
args = parser.parse_args()
REDIS_POOL = redis.ConnectionPool(host=args.redis_server, port=args.redis_port)
http_server = WSGIServer(('', args.port), app)
http_server.serve_forever()
if __name__ == '__main__':
main()