ΠΡΠΊΠΎΠ»ΠΊΠΎ ΡΠ΅Π΄Π° ΠΊΠΎΠ΄ ΠΈ Π²Π°ΡΠ΅ΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π³Π΅Π½Π΅ΡΠΈΡΠ° ΠΌΠ΅ΡΡΠΈΠΊΠΈ, ΡΠ°Ρ!
ΠΠ° Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΡΠ΅ ΠΊΠ°ΠΊ ΡΠ°Π±ΠΎΡΠΈ prometheus_flask_exporter Π΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ΅Π½ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π΅Π½ ΠΏΡΠΈΠΌΠ΅Ρ:
from flask import Flask
from prometheus_flask_exporter import PrometheusMetrics
app = Flask(__name__)
metrics = PrometheusMetrics(app)
@app.route('/')
def main():
return 'OK'Π’ΠΎΠ²Π° Π΅ Π²ΡΠΈΡΠΊΠΎ, ΠΊΠΎΠ΅ΡΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΎ, Π·Π° Π΄Π° Π·Π°ΠΏΠΎΡΠ½Π΅ΡΠ΅! ΠΠΎΠ±Π°Π²ΡΠΉΠΊΠΈ ΠΈΠΌΠΏΠΎΡΡ ΠΈ ΡΠ΅Π΄ Π·Π° ΠΈΠ½ΠΈΡΠΈΠ°Π»ΠΈΠ·Π°ΡΠΈΡ PrometheusMetrics, ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΠΌΠ΅ΡΡΠΈΠΊΠΈ Π·Π° Π²ΡΠ΅ΠΌΠ΅ΡΠΎ Π½Π° Π·Π°ΡΠ²ΠΊΠΈΡΠ΅ ΠΈ Π±ΡΠΎΡΡΠΈΡΠ΅ Π½Π° Π·Π°ΡΠ²ΠΊΠΈΡΠ΅, ΠΏΠΎΠΊΠ°Π·Π²Π°Π½ΠΈ Π½Π° ΠΊΡΠ°ΠΉΠ½Π° ΡΠΎΡΠΊΠ° /metrics Π½Π° Flask ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ, Π² ΠΊΠΎΠ΅ΡΠΎ Π΅ ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠ°Π½ΠΎ, ΠΊΠ°ΠΊΡΠΎ ΠΈ Π²ΡΠΈΡΠΊΠΈΡΠ΅ ΠΌΠ΅ΡΡΠΈΠΊΠΈ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅, ΠΊΠΎΠΈΡΠΎ ΠΏΠΎΠ»ΡΡΠ°Π²Π°ΡΠ΅ ΠΎΡ ΠΎΡΠ½ΠΎΠ²Π½Π°ΡΠ° .
ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈΡΠ΅ Π² GitHub ΡΠ΅ΠΏΠΎΠ·ΠΈΡΠΎΡΠΈΡ, ΠΊΠΎΠΉΡΠΎ ΡΡΠ°ΡΡΠΈΡΠ° ΠΈΠ½ΡΡΠ°Π½ΡΠΈΡ ΠΈ Π²ΠΌΠ΅ΡΡΠΎ Ρ Π΄Π΅ΠΌΠΎΠ½ΡΡΡΠ°ΡΠΈΠΎΠ½Π½ΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Π·Π° Π³Π΅Π½Π΅ΡΠΈΡΠ°Π½Π΅ Π½Π° ΠΌΠ΅ΡΡΠΈΠΊΠΈ, ΠΊΠΎΠΈΡΠΎ ΡΠ΅ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Ρ ΠΏΡΠΈΠ±Π»ΠΈΠ·ΠΈΡΠ΅Π»Π½ΠΎ ΡΠ°ΠΊΠ°:

Π‘ΡΡΠΎ ΡΠ°ΠΊΠ° ΡΠ΅ Π½Π°ΠΌΠ΅ΡΠΈΡΠ΅ ΡΠΏΠΈΡΡΠΊ Ρ ΠΌΠ΅ΡΡΠΈΠΊΠΈ Π² ΠΏΡΠΈΠΌΠ΅ΡΠ°, ΠΊΠΎΠΈΡΠΎ ΡΠ΅ ΠΏΠΎΠΊΠ°Π·Π²Π°Ρ Π½Π° ΠΊΠΎΠ½ΡΡΠΎΠ»Π½ΠΈΡ ΠΏΠ°Π½Π΅Π», Π·Π°Π΅Π΄Π½ΠΎ Ρ Prometheus Π·Π°ΡΠ²ΠΊΠΈ, ΠΊΠΎΠΈΡΠΎ Π·Π°ΠΏΡΠ»Π²Π°Ρ ΡΠ°Π±Π»Π°ΡΠ°.
ΠΠ°ΡΡΡΠΎΠΉΠΊΠ°
Π Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° ΠΈΠΌΠ° ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ ΠΎΠΏΡΠΈΠΈ Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ, ΡΠ°Π·Π³Π»Π΅Π΄Π°ΠΉΡΠ΅ ΠΏΡΠΎΠ΅ΠΊΡΠΈΡΠ΅ ΠΈΠΌ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Ρ ΠΊΡΠ°ΡΠΊΠΎ ΠΎΠ±ΡΡΠ½Π΅Π½ΠΈΠ΅.
ΠΡΠ½ΠΎΠ²Π½Π°ΡΠ° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ Π΅ ΠΏΠΎΠΊΠ°Π·Π°Π½Π° Π²Π³ΠΎΡΠ΅. ΠΡΠΎΡΡΠΎ ΡΡΠ·Π΄Π°ΠΉΡΠ΅ ΠΈΠ½ΡΡΠ°Π½ΡΠΈΡ PrometheusMetrics, Π΄Π° Ρ Π½Π°ΡΠ΅ΡΠ΅ΠΌ metrics, Π° ΡΠ»Π΅Π΄ ΡΠΎΠ²Π° Ρ Π½Π΅ΠΉΠ½Π° ΠΏΠΎΠΌΠΎΡ ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅ΡΠ΅ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΠΌΠ΅ΡΡΠΈΠΊΠΈ, ΠΊΠΎΠΈΡΠΎ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° ΡΡΠ±ΠΈΡΠ°ΡΠ΅, Π΄Π΅ΠΊΠΎΡΠΈΡΠ°ΠΉΠΊΠΈ ΡΡΠ½ΠΊΡΠΈΠΈ:
@metrics.counter(..)@metrics.gauge(..)@metrics.summary(..)@metrics.histogram(..)
ΠΡΠΎΡΡΠΈΡΠ΅ ΡΡΠΈΡΠ°Ρ ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½ΠΈΡΡΠ°, Π° ΠΎΡΡΠ°Π½Π°Π»ΠΈΡΠ΅ ΡΡΠ±ΠΈΡΠ°Ρ ΠΌΠ΅ΡΡΠΈΠΊΠΈ Π² Π·Π°Π²ΠΈΡΠΈΠΌΠΎΡΡ ΠΎΡ ΠΏΡΠΎΠ΄ΡΠ»ΠΆΠΈΡΠ΅Π»Π½ΠΎΡΡΡΠ° Π½Π° ΡΠ΅Π·ΠΈ ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½ΠΈΡ. ΠΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»ΠΈΡΠ΅ Π΅ΡΠΈΠΊΠ΅ΡΠΈ Π·Π° Π²ΡΡΠΊΠ° ΠΎΡ ΡΡΡ , ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»Π½ΠΎ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΉΠΊΠΈ ΡΠ²ΠΎΠΉΡΡΠ²Π° Π½Π° Π·Π°ΡΠ²ΠΊΠ°ΡΠ° ΠΈΠ»ΠΈ ΠΎΡΠ³ΠΎΠ²ΠΎΡΠ°. ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ:
from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics
app = Flask(__name__)
# ΠΡΡΠΏΠΈΡΠ°Π½Π΅ ΠΏΠΎ ΠΊΡΠ°ΠΉΠ½Π° ΡΠΎΡΠΊΠ°, Π° Π½Π΅ ΠΏΠΎ ΠΏΡΡ
metrics = PrometheusMetrics(app, group_by='endpoint')
@app.route('/collection/:collection_id/item/:item_id')
@metrics.counter(
'cnt_collection', 'ΠΡΠΎΠΉ ΠΏΠΎΠ²ΠΈΠΊΠ²Π°Π½ΠΈΡ Π½Π° ΠΊΠΎΠ»Π΅ΠΊΡΠΈΡ', labels={
'collection': lambda: request.view_args['collection_id'],
'status': lambda resp: resp.status_code
})
def get_item_from_collection(collection_id, item_id):
passΠ Π³ΠΎΡΠ½ΠΈΡ ΠΏΡΠΈΠΌΠ΅Ρ Π½Π°ΡΠΈΡΠΊΠ°Π½Π΅ΡΠΎ Π½Π° ΠΊΡΠ°ΠΉΠ½Π° ΡΠΎΡΠΊΠ° /collection/10002/item/76 ΡΠ΅ ΡΠ²Π΅Π»ΠΈΡΠΈ Π±ΡΠΎΡΡΠ°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ cnt_collection{collection = Β«10002Β», status = Β«200Β»}, ΠΏΠ»ΡΡ ΡΠ΅ ΠΏΠΎΠ»ΡΡΠΈΡΠ΅ ΠΌΠ΅ΡΡΠΈΠΊΠΈ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ (Π·Π° Π²ΡΡΠΊΠ° ΠΊΡΠ°ΠΉΠ½Π° ΡΠΎΡΠΊΠ° Π² ΡΠΎΠ·ΠΈ ΠΏΡΠΈΠΌΠ΅Ρ) ΠΎΡ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅:
flask_http_request_duration_secondsΒ β ΠΡΠΎΠ΄ΡΠ»ΠΆΠΈΡΠ΅Π»Π½ΠΎΡΡΡΠ° Π½Π° HTTP Π·Π°ΡΠ²ΠΊΠ°ΡΠ° Π² ΡΠ΅ΠΊΡΠ½Π΄ΠΈ Π·Π° Π²ΡΠΈΡΠΊΠΈ Flask Π·Π°ΡΠ²ΠΊΠΈ ΠΏΠΎ ΠΌΠ΅ΡΠΎΠ΄, ΠΏΡΡ ΠΈ ΡΡΠ°ΡΡΡflask_http_request_totalΒ β ΠΠ±ΡΠΎ Π±ΡΠΎΡ Π½Π° HTTP Π·Π°ΡΠ²ΠΊΠΈΡΠ΅ ΠΏΠΎ ΠΌΠ΅ΡΠΎΠ΄ΠΈ ΠΈ ΡΡΠ°ΡΡΡΡΠΈ
ΠΠΌΠ° ΠΎΠΏΡΠΈΠΈ Π΄Π° ΠΏΡΠΎΠΏΡΡΠ½Π΅ΡΠ΅ ΠΏΡΠΎΡΠ»Π΅Π΄ΡΠ²Π°Π½Π΅ΡΠΎ Π½Π° ΠΎΠΏΡΠ΅Π΄Π΅Π»Π΅Π½ΠΈ ΠΊΡΠ°ΠΉΠ½ΠΈ ΡΠΎΡΠΊΠΈ, Π΄Π° ΡΠ΅Π³ΠΈΡΡΡΠΈΡΠ°ΡΠ΅ Π΄ΠΎΠΏΡΠ»Π½ΠΈΡΠ΅Π»Π½ΠΈ ΠΌΠ΅ΡΡΠΈΠΊΠΈ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ ΠΈΠ»ΠΈ Π΄Π° ΠΏΡΠΎΠΏΡΡΠ½Π΅ΡΠ΅ ΡΠ΅Π·ΠΈ, ΠΊΠΎΠΈΡΠΎ ΡΠ° ΠΏΠΎΡΠΎΡΠ΅Π½ΠΈ ΠΏΠΎ-Π³ΠΎΡΠ΅, ΠΈΠ»ΠΈ Π΄Π° ΠΏΡΠΈΠ»ΠΎΠΆΠΈΡΠ΅ Π΅Π΄Π½Π° ΠΈ ΡΡΡΠ° ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½Π° ΠΌΠ΅ΡΡΠΈΠΊΠ° ΠΊΡΠΌ Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΠΊΡΠ°ΠΉΠ½ΠΈ ΡΠΎΡΠΊΠΈ. ΠΠ°ΠΏΠΎΠ·Π½Π°ΠΉΡΠ΅ ΡΠ΅ Ρ ΠΏΡΠΎΠ΅ΠΊΡΠ°, Π·Π° Π΄Π° ΡΠ°Π·Π±Π΅ΡΠ΅ΡΠ΅ ΠΊΠ°ΠΊΠ²ΠΎ Π΅ Π½Π°Π»ΠΈΡΠ½ΠΎ.
app = Flask(__name__)
metrics = PrometheusMetrics(app)
@app.route('οΈ')
def main():
pass # requests tracked by default
@app.route('οΈ/skip')
@metrics.do_not_track()
def skip():
pass # default metrics are not collected
# custom metric to be applied to multiple endpoints
common_counter = metrics.counter(
'by_endpoint_counter', 'Request count by endpoints',
labels={'endpoint': lambda: request.endpoint}
)
@app.route('οΈ/common/one')
@common_counter
def endpoint_one():
pass # tracked by the custom and the default metrics
@app.route('οΈ/common/two')
@common_counter
def endpoint_two():
pass # also tracked by the custom and the default metrics
# register additional default metrics
metrics.register_default(
metrics.counter(
'by_path_counter', 'Request count by request paths',
labels={'path': lambda: request.path}
)
)ΠΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° ΡΠ°Π·ΠΏΠΎΠ»Π°Π³Π° Ρ ΡΠ΄ΠΎΠ±Π½ΠΈ ΡΠ°Π·ΡΠΈΡΠ΅Π½ΠΈΡ Π·Π° ΠΏΠΎΠΏΡΠ»ΡΡΠ½ΠΈ ΠΌΠ½ΠΎΠ³ΠΎΠΏΡΠΎΡΠ΅ΡΠΎΡΠ½ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠΈ, ΠΊΠ°ΡΠΎ uWSGI ΠΈ Gunicorn. ΠΠΎΠΆΠ΅ΡΠ΅ ΡΡΡΠΎ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈΡΠ΅ ΠΌΠ°Π»ΠΊΠΈ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π½Π° ΡΠ΅Π»Π΅Π²ΠΈ ΡΠ»ΡΡΠ°ΠΈ Π½Π° ΡΠΏΠΎΡΡΠ΅Π±Π°, Π²ΠΊΠ»ΡΡΠΈΡΠ΅Π»Π½ΠΎ ΠΌΠ½ΠΎΠ³ΠΎΠΏΡΠΎΡΠ΅ΡΠΎΡΠ½ΠΈ.
Π‘ΡΠ±ΠΈΡΠ°Π½Π΅ Π½Π° ΠΌΠ΅ΡΡΠΈΠΊΠΈ
ΠΠ°ΠΊΡΠΎ Π±Π΅ΡΠ΅ ΡΠΏΠΎΠΌΠ΅Π½Π°ΡΠΎ ΠΏΠΎ-Π³ΠΎΡΠ΅, Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ°ΡΠ° ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ ΠΏΡΠ΅Π΄ΠΎΡΡΠ°Π²Ρ ΠΊΡΠ°ΠΉΠ½Π° ΡΠΎΡΠΊΠ° /metrics Π² ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Flask, ΠΊΠΎΡΡΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ»ΡΠΆΠΈ ΠΊΠ°ΡΠΎ ΡΠ΅Π» Π·Π° .
Π ΠΏΡΠΈΠΌΠ΅ΡΠ° ΠΏΠΎ-Π³ΠΎΡΠ΅ Ρ ΡΠ°Π±Π»ΠΎΡΠΎ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π½Π°ΡΠΎΡΠΈΡΠ΅ Π²Π°ΡΠΈΡ Prometheus ΠΊΡΠΌ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Flask Ρ Π½Π°ΡΡΡΠΎΠΉΠΊΠΈ ΠΏΠΎ ΠΏΠΎΠ΄ΡΠ°Π·Π±ΠΈΡΠ°Π½Π΅ Ρ ΡΠ°Π·ΠΈ ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ:
scrape_configs:
- job_name: 'example'
dns_sd_configs:
- names: ['app']
port: 5000
type: A
refresh_interval: 5sΠΠΈΠΆΡΠ΅ ΠΏΡΠ»Π΅Π½ ΠΏΡΠΈΠΌΠ΅Ρ Π² . Π’ΠΎΠ²Π° ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°, ΡΠ΅ Prometheus ΠΌΠΎΠΆΠ΅ Π΄Π° Π½Π°ΠΌΠ΅ΡΠΈ Π²Π°ΡΠΈΡΠ΅ ΠΈΠ½ΡΡΠ°Π½ΡΠΈΠΈ Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ Flask Π½Π° http://app:5000/metrics, ΠΊΡΠ΄Π΅ΡΠΎ ΠΈΠΌΠ΅ΡΠΎ Π½Π° Π΄ΠΎΠΌΠ΅ΠΉΠ½Π° Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ΡΠΎ ΠΌΠΎΠΆΠ΅ ΠΏΠΎΡΠ΅Π½ΡΠΈΠ°Π»Π½ΠΎ Π΄Π° ΡΠ΅ ΡΠ°Π·ΡΠ΅ΡΠ°Π²Π° Π½Π° Π½ΡΠΊΠΎΠ»ΠΊΠΎ IP Π°Π΄ΡΠ΅ΡΠ°, Π½Π°ΠΏΡΠΈΠΌΠ΅Ρ, ΠΊΠΎΠ³Π°ΡΠΎ ΡΠ°Π±ΠΎΡΠΈ Π² ΠΈΠ»ΠΈ .
ΠΠΊΠΎ ΡΠ°ΠΊΠΎΠ²Π° ΡΠ°Π·ΠΊΡΠΈΡΠΈΠ΅ Π½Π° ΠΊΡΠ°ΠΉΠ½Π° ΡΠΎΡΠΊΠ° Π½Π° ΠΌΠ΅ΡΡΠΈΠΊΠΈ Π½Π΅ Π²ΠΈ ΡΡΡΡΠΎΠΈΠ²Π°, Π²Π΅ΡΠΎΡΡΠ½ΠΎ Π·Π°ΡΠΎΡΠΎ Π½Π΅ ΠΈΡΠΊΠ°ΡΠ΅ Π΄Π° ΡΠ°Π·ΡΠ΅ΡΠΈΡΠ΅ Π²ΡΠ½ΡΠ΅Π½ Π΄ΠΎΡΡΡΠΏ Π΄ΠΎ Π½Π΅Ρ, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π»Π΅ΡΠ½ΠΎ Π΄Π° Ρ Π΄Π΅Π°ΠΊΡΠΈΠ²ΠΈΡΠ°ΡΠ΅, ΠΏΡΠ΅Π΄Π°Π²Π°ΠΉΠΊΠΈ path=None ΠΏΡΠΈ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ΡΠΎ Π½Π° ΠΈΠ½ΡΡΠ°Π½ΡΠΈΡΡΠ° PrometheusMetrics.
from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics
app = Flask(__name__)
metrics = PrometheusMetrics(app, path=None)
...
metrics.start_http_server(5099)Π‘Π»Π΅Π΄ ΡΠΎΠ²Π° ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ start_http_server(port), Π·Π° Π΄Π° ΠΎΡΠ²ΠΎΡΠΈΡΠ΅ ΡΠ°Π·ΠΈ ΠΊΡΠ°ΠΉΠ½Π° ΡΠΎΡΠΊΠ° Π½Π° Π΄ΡΡΠ³ HTTP ΠΏΠΎΡΡ, 5099 Π² ΠΏΡΠΈΠΌΠ΅ΡΠ° ΠΏΠΎ-Π³ΠΎΡΠ΅. ΠΠ»ΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π½ΠΎ, Π°ΠΊΠΎ ΡΡΠ΅ ΡΡΠ³Π»Π°ΡΠ½ΠΈ, ΡΠ΅ ΠΊΡΠ°ΠΉΠ½Π° ΡΠΎΡΠΊΠ° ΠΎΡΡΠ°Π²Π° Π² ΡΡΡΠΎΡΠΎ ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΠ΅ Flask, Π½ΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΠΏΡΠΎΠΌΠ΅Π½ΠΈΡΠ΅ ΠΏΡΡΡ ΠΉ ΠΎΡ /metrics, ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° ΠΏΡΠ΅Π΄Π°Π΄Π΅ΡΠ΅ Π΄ΡΡΠ³ URI ΠΊΠ°ΡΠΎ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΡ Π½Π° ΠΏΡΡΡ, ΠΈΠ»ΠΈ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΡΠ΅ register_endpoint(..), Π·Π° Π΄Π° Π³ΠΎ Π·Π°Π΄Π°Π΄Π΅ΡΠ΅ ΠΏΠΎ-ΠΊΡΡΠ½ΠΎ.
ΠΡΡΠ·ΠΊΠΈ
Β β Π’ΠΎΠ·ΠΈ Π΅ΠΊΡΠΏΠΎΡΡΠ΅Ρ Π΅ Π·Π° Prometheus
Β β ΠΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅, ΠΏΡΠΈΠΌΠ΅ΡΠΈ ΠΈ ΠΏΠ°ΡΠ°ΠΌΠ΅ΡΡΠΈ Π·Π° ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡ
Β β ΠΡΠΈΠΌΠ΅ΡΠΈ Π·Π° Π½Π°ΡΡΡΠΎΠΉΠΊΠ° Π½Π° ΠΌΠΎΠ½ΠΈΡΠΎΡΠΈΠ½Π³ Π½Π° ΠΏΡΠΈΠ»ΠΎΠΆΠ΅Π½ΠΈΡ Flask ΠΏΠΎ ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ Π½Π°ΡΠΈΠ½ΠΈ
Β β Π’ΠΎΠ·ΠΈ ΠΏΡΠΎΠ΅ΠΊΡ Π΅ Π² PyPI
Β β ΠΡΠΈΡΠΈΠ°Π»Π½Π°ΡΠ° ΠΊΠ»ΠΈΠ΅Π½ΡΡΠΊΠ° Π±ΠΈΠ±Π»ΠΈΠΎΡΠ΅ΠΊΠ° Π½Π° Prometheus Π·Π° Python
ΠΠΊΠΎ ΡΠ΅ΡΠΈΡΠ΅ Π΄Π° ΠΎΠΏΠΈΡΠ°ΡΠ΅, Π½Π΅ ΡΠ΅ ΠΊΠΎΠ»Π΅Π±Π°ΠΉΡΠ΅ Π΄Π° ΠΎΡΠ²ΠΎΡΠΈΡΠ΅ issue Π² GitHub ΠΈΠ»ΠΈ Π΄Π° ΠΎΡΡΠ°Π²ΠΈΡΠ΅ Π²Π°ΡΠΈΡΠ΅ ΠΊΠΎΠΌΠ΅Π½ΡΠ°ΡΠΈ, ΠΎΡΠ·ΠΈΠ²ΠΈ ΠΈ ΠΏΡΠ΅Π΄Π»ΠΎΠΆΠ΅Π½ΠΈΡ!
ΠΠ»Π°Π³ΠΎΠ΄Π°ΡΡ!
ΠΠ·ΡΠΎΡΠ½ΠΈΠΊ: habr.com
