File: test_instrumentator_multiple_apps.py

package info (click to toggle)
prometheus-fastapi-instrumentator 7.1.0-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 492 kB
  • sloc: python: 2,586; makefile: 5
file content (165 lines) | stat: -rw-r--r-- 5,157 bytes parent folder | download
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