8 changed files with 19 additions and 131 deletions
@ -1 +1 @@ |
|||
pushgateway/.htpasswd |
|||
.htpasswd |
@ -1,5 +0,0 @@ |
|||
FROM python:3.10 |
|||
RUN pip install fastapi uvicorn |
|||
WORKDIR /app |
|||
COPY server.py /app/ |
|||
ENTRYPOINT ["python3", "server.py"] |
@ -1 +0,0 @@ |
|||
curl http://192.168.3.1:9100/metrics | curl -H "Host: srv" -H "Secret: secret" -X POST -d "$(</dev/stdin)" http://192.168.3.10:9100/metrics >> /dev/null |
@ -1,25 +0,0 @@ |
|||
#curl -s http://localhost:9100/metrics | curl --data-binary @- http://pushgateway.example.org:9091/metrics/job/some_job/instance/some_instance |
|||
services: |
|||
pushgateway: |
|||
image: docker.pblr-nyk.pro/prom/pushgateway:latest |
|||
container_name: p_gw |
|||
restart: unless-stopped |
|||
deploy: |
|||
resources: |
|||
limits: |
|||
cpus: "0.1" |
|||
memory: 128M |
|||
pushgateway_nginx: |
|||
image: docker.pblr-nyk.pro/nginx:1.27.4-alpine |
|||
container_name: p_gw_nginx |
|||
restart: unless-stopped |
|||
volumes: |
|||
- $PWD/srv.conf:/etc/nginx/conf.d/srv.conf:ro |
|||
- $PWD/.htpasswd:/etc/nginx/.htpasswd:ro |
|||
ports: |
|||
- 9091:9091 |
|||
deploy: |
|||
resources: |
|||
limits: |
|||
cpus: "0.1" |
|||
memory: 128M |
@ -1,90 +0,0 @@ |
|||
from fastapi import FastAPI |
|||
from fastapi import Request |
|||
from fastapi.responses import Response |
|||
from fastapi import BackgroundTasks |
|||
import uvicorn |
|||
import os |
|||
from time import time |
|||
import asyncio |
|||
import datetime |
|||
|
|||
class Collector: |
|||
app = FastAPI() |
|||
secrets = [] |
|||
hosts = [] |
|||
store = {} |
|||
def __init__(self) -> None: |
|||
self.secrets = os.getenv("KEYS", "secret").split(",") |
|||
self.hosts = os.getenv("HOSTS", "srv").split(",") |
|||
self.dead_after = int(os.getenv("DEAD_AFTER", "90")) |
|||
self.build_routes() |
|||
|
|||
def check_headers(self, request: Request): |
|||
if not request.headers.get("Secret", ""): |
|||
print("secret empty") |
|||
return Response(status_code=400) |
|||
if not request.headers.get("Host", "") and not request.headers.get("Host-replace", ""): |
|||
print("host empty") |
|||
return Response(status_code=400) |
|||
|
|||
if not request.headers.get("Secret", "") in self.secrets: |
|||
return Response(status_code=400) |
|||
|
|||
host = request.headers.get("Host-replace", "") or request.headers.get("Host", "") |
|||
host = host.split(":")[0] |
|||
if not host in self.hosts: |
|||
return Response(status_code=400) |
|||
|
|||
return None |
|||
|
|||
async def deadline(self, host): |
|||
await asyncio.sleep(self.dead_after) |
|||
if host in self.store: |
|||
if time()+1 - self.store[host]['timestamp'] > self.dead_after: |
|||
print(f"{host} is dead") |
|||
del self.store[host] |
|||
|
|||
|
|||
def build_routes(self): |
|||
@self.app.get("/metrics") |
|||
async def get(request: Request): |
|||
response: Response = self.check_headers(request) |
|||
if response: |
|||
return response |
|||
|
|||
host = request.headers.get("Host-replace", "") or request.headers.get("Host", "") |
|||
host = host.split(":")[0] |
|||
|
|||
if host in self.store and self.store[host]['data']: |
|||
return Response( |
|||
content=self.store[host]['data'], |
|||
status_code=200, |
|||
headers=self.store[host]['headers']) |
|||
else: |
|||
print(f"cannot find {host}") |
|||
return Response(status_code=404) |
|||
|
|||
@self.app.post("/metrics") |
|||
async def post(request: Request, background_tasks: BackgroundTasks): |
|||
response: Response = self.check_headers(request) |
|||
if response: |
|||
return response |
|||
|
|||
host = request.headers.get("Host-replace", "") or request.headers.get("Host", "") |
|||
host = host.split(":")[0] |
|||
|
|||
self.store[host] = { |
|||
"data":await request.body(), |
|||
"timestamp": time(), |
|||
"headers": { |
|||
"Content-Type": "text/plain; version=0.0.4; charset=utf-8; escaping=underscores", |
|||
"Date": datetime.datetime.utcnow().strftime("%a, %d %b %Y %H:%M:%S GMT") |
|||
} |
|||
} |
|||
|
|||
background_tasks.add_task(self.deadline, host) |
|||
return Response(status_code=200) |
|||
|
|||
if __name__ == "__main__": |
|||
collector = Collector() |
|||
uvicorn.run(collector.app, host = os.getenv("NEC_HOST", "0.0.0.0"), port = int(os.getenv("NEC_PORT", "9100"))) |
Loading…
Reference in new issue