wildduck-exporter/wildduck_exporter.py

61 lines
1.8 KiB
Python
Executable File

#!/usr/bin/env python3
import os
from motor.motor_asyncio import AsyncIOMotorClient
from sanic import Sanic, response, exceptions
MONGO_URI = os.getenv("MONGO_URI")
if not MONGO_URI:
raise ValueError("No MONGO_URI specified")
PROMETHEUS_BEARER_TOKEN = os.getenv("PROMETHEUS_BEARER_TOKEN")
if not PROMETHEUS_BEARER_TOKEN:
raise ValueError("No PROMETHEUS_BEARER_TOKEN specified")
app = Sanic("exporter")
@app.listener("before_server_start")
async def setup_db(app, loop):
app.ctx.db = AsyncIOMotorClient(MONGO_URI).get_default_database()
async def wrap(i, prefix="wildduck_"):
metrics_seen = set()
async for name, tp, value, labels in i:
if name not in metrics_seen:
yield "# TYPE %s %s" % (name, tp)
metrics_seen.add(name)
yield "%s%s %d" % (
prefix + name,
("{%s}" % ",".join(["%s=\"%s\"" % j for j in labels.items()]) if labels else ""),
value)
async def fetch():
async for u in app.ctx.db.users.find():
labels = {
"username": u["username"],
"email": u["address"],
}
if u["lastLogin"]["time"]:
yield "last_login", "gauge", u["lastLogin"]["time"].timestamp(), labels
if u["storageUsed"]:
yield "storage_used", "gauge", u["storageUsed"], labels
if u["targets"]:
yield "forwarding_addresses", "gauge", len(u["targets"]), labels
yield "account_enabled", "gauge", not u["disabled"], labels
@app.route("/metrics")
async def view_export(request):
if request.token != PROMETHEUS_BEARER_TOKEN:
raise exceptions.Forbidden("Invalid bearer token")
async def streaming_fn(response):
async for line in wrap(fetch()):
await response.write(line + "\n")
return response.stream(streaming_fn, content_type="text/plain")
app.run(port=3001)