Skip to content

Commit

Permalink
added statistics (#8)
Browse files Browse the repository at this point in the history
added prometheus_async dependency
  • Loading branch information
markusressel authored Oct 20, 2020
1 parent 0361f03 commit 5fabee0
Show file tree
Hide file tree
Showing 8 changed files with 58 additions and 7 deletions.
1 change: 1 addition & 0 deletions Pipfile
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ orjson = ">=3,<4"
aiohttp = "*"
asyncio-mqtt = "*"
prometheus-client = "*"
prometheus_async = "*"

[dev-packages]
pytest = "*"
Expand Down
16 changes: 15 additions & 1 deletion Pipfile.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion barcode_server/barcode.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

from barcode_server.config import AppConfig
from barcode_server.keyevent_reader import KeyEventReader
from barcode_server.stats import SCAN_COUNT, DEVICES_COUNT
from barcode_server.stats import SCAN_COUNT, DEVICES_COUNT, DEVICE_DETECTION_TIME

LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -99,6 +99,7 @@ def _detect_devices(self):
DEVICES_COUNT.set(len(self.devices))

@staticmethod
@DEVICE_DETECTION_TIME.time()
def _find_devices(patterns: List, paths: List[str]) -> Dict[str, InputDevice]:
"""
# Finds the input device with the name ".*Barcode Reader.*".
Expand Down
2 changes: 2 additions & 0 deletions barcode_server/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@
CONFIG_NODE_PORT = "port"

DEFAULT_SERVER_HOST = "localhost"

ENDPOINT_DEVICES = "devices"
3 changes: 3 additions & 0 deletions barcode_server/notifier/http.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@

import aiohttp
from evdev import InputDevice
from prometheus_async.aio import time

from barcode_server.notifier import BarcodeNotifier
from barcode_server.stats import HTTP_NOTIFIER_TIME
from barcode_server.util import barcode_event_to_json

LOGGER = logging.getLogger(__name__)
Expand All @@ -18,6 +20,7 @@ def __init__(self, method: str, url: str, headers: List[str]):
headers = list(map(lambda x: tuple(x.split(':', 1)), headers))
self.headers = list(map(lambda x: (x[0].strip(), x[1].strip()), headers))

@time(HTTP_NOTIFIER_TIME)
async def notify(self, device: InputDevice, barcode: str):
json = barcode_event_to_json(device, barcode)
try:
Expand Down
3 changes: 3 additions & 0 deletions barcode_server/notifier/mqtt.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

from asyncio_mqtt import Client
from evdev import InputDevice
from prometheus_async.aio import time

from barcode_server.notifier import BarcodeNotifier
from barcode_server.stats import MQTT_NOTIFIER_TIME
from barcode_server.util import barcode_event_to_json

LOGGER = logging.getLogger(__name__)
Expand All @@ -25,6 +27,7 @@ def __init__(self, host: str, port: int = 1883,
self.qos = qos
self.retain = retain

@time(MQTT_NOTIFIER_TIME)
async def notify(self, device: InputDevice, barcode: str):
json = barcode_event_to_json(device, barcode)
try:
Expand Down
21 changes: 19 additions & 2 deletions barcode_server/stats.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,28 @@
from prometheus_client import Gauge
from prometheus_client import Gauge, Summary

from barcode_server.const import *

WEBSOCKET_CLIENT_COUNT = Gauge(
'websocket_client_count',
'Number of currently connected websocket clients'
)

DEVICES_COUNT = Gauge(
'devices_count',
'Number of devices currently detected'
'Number of currently detected devices'
)

SCAN_COUNT = Gauge(
'scan_count',
'Number of times a scan has been detected'
)

DEVICE_DETECTION_TIME = Summary('device_detection_processing_seconds', 'Time spent detecting devices')

REST_TIME = Summary('rest_endpoint_processing_seconds', 'Time spent in a rest command handler', ['endpoint'])
REST_TIME_DEVICES = REST_TIME.labels(endpoint=ENDPOINT_DEVICES)

NOTIFIER_TIME = Summary('notifier_processing_seconds', 'Time spent in a notifier', ['type'])
WEBSOCKET_NOTIFIER_TIME = NOTIFIER_TIME.labels(type='websocket')
HTTP_NOTIFIER_TIME = NOTIFIER_TIME.labels(type='http')
MQTT_NOTIFIER_TIME = NOTIFIER_TIME.labels(type='mqtt')
16 changes: 13 additions & 3 deletions barcode_server/webserver.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@
from aiohttp import web
from aiohttp.web_middlewares import middleware
from evdev import InputDevice
from prometheus_async.aio import time

from barcode_server.barcode import BarcodeReader
from barcode_server.config import AppConfig
from barcode_server.const import X_Auth_Token
from barcode_server.const import *
from barcode_server.notifier.http import HttpNotifier
from barcode_server.notifier.mqtt import MQTTNotifier
from barcode_server.stats import REST_TIME_DEVICES, WEBSOCKET_CLIENT_COUNT, WEBSOCKET_NOTIFIER_TIME
from barcode_server.util import barcode_event_to_json, input_device_to_dict

LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -79,7 +81,8 @@ async def authentication_middleware(self, request, handler):

return await handler(self, request)

@routes.get("/devices")
@routes.get(f"/{ENDPOINT_DEVICES}")
@time(REST_TIME_DEVICES)
async def devices_handle(self, request):
import orjson
device_list = list(map(input_device_to_dict, self.barcode_reader.devices.values()))
Expand All @@ -92,7 +95,9 @@ async def websocket_handler(self, request):
await websocket.prepare(request)

self.clients.add(websocket)
LOGGER.debug(f"New client connected: {request.host} Client count: {len(self.clients)}")
client_count = len(self.clients)
WEBSOCKET_CLIENT_COUNT.set(client_count)
LOGGER.debug(f"New client connected: {request.host} Client count: {client_count}")
try:
async for msg in websocket:
if msg.type == aiohttp.WSMsgType.TEXT:
Expand All @@ -107,13 +112,18 @@ async def websocket_handler(self, request):
LOGGER.exception(e)
finally:
self.clients.discard(websocket)
client_count = len(self.clients)
WEBSOCKET_CLIENT_COUNT.set(client_count)
LOGGER.debug(f"Client disconnected: {request.host}")
return websocket

async def on_barcode(self, device: InputDevice, barcode: str):
for notifier in self.notifiers:
asyncio.create_task(notifier.notify(device, barcode))
await self._notify_websocket_clients(device, barcode)

@time(WEBSOCKET_NOTIFIER_TIME)
async def _notify_websocket_clients(self, device, barcode):
for client in self.clients:
json = barcode_event_to_json(device, barcode)
asyncio.create_task(client.send_str(json))
Expand Down

0 comments on commit 5fabee0

Please sign in to comment.