рдХреЛрдб рдХреА рдХреБрдЫ рдкрдВрдХреНрддрд┐рдпрд╛рдБ рдФрд░ рдЖрдкрдХрд╛ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдЙрддреНрдкрдиреНрди рдХрд░рддрд╛ рд╣реИ, рд╡рд╛рд╣!
рдпрд╣ рд╕рдордЭрдиреЗ рдХреЗ рд▓рд┐рдП рдХрд┐ рдкреНрд░реЛрдореЗрдерд┐рдпрд╕_ рдХреИрд╕реЗ рдХрд╛рдо рдХрд░рддрд╛ рд╣реИрдХреБрдкреНрдкреА_рдирд┐рд░реНрдпрд╛рддрдХ рдХреЗ рд▓рд┐рдП рдПрдХ рдиреНрдпреВрдирддрдо рдЙрджрд╛рд╣рд░рдг рд╣реА рдкрд░реНрдпрд╛рдкреНрдд рд╣реИ:
from flask import Flask
from prometheus_flask_exporter import PrometheusMetrics
app = Flask(__name__)
metrics = PrometheusMetrics(app)
@app.route('/')
def main():
return 'OK'
рдЖрд░рдВрдн рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдЖрдкрдХреЛ рдмрд╕ рдЗрддрдирд╛ рд╣реА рдЪрд╛рд╣рд┐рдП! рдЖрд░рдВрднреАрдХрд░рдг рдХреЗ рд▓рд┐рдП рдПрдХ рдЖрдпрд╛рдд рдФрд░ рдПрдХ рдкрдВрдХреНрддрд┐ рдЬреЛрдбрд╝рдХрд░ рдкреНрд░реЛрдореЗрдерд┐рдпрд╕рдореЗрдЯреНрд░рд┐рдХреНрд╕, рдЖрдкрдХреЛ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдорд┐рд▓реЗрдВрдЧреЗ рдЕрдиреБрд░реЛрдз рдЕрд╡рдзрд┐ ╨╕ рдЕрдиреБрд░реЛрдз рдХрд╛рдЙрдВрдЯрд░, рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдкрд░ рдкреНрд░рджрд░реНрд╢рд┐рдд рдХрд┐рдпрд╛ рдЧрдпрд╛ /рдореИрдЯреНрд░рд┐рдХреНрд╕ рдлреНрд▓рд╛рд╕реНрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдЬрд┐рд╕рдХреЗ рд╕рд╛рде рдпрд╣ рдкрдВрдЬреАрдХреГрдд рд╣реИ, рд╕рд╛рде рд╣реА рдЖрдзрд╛рд░ рд╕реЗ рдЖрдкрдХреЛ рдорд┐рд▓рдиреЗ рд╡рд╛рд▓реЗ рд╕рднреА рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рднреА
рддреБрдо рдЦреЛрдЬ рд╕рдХрддреЗ рд╣реЛ
рдЖрдкрдХреЛ рдЗрд╕рдореЗрдВ рд╕рдВрдХреЗрддрдХреЛрдВ рдХреА рдПрдХ рд╕реВрдЪреА рднреА рдорд┐рд▓реЗрдЧреА
рд╕рдорд╛рдпреЛрдЬрди
рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдХрдИ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╡рд┐рдХрд▓реНрдк рд╣реИрдВ, рджреЗрдЦреЗрдВ
рдореВрд▓ рд╡рд┐рдиреНрдпрд╛рд╕ рдКрдкрд░ рджрд┐рдЦрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИред рдмрд╕ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рдПрдВ рдкреНрд░реЛрдореЗрдерд┐рдпрд╕рдореЗрдЯреНрд░рд┐рдХреНрд╕, рдЪрд▓реЛ рдЗрд╕реЗ рдХреЙрд▓ рдХрд░реЗрдВ рдореЗрдЯреНрд░рд┐рдХреНрд╕, рдФрд░ рдлрд┐рд░ рдЗрд╕рдХрд╛ рдЙрдкрдпреЛрдЧ рдЙрди рдЕрддрд┐рд░рд┐рдХреНрдд рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдХреЛ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдХрд░реЗрдВ рдЬрд┐рдиреНрд╣реЗрдВ рдЖрдк рдлрд╝рдВрдХреНрд╢рдВрд╕ рдХреЛ рд╕рдЬрд╛рдХрд░ рдПрдХрддреНрд░ рдХрд░рдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ:
-
@metrics.counter(..)
-
@metrics.gauge(..)
-
@metrics.summary(..)
-
@metrics.histogram(..)
рдХрд╛рдЙрдВрдЯрд░ рдХреЙрд▓реЛрдВ рдХреА рдЧрд┐рдирддреА рдХрд░рддреЗ рд╣реИрдВ, рдФрд░ рдЕрдиреНрдп рдЙрди рдХреЙрд▓реЛрдВ рдХреА рдЕрд╡рдзрд┐ рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдореАрдЯреНрд░рд┐рдХ рдПрдХрддреНрд░ рдХрд░рддреЗ рд╣реИрдВред рдЖрдк рд╕рдВрднрд╛рд╡рд┐рдд рд░реВрдк рд╕реЗ рдЕрдиреБрд░реЛрдз рдпрд╛ рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдЧреБрдгреЛрдВ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдХреЗ рдЗрдирдореЗрдВ рд╕реЗ рдкреНрд░рддреНрдпреЗрдХ рдХреЗ рд▓рд┐рдП рд▓реЗрдмрд▓ рдкрд░рд┐рднрд╛рд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВред рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП:
from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics
app = Flask(__name__)
# group by endpoint rather than path
metrics = PrometheusMetrics(app, group_by='endpoint')
@app.route('/collection/:collection_id/item/:item_id')
@metrics.counter(
'cnt_collection', 'Number of invocations per 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
рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдкрд░ рдХреНрд▓рд┐рдХ рдХрд░реЗрдВ /рд╕рдВрдЧреНрд░рд╣/10002/рдЖрдЗрдЯрдо/76 рдЙрджрд╛рд╣рд░рдг рдХреЗ рд▓рд┐рдП, рдХрд╛рдЙрдВрдЯрд░ рдореЗрдВ рд╡реГрджреНрдзрд┐ рдХрд╛ рдХрд╛рд░рдг рдмрдиреЗрдЧрд╛ cnt_collection{рд╕рдВрдЧреНрд░рд╣ = "10002", рд╕реНрдерд┐рддрд┐ = "200"}, рд╕рд╛рде рд╣реА рдЖрдкрдХреЛ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рд╕реЗ рдбрд┐рдлрд╝реЙрд▓реНрдЯ рдореЗрдЯреНрд░рд┐рдХреНрд╕ (рдЗрд╕ рдЙрджрд╛рд╣рд░рдг рдореЗрдВ рдкреНрд░рддреНрдпреЗрдХ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдХреЗ рд▓рд┐рдП) рдорд┐рд▓реЗрдВрдЧреЗ:
-
flask_http_request_duration_seconds
- рд╡рд┐рдзрд┐, рдкрде рдФрд░ рд╕реНрдерд┐рддрд┐ рдХреЗ рдЕрдиреБрд╕рд╛рд░ рд╕рднреА рдлреНрд▓рд╛рд╕реНрдХ рдЕрдиреБрд░реЛрдзреЛрдВ рдХреЗ рд▓рд┐рдП HTTP рдЕрдиреБрд░реЛрдз рдЕрд╡рдзрд┐ рд╕реЗрдХрдВрдб рдореЗрдВ -
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}
)
)
рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдореЗрдВ рдпреВрдбрдмреНрд▓реНрдпреВрдПрд╕рдЬреАрдЖрдИ рдФрд░ рдЧреБрдирд┐рдХреЙрд░реНрди рдЬреИрд╕реА рд▓реЛрдХрдкреНрд░рд┐рдп рдорд▓реНрдЯреАрдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдХреЗ рд▓рд┐рдП рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдПрдХреНрд╕рдЯреЗрдВрд╢рди рд╣реИрдВред рдЖрдк рдорд▓реНрдЯреАрдкреНрд░реЛрд╕реЗрд╕рд┐рдВрдЧ рд╕рд╣рд┐рдд рд▓рдХреНрд╖рд┐рдд рдЙрдкрдпреЛрдЧ рдХреЗ рдорд╛рдорд▓реЛрдВ рдХреЗ рдЫреЛрдЯреЗ рдЙрджрд╛рд╣рд░рдг рднреА рдкрд╛ рд╕рдХрддреЗ рд╣реИрдВред
рдореЗрдЯреНрд░рд┐рдХреНрд╕ рд╕рдВрдЧреНрд░рд╣
рдЬреИрд╕рд╛ рдХрд┐ рдКрдкрд░ рдмрддрд╛рдпрд╛ рдЧрдпрд╛ рд╣реИ, рд▓рд╛рдЗрдмреНрд░реЗрд░реА рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд░реВрдк рд╕реЗ рдПрдХ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдкреНрд░рджрд╛рди рдХрд░рддреА рд╣реИ /рдореИрдЯреНрд░рд┐рдХреНрд╕ рдлреНрд▓рд╛рд╕реНрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ, рдЬреЛ рдПрдХ рд▓рдХреНрд╖реНрдп рдХреЗ рд░реВрдк рдореЗрдВ рдХрд╛рдо рдХрд░ рд╕рдХрддрд╛ рд╣реИ
рдЙрдкрд░реЛрдХреНрдд рдбреИрд╢рдмреЛрд░реНрдб рдЙрджрд╛рд╣рд░рдг рдореЗрдВ, рдЖрдк рдЕрдкрдиреЗ рдкреНрд░реЛрдореЗрдерд┐рдпрд╕ рдХреЛ рдЗрд╕ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рдХреЗ рд╕рд╛рде рдбрд┐рдлрд╝реЙрд▓реНрдЯ рд╕реЗрдЯрд┐рдВрдЧреНрд╕ рд╡рд╛рд▓реЗ рдлреНрд▓рд╛рд╕реНрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдкрд░ рд▓рдХреНрд╖рд┐рдд рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ:
scrape_configs:
- job_name: 'example'
dns_sd_configs:
- names: ['app']
port: 5000
type: A
refresh_interval: 5s
рдкреВрд░рд╛ рдЙрджрд╛рд╣рд░рдг рдпрд╣рд╛рдВ рджреЗрдЦреЗрдВ
рдпрджрд┐ рдореЗрдЯреНрд░рд┐рдХреНрд╕ рдПрдВрдбрдкреЙрдЗрдВрдЯ рдХреЛ рдЗрд╕ рддрд░рд╣ рд╕реЗ рдЙрдЬрд╛рдЧрд░ рдХрд░рдирд╛ рдЖрдкрдХреЗ рд▓рд┐рдП рдЙрдкрдпреБрдХреНрдд рдирд╣реАрдВ рд╣реИ, рд╢рд╛рдпрдж рдЗрд╕рд▓рд┐рдП рдХрд┐ рдЖрдк рдЙрд╕ рддрдХ рдмрд╛рд╣рд░реА рдкрд╣реБрдВрдЪ рдХреА рдЕрдиреБрдорддрд┐ рдирд╣реАрдВ рджреЗрдирд╛ рдЪрд╛рд╣рддреЗ рд╣реИрдВ, рддреЛ рдЖрдк рдЗрд╕реЗ рдкрд╛рд╕ рдХрд░рдХреЗ рдЖрд╕рд╛рдиреА рд╕реЗ рдЕрдХреНрд╖рдо рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдкрде=рдХреЛрдИ рдирд╣реАрдВ рдПрдХ рдЙрджрд╛рд╣рд░рдг рдмрдирд╛рддреЗ рд╕рдордп рдкреНрд░реЛрдореЗрдерд┐рдпрд╕рдореЗрдЯреНрд░рд┐рдХреНрд╕.
from flask import Flask, request
from prometheus_flask_exporter import PrometheusMetrics
app = Flask(__name__)
metrics = PrometheusMetrics(app, path=None)
...
metrics.start_http_server(5099)
рддрдм рдЖрдк рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рдкреНрд░рд╛рд░рдВрдн_http_рд╕рд░реНрд╡рд░(рдкреЛрд░реНрдЯ)рдЗрд╕ рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдХреЛ рдХрд┐рд╕реА рднрд┐рдиреНрди HTTP рдкреЛрд░реНрдЯ рдкрд░ рдЦреЛрд▓рдиреЗ рдХреЗ рд▓рд┐рдП, 5099 рдЙрдкрд░реЛрдХреНрдд рдЙрджрд╛рд╣рд░рдг рдореЗрдВ. рд╡реИрдХрд▓реНрдкрд┐рдХ рд░реВрдк рд╕реЗ, рдпрджрд┐ рдЖрдк рд╕рдорд╛рдкрди рдмрд┐рдВрджреБ рдХреЗ рдПрдХ рд╣реА рдлреНрд▓рд╛рд╕реНрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЗрдВ рд╣реЛрдиреЗ рд╕реЗ рдЦреБрд╢ рд╣реИрдВ, рд▓реЗрдХрд┐рди рдЖрдкрдХреЛ рдЗрд╕рдХрд╛ рдкрде рдмрджрд▓рдиреЗ рдХреА рдЖрд╡рд╢реНрдпрдХрддрд╛ рд╣реИ /рдореИрдЯреНрд░рд┐рдХреНрд╕, рдЖрдк рдпрд╛ рддреЛ рдкрде рдкреИрд░рд╛рдореАрдЯрд░ рдХреЗ рд░реВрдк рдореЗрдВ рдПрдХ рдФрд░ рдпреВрдЖрд░рдЖрдИ рдкрд╛рд╕ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ, рдпрд╛ рдЙрдкрдпреЛрдЧ рдХрд░ рд╕рдХрддреЗ рд╣реИрдВ рд░рдЬрд┐рд╕реНрдЯрд░_рдПрдВрдбрдкреЙрдЗрдВрдЯ(..)рдЗрд╕реЗ рдмрд╛рдж рдореЗрдВ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП.
рд╕рдВрджрд░реНрднреЛрдВ
-
rycus86/prometheus_flask_exporter - рдкреНрд░реЛрдореЗрдерд┐рдпрд╕ рдХреЗ рд▓рд┐рдП рдпрд╣ рдмреЛрддрд▓ рдирд┐рд░реНрдпрд╛рддрдХ -
рдкреНрд░реЛрдореЗрдерд┐рдпрд╕-рдлреНрд▓рд╛рд╕реНрдХ-рдирд┐рд░реНрдпрд╛рддрдХ README - рдЙрдкрдпреЛрдЧ, рдЙрджрд╛рд╣рд░рдг рдФрд░ рдХреЙрдиреНрдлрд╝рд┐рдЧрд░реЗрд╢рди рд╡рд┐рдХрд▓реНрдк -
рдкреНрд░реЛрдореЗрдерд┐рдпрд╕-рдлреНрд▓рд╛рд╕реНрдХ-рдирд┐рд░реНрдпрд╛рддрдХ рдЙрджрд╛рд╣рд░рдг - рд╡рд┐рднрд┐рдиреНрди рддрд░реАрдХреЛрдВ рд╕реЗ рдлреНрд▓рд╛рд╕реНрдХ рдПрдкреНрд▓рд┐рдХреЗрд╢рди рдореЙрдирд┐рдЯрд░рд┐рдВрдЧ рд╕реНрдерд╛рдкрд┐рдд рдХрд░рдиреЗ рдХреЗ рдЙрджрд╛рд╣рд░рдг -
PyPI рдкрд░ рдкреНрд░реЛрдореЗрдерд┐рдпрд╕-рдлреНрд▓рд╛рд╕реНрдХ-рдирд┐рд░реНрдпрд╛рддрдХ - рдпрд╣ рдкреНрд░реЛрдЬреЗрдХреНрдЯ PyPI рдкрд░ рд╣реИ -
рдкреНрд░реЛрдореЗрдерд┐рдпрд╕/рдХреНрд▓рд╛рдЗрдВрдЯ_рдкрд╛рдпрдерди - рдкрд╛рдпрдерди рдХреЗ рд▓рд┐рдП рдЖрдзрд┐рдХрд╛рд░рд┐рдХ рдкреНрд░реЛрдореЗрдерд┐рдпрд╕ рдХреНрд▓рд╛рдЗрдВрдЯ рд▓рд╛рдЗрдмреНрд░реЗрд░реА
рдпрджрд┐ рдЖрдк рдЗрд╕реЗ рдЖрдЬрд╝рдорд╛рдиреЗ рдХрд╛ рдирд┐рд░реНрдгрдп рд▓реЗрддреЗ рд╣реИрдВ, рддреЛ рдмреЗрдЭрд┐рдЭрдХ GitHub рдкрд░ рдПрдХ рдореБрджреНрджрд╛ рдЦреЛрд▓реЗрдВ рдпрд╛ рдЕрдкрдиреА рдЯрд┐рдкреНрдкрдгрд┐рдпрд╛рдБ, рдкреНрд░рддрд┐рдХреНрд░рд┐рдпрд╛ рдФрд░ рд╕реБрдЭрд╛рд╡ рдЫреЛрдбрд╝реЗрдВ!
рд╢реБрдХреНрд░рд┐рдпрд╛!
рд╕реНрд░реЛрдд: www.habr.com