Initial commit
This commit is contained in:
		
							
								
								
									
										6
									
								
								.flake8
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								.flake8
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,6 @@ | ||||
| [flake8] | ||||
| inline-quotes = " | ||||
| multiline-quotes = """ | ||||
| indent-size = 4 | ||||
| max-line-length = 160 | ||||
| ignore = Q003 E128 E704 | ||||
							
								
								
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| .env | ||||
							
								
								
									
										9
									
								
								.gitlint
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								.gitlint
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | ||||
| [general] | ||||
| ignore=body-is-missing,T3 | ||||
| ignore-stdin=true | ||||
|  | ||||
| [title-match-regex] | ||||
| regex=[A-Z] | ||||
|  | ||||
| [author-valid-email] | ||||
| regex=[^@]+@k-space.ee | ||||
							
								
								
									
										16
									
								
								.pre-commit-config.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								.pre-commit-config.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,16 @@ | ||||
| repos: | ||||
| -   repo: https://github.com/PyCQA/flake8 | ||||
|     rev: 3.9.2 | ||||
|     hooks: | ||||
|     -   id: flake8 | ||||
|         additional_dependencies: [flake8-typing-imports==1.10.0,flake8-quotes==3.2.0] | ||||
|  | ||||
| -   repo: https://github.com/jorisroovers/gitlint | ||||
|     rev: v0.15.1 | ||||
|     hooks: | ||||
|     -   id: gitlint | ||||
|  | ||||
| -   repo: https://github.com/Lucas-C/pre-commit-hooks-nodejs | ||||
|     rev: v1.1.1 | ||||
|     hooks: | ||||
|     -   id: dockerfile_lint | ||||
							
								
								
									
										4
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								Dockerfile
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| FROM python:3 | ||||
| RUN pip3 install motor sanic | ||||
| ADD wildduck_exporter.py /wildduck_exporter.py | ||||
| ENTRYPOINT /wildduck_exporter.py | ||||
							
								
								
									
										8
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										8
									
								
								docker-compose.yml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,8 @@ | ||||
| version: '3.7' | ||||
| services: | ||||
|   app: | ||||
|     image: kspaceee/wildduck-exporter:latest | ||||
|     network_mode: host | ||||
|     env_file: .env | ||||
|     build: | ||||
|       context: . | ||||
							
								
								
									
										60
									
								
								wildduck_exporter.py
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										60
									
								
								wildduck_exporter.py
									
									
									
									
									
										Executable file
									
								
							| @@ -0,0 +1,60 @@ | ||||
| #!/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) | ||||
		Reference in New Issue
	
	Block a user