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 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165
|
from fastapi import FastAPI
from prometheus_client import CollectorRegistry, Counter
from starlette.testclient import TestClient
from prometheus_fastapi_instrumentator import Instrumentator, metrics
def test_multiple_apps_custom_registry():
"""
Tests instrumentation of multiple apps in combination with middlewares
where each app gets it's own registry. In addition it tests that custom
metrics are not shared between app's metrics endpoints.
"""
app1 = FastAPI()
app2 = FastAPI()
@app1.get("/dummy")
def read_dummy_app1():
return "Hello from app1"
@app2.get("/dummy")
def read_dummy_app2():
return "Hello from app2"
registry1 = CollectorRegistry(auto_describe=True)
registry2 = CollectorRegistry(auto_describe=True)
Instrumentator(registry=registry1).instrument(app1).expose(app1)
Instrumentator(registry=registry2).instrument(app2).expose(app2)
Counter("test_app1_only", "In app1 metrics only.", registry=registry1).inc()
# Add middleware after adding the instrumentator, this triggers another
# app.build_middleware_stack(), which creates the middleware again, but it
# will use the same Prometheus registry again, which could try to create the
# same metrics again causing duplication errors.
@app1.middleware("http")
@app2.middleware("http")
async def dummy_middleware(request, call_next):
response = await call_next(request)
return response
client1 = TestClient(app1)
client2 = TestClient(app2)
client1.get("/dummy")
client2.get("/dummy")
metrics1 = client1.get("/metrics").content.decode()
metrics2 = client2.get("/metrics").content.decode()
print("app1 GET /metrics\n" + metrics1)
print("app2 GET /metrics\n" + metrics2)
want = 'http_requests_total{handler="/dummy",method="GET",status="2xx"} 1.0\n'
assert want in metrics1
assert want in metrics2
want = "test_app1_only_total 1.0\n"
assert want in metrics1
assert want not in metrics2
def test_multiple_apps_expose_defaults():
"""Tests instrumentation of multiple apps in combination with middlewares."""
app1 = FastAPI()
app2 = FastAPI()
@app1.get("/dummy")
def read_dummy_app1():
return "Hello from app1"
@app2.get("/dummy")
def read_dummy_app2():
return "Hello from app2"
Instrumentator().instrument(app1).expose(app1)
Instrumentator().instrument(app2).expose(app2)
# Add middleware after adding the instrumentator, this triggers another
# app.build_middleware_stack(), which creates the middleware again, but it
# will use the same Prometheus registry again, which could try to create the
# same metrics again causing duplication errors.
@app1.middleware("http")
@app2.middleware("http")
async def dummy_middleware(request, call_next):
response = await call_next(request)
return response
client1 = TestClient(app1)
client2 = TestClient(app2)
client1.get("/dummy")
client2.get("/dummy")
metrics1 = client1.get("/metrics").content.decode()
metrics2 = client2.get("/metrics").content.decode()
print("app1 GET /metrics\n" + metrics1)
print("app2 GET /metrics\n" + metrics2)
want = 'http_requests_total{handler="/dummy",method="GET",status="2xx"} 1.0\n'
assert want in metrics1
assert want in metrics2
def test_multiple_apps_expose_full():
"""Tests instrumentation of multiple apps in combination with middlewares."""
app1 = FastAPI()
app2 = FastAPI()
@app1.get("/dummy")
def read_dummy_app1():
return "Hello from app1"
@app2.get("/dummy")
def read_dummy_app2():
return "Hello from app2"
Instrumentator().add(
metrics.request_size(),
metrics.requests(),
metrics.combined_size(),
metrics.response_size(),
metrics.latency(),
metrics.default(),
).instrument(app1).expose(app1)
Instrumentator().add(
metrics.request_size(),
metrics.requests(),
metrics.combined_size(),
metrics.response_size(),
metrics.latency(),
metrics.default(),
).instrument(app2).expose(app2)
# Add middleware after adding the instrumentator, this triggers another
# app.build_middleware_stack(), which creates the middleware again, but it
# will use the same Prometheus registry again, which could try to create the
# same metrics again causing duplication errors.
@app1.middleware("http")
@app2.middleware("http")
async def dummy_middleware(request, call_next):
response = await call_next(request)
return response
client1 = TestClient(app1)
client2 = TestClient(app2)
client1.get("/dummy")
client2.get("/dummy")
metrics1 = client1.get("/metrics").content.decode()
metrics2 = client2.get("/metrics").content.decode()
print("app1 GET /metrics\n" + metrics1)
print("app2 GET /metrics\n" + metrics2)
want = 'http_requests_total{handler="/dummy",method="GET",status="2xx"} 1.0\n'
assert want in metrics1
assert want in metrics2
|