-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathsseClient.py
106 lines (85 loc) · 2.66 KB
/
sseClient.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
102
103
104
105
106
""" Acts as a client to the AuthLogWatcher and a webserver to display the
latest event data (over SSE).
"""
# GEvent first...
import gevent
import gevent.monkey
from gevent.pywsgi import WSGIServer
gevent.monkey.patch_all()
# All others...
from flask import Flask, request, Response, render_template, send_from_directory
import sys
import json
import Queue
import string
import random
import logging
# App modules
import rpcClient
app = Flask(__name__)
# Logging...
handler = logging.StreamHandler(sys.stdout)
handler.setFormatter(logging.Formatter('%(asctime)s [%(name)s] %(levelname)s : %(message)s'))
handler.setLevel(logging.DEBUG)
rootLogger = logging.getLogger()
rootLogger.addHandler(handler)
rootLogger.setLevel(logging.DEBUG)
clientLogger = logging.getLogger("AuthLogClient")
streamLogger = logging.getLogger("StreamClient")
app.logger.addHandler(handler)
client = None
def generateId(size=6, chars=string.ascii_uppercase + string.digits):
return ''.join(random.choice(chars) for _ in range(size))
def eventStream():
clientId = generateId()
streamLogger.info("Streaming to client: %s" % repr(clientId))
queue = Queue.Queue()
event = { "eventCount": client.eventCount }
responseStr = "event: init\ndata: "+json.dumps(event)+"\n\n"
yield responseStr
try:
for event in client.getEvents(queue):
if event:
responseStr = "event: auth\ndata: "+json.dumps(event)+"\n\n"
yield responseStr
except GeneratorExit:
raise
except:
import traceback
traceback.print_exc()
finally:
streamLogger.info("Removing client stream: %s" % repr(clientId))
client.removeQueue(queue)
@app.route('/js/<path:path>')
def send_js(path):
return send_from_directory('js', path)
@app.route('/css/<path:path>')
def send_css(path):
return send_from_directory('css', path)
@app.route('/svg/<path:path>')
def send_svg(path):
return send_from_directory('svg', path)
@app.route('/auth')
def sse_request():
return Response(
eventStream(),
mimetype='text/event-stream')
@app.route('/')
def page():
return render_template('sse.html')
if __name__ == '__main__':
# subscribe to the auth.log events
model = rpcClient.AuthLogModel()
client = rpcClient.AuthLogClient(model)
client.subscribe()
# Host a flask server
host, port = ('0.0.0.0', 80)
rootLogger.info("Serving HTTP at %s:%d" % (host, port))
http_server = WSGIServer((host, port), app)
try:
http_server.serve_forever()
except:
rootLogger.critical("Fatal Error!", exc_info=True)
finally:
client.unsubscribe()
rootLogger.info("Exiting.")