ЁЯУК рдзрдбрд╛ 03 тАФ Metrics: рддрдкрд╛рд╕рдгреА рддрдХреНрддрд╛
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 12 рдкреИрдХреА рдзрдбрд╛ 03 ┬╖ рдорд╛рдЧреЗ: lesson-02-logs ┬╖ рдкреБрдвреЗ: lesson-04-percentiles
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ02, рдЖрдгрд┐ рджреБрд╕рд░рд╛ signal: metrics. рддреБрдореНрд╣реА metrics рдЪреЗ рддреАрди рдкреНрд░рдХрд╛рд░ рд╢рд┐рдХрддрд╛ тАФ
counter, gauge, histogram тАФ рдЖрдгрд┐ labels, Prometheus рдЪрд╛ text format, рдЖрдгрд┐
cardinality рдЪрд╛ рд╕рд╛рдкрд│рд╛. Counter, Gauge, Histogram, exposition() рдЖрдгрд┐
cardinality() obs/signals.py рдордзреНрдпреЗ рдЖрд╣реЗрдд;
obs/demo.py рдордзреАрд▓ metrics() рддреЗ print рдХрд░рддреЗ.
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
рдЖрд░реЛрдЧреНрдп рдХрдХреНрд╖рд╛рдЪреНрдпрд╛ рднрд┐рдВрддреАрд╡рд░ рдХрддрд░рд┐рдирд╛рдЪрд╛ рддрдкрд╛рд╕рдгреА рддрдХреНрддрд╛ ЁЯУК рд▓рдЯрдХрд▓реЗрд▓рд╛ рдЖрд╣реЗ. рддреЛ рджреИрдирдВрджрд┐рдиреАрд╕рд╛рд░рдЦреНрдпрд╛ рдЧреЛрд╖реНрдЯреА рд╕рд╛рдВрдЧрдд рдирд╛рд╣реА. рддреНрдпрд╛рдд рд╡реЗрд│реЗрдиреБрд╕рд╛рд░ рдЖрдХрдбреЗ рдЕрд╕рддрд╛рдд. рддреНрдпрд╛рдЪреЗ рддреАрди рдкреНрд░рдХрд╛рд░ рдЖрд╣реЗрдд:
- рдПрдХ рдореЛрдЬрдгреА (tally) тАФ "рдЖрдЬ рддрдкрд╛рд╕рд▓реЗрд▓реЗ рд╡рд┐рджреНрдпрд╛рд░реНрдереА": рдХрддрд░рд┐рдирд╛ рдкреНрд░рддреНрдпреЗрдХ рд╡реЗрд│реА рдПрдХ рдЦреВрдг рдЬреЛрдбрддреЗ. рддреЛ рдлрдХреНрдд рд╡рд╛рдврддреЛ. рдордзреНрдпрд░рд╛рддреНрд░реА рддреЛ рдкреБрдиреНрд╣рд╛ рд╢реВрдиреНрдпрд╛рдкрд╛рд╕реВрди рд╕реБрд░реВ рд╣реЛрддреЛ. рдХрдХреНрд╖ рдХрд┐рддреА рд╡реНрдпрд╕реНрдд рдЖрд╣реЗ рд╣реЗ рдЬрд╛рдгрдгреНрдпрд╛рд╕рд╛рдареА рддреА "рдЧреЗрд▓реНрдпрд╛ рддрд╛рд╕рд╛рдд рдХрд┐рддреА рдЦреБрдгрд╛?" рдЕрд╕реЗ рд╡рд┐рдЪрд╛рд░рддреЗ тАФ "рдПрдХреВрдг рдХрд┐рддреА рдЦреБрдгрд╛?" рдЕрд╕реЗ рдирд╛рд╣реА.
- рдПрдХ thermometer рдЪреЗ рд╡рд╛рдЪрди тАФ "рдЖрддреНрддрд╛ рд╡рд╛рдкрд░рд╛рдд рдЕрд╕рд▓реЗрд▓реЗ рдмреЗрдб": 4, рдордЧ 2, рдордЧ 3. рддреЗ рд╡рд░ рдЖрдгрд┐ рдЦрд╛рд▓реА рд╣реЛрддреЗ. рдлрдХреНрдд рдЖрддреНрддрд╛рдЪреЗ рд╡рд╛рдЪрди рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ.
- рдПрдХ рд╡рд░реНрдЧреАрдХрд░рдгрд╛рдЪреЗ рдХрдкрд╛рдЯ тАФ рдкреНрд░рддреНрдпреЗрдХ рднреЗрдЯреАрдЪрд╛ рдХрд╛рд▓рд╛рд╡рдзреА рдПрдХрд╛ рдЦреЛрдХреНрдпрд╛рдд рдЬрд╛рддреЛ: "5 рдорд┐рдирд┐рдЯреЗ рдХрд┐рдВрд╡рд╛ рдХрдореА", "10 рдХрд┐рдВрд╡рд╛ рдХрдореА", "30 рдХрд┐рдВрд╡рд╛ рдХрдореА". рдкреНрд░рддреНрдпреЗрдХ рдЦреЛрдХрд╛ рддреНрдпрд╛рдЪреНрдпрд╛ рдЖрдХрд╛рд░рд╛рдкрд░реНрдпрдВрддрдЪреЗ рд╕рдЧрд│реЗ рдореЛрдЬрддреЛ, рдореНрд╣рдгреВрди "10 рдХрд┐рдВрд╡рд╛ рдХрдореА" рдЦреЛрдХрд╛ 5 рдорд┐рдирд┐рдЯрд╛рдВрдЪреНрдпрд╛ рднреЗрдЯреАрд╣реА рдореЛрдЬрддреЛ.
рдЖрдгрд┐ рдПрдХ рдЗрд╢рд╛рд░рд╛. рдХрддрд░рд┐рдирд╛ рдореЛрдЬрдгреА рд╡рд░реНрдЧрд╛рдиреБрд╕рд╛рд░ рд╡рд┐рднрд╛рдЧреВ рд╢рдХрддреЗ: 3A, 3B, 4A. рддреЗ рдареАрдХ рдЖрд╣реЗ тАФ рдХрд╛рд╣реА рд╕реНрддрдВрдн. рдкрдг рдЬрд░ рддреА рддреА рд╡рд┐рджреНрдпрд╛рд░реНрдереНрдпрд╛рдЪреНрдпрд╛ рдирд╛рд╡рд╛рдиреБрд╕рд╛рд░ рд╡рд┐рднрд╛рдЧрд▓реА, рддрд░ рддрдХреНрддреНрдпрд╛рд▓рд╛ рд╢рд╛рд│реЗрддрд▓реНрдпрд╛ рдкреНрд░рддреНрдпреЗрдХ рд╡рд┐рджреНрдпрд╛рд░реНрдереНрдпрд╛рд╕рд╛рдареА рдПрдХ рд╕реНрддрдВрдн рд▓рд╛рдЧреЗрд▓. рднрд┐рдВрдд рддреЗрд╡рдвреА рдореЛрдареА рдирд╛рд╣реА.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
subgraph types["ЁЯУК three metric types"]
c["тЮХ counter<br/>http_requests_total<br/>only up ┬╖ resets to 0 on restart"]
g["ЁЯМбя╕П gauge<br/>print_queue_length 137<br/>up and down"]
h["ЁЯЧДя╕П histogram<br/>_bucket{le=тАж} cumulative<br/>+ _sum + _count"]
end
ex["ЁЯУД /metrics text format"]
c --> ex
g --> ex
h --> ex
lab["ЁЯП╖я╕П labels: route ├Ч status = 2 ├Ч 3 = 6 series<br/>+ user_id (50,000) = 300,000 series ЁЯТе"]
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/observability/lesson-diagrams.html#l03
тЭУ рдХрд╛рдп
- Metric тАФ рд╡реЗрд│реЗрдиреБрд╕рд╛рд░ рдореЛрдЬрд▓реЗрд▓рд╛ рдЖрдХрдбрд╛. рдкреНрд░рддреНрдпреЗрдХ рдХрд┐рдВрдордд
(timestamp, value)рдореНрд╣рдгреВрди рд╕рд╛рдард╡рд▓реА рдЬрд╛рддреЗ. Time series рдореНрд╣рдгрдЬреЗ рдПрдХ metric name рдЖрдгрд┐ labels рдЪреНрдпрд╛ рдХрд┐рдорддреАрдВрдЪрд╛ рдПрдХ рдиреЗрдордХрд╛ рд╕рдВрдЪ. - Counter тАФ рдПрдХ рдПрдХреВрдг рдЖрдХрдбрд╛ рдЬреЛ рдлрдХреНрдд рд╡рд╛рдврддреЛ (рд╣рд╛рддрд╛рд│рд▓реЗрд▓реНрдпрд╛ requests, errors, рдкрд╛рдард╡рд▓реЗрд▓реЗ bytes). рддреЛ
process restart рдЭрд╛рд▓реНрдпрд╛рд╡рд░ 0 рд╡рд░ reset рд╣реЛрддреЛ. рддреБрдореНрд╣реА рдЬрд╡рд│рдЬрд╡рд│ рдХрдзреАрдЪ рддреНрдпрд╛рдЪреА рдХрдЪреНрдЪреА рдХрд┐рдВрдордд graph рдХрд░рдд рдирд╛рд╣реА; рддреБрдореНрд╣реА
рддреНрдпрд╛рдЪрд╛ rate graph рдХрд░рддрд╛ тАФ рдПрдХрд╛ window рдордзрд▓реА рджрд░ рд╕реЗрдХрдВрджрд╛рдЪреА рд╡рд╛рдв (рдзрдбрд╛ 07). рдирд╛рд╡реЗ
_totalрдиреЗ рд╕рдВрдкрддрд╛рдд. - Gauge тАФ рд╡рд░ рдЖрдгрд┐ рдЦрд╛рд▓реА рд╣реЛрдгрд╛рд░реА рдХрд┐рдВрдордд: queue length, рд╡рд╛рдкрд░рд╛рддрд▓реА memory, рд╡рд╛рдкрд░рд╛рддрд▓реЗ рдмреЗрдб, рддрд╛рдкрдорд╛рди. рддреБрдореНрд╣реА рддреА рдЖрддреНрддрд╛ рдЬрд╢реА рдЖрд╣реЗ рддрд╢реА рд╡рд╛рдЪрддрд╛.
- Histogram тАФ рдирд┐рд░реАрдХреНрд╖рдгреЗ (рдЬрд╕реЗ request durations) buckets рдордзреНрдпреЗ рдореЛрдЬрддреЛ.
Prometheus рдордзреНрдпреЗ buckets cumulative рдЕрд╕рддрд╛рдд:
leрдореНрд╣рдгрдЬреЗ "less than or equal", рдореНрд╣рдгреВрди_bucket{le="0.25"}рдкреНрд░рддреНрдпреЗрдХ тЙд 0.25 s request рдореЛрдЬрддреЛ, тЙд 0.1 s рдЪреНрдпрд╛ requests рд╕рд╣. рдиреЗрд╣рдореА рдПрдХle="+Inf"bucket рдЕрд╕рддреЛ (рдкреНрд░рддреНрдпреЗрдХ рдирд┐рд░реАрдХреНрд╖рдг). Histogram_sum(рд╕рдЧрд│реНрдпрд╛ рдХрд┐рдорддреАрдВрдЪреА рдмреЗрд░реАрдЬ) рдЖрдгрд┐_count(рдХрд┐рддреА) рд╕реБрджреНрдзрд╛ рджреЗрддреЛ._sum / _countрдореНрд╣рдгрдЬреЗ рд╕рд░рд╛рд╕рд░реА. рдзрдбрд╛ 04 buckets рдЪреЗ percentiles рдордзреНрдпреЗ рд░реВрдкрд╛рдВрддрд░ рдХрд░рддреЛ. - Summary тАФ durations рд╕рд╛рдареА Prometheus рдЪрд╛ рджреБрд╕рд░рд╛ рдкреНрд░рдХрд╛рд░. рддреЛ quantiles (рдЬрд╕реЗ p99) app рдЪреНрдпрд╛ рдЖрддрдЪ (client-side) рдореЛрдЬрддреЛ рдЖрдгрд┐ рдереЗрдЯ рджреЗрддреЛ. рддреЗ quantiles aggregate рдХрд░рддрд╛ рдпреЗрдд рдирд╛рд╣реАрдд: рджрд╣рд╛ pods рдЪреЗ p99 рдПрдХрддреНрд░ рдХрд░реВрди рдПрдХ p99 рдмрдирд╡рддрд╛ рдпреЗрдд рдирд╛рд╣реА (рдХрд╛ рддреЗ рдзрдбрд╛ 04 рджрд╛рдЦрд╡рддреЛ). рддреБрдореНрд╣реА рдПрдХрд╛рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд copies рдЪрд╛рд▓рд╡рдд рдЕрд╕рд╛рд▓ рддрд░ histograms рд╡рд╛рдкрд░рд╛.
- Labels тАФ metric рд▓рд╛ рд╡рд┐рднрд╛рдЧрдгрд╛рд▒реНрдпрд╛ keyтАУvalue рдЬреЛрдбреНрдпрд╛:
http_requests_total{route="/results", status="500"}. - Cardinality тАФ рдПрдХ metric рдХрд┐рддреА time series рдмрдирд╡рддреЛ рддреА рд╕рдВрдЦреНрдпрд╛. рддреА рдкреНрд░рддреНрдпреЗрдХ label рдЪреНрдпрд╛ рдХрд┐рдорддреАрдВрдЪреНрдпрд╛
рд╕рдВрдЦреНрдпрд╛рдВрдЪрд╛ рдЧреБрдгрд╛рдХрд╛рд░ рдЕрд╕рддреЗ: 2 routes ├Ч 3 statuses = 6 series; 50,000 users рд╕рд╣
user_idрдЬреЛрдбрд▓рд╛ рддрд░ 300,000. рдкреНрд░рддреНрдпреЗрдХ series рд▓рд╛ memory, storage рдЖрдгрд┐ query time рд▓рд╛рдЧрддреЛ. User ids, emails, рдкреВрд░реНрдг URLs, trace ids рдХрд┐рдВрд╡рд╛ timestamps рдХрдзреАрдЪ label values рдореНрд╣рдгреВрди рд╡рд╛рдкрд░реВ рдирдХрд╛. рддреНрдпрд╛ logs рдЖрдгрд┐ traces рдордзреНрдпреЗ рдЬрд╛рддрд╛рдд. - Exposition format тАФ
/metricsendpoint рджреЗрддреЛ рддреЛ рд╕рд╛рдзрд╛ рдордЬрдХреВрд░:# HELP,# TYPE, рдордЧ рдкреНрд░рддреНрдпреЗрдХ series рд╕рд╛рдареА рдПрдХ рдУрд│. - рджреЛрди рдЙрдкрдпреЛрдЧреА checklists: services рд╕рд╛рдареА RED тАФ Rate, Errors, Duration; рдЖрдгрд┐ resources рд╕рд╛рдареА USE тАФ Utilisation, Saturation, Errors.
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг metrics рд╕реНрд╡рд╕реНрдд рдЖрдгрд┐ рдЬрд▓рдж рдЕрд╕рддрд╛рдд. Traffic рдХрд┐рддреАрд╣реА рдЕрд╕реЛ, counter рдореНрд╣рдгрдЬреЗ рдкреНрд░рддреНрдпреЗрдХ series рд╕рд╛рдареА рдПрдХ рдЖрдХрдбрд╛: 10 requests рдЕрд╕реЛрдд рдХрд┐рдВрд╡рд╛ 1 рдХреЛрдЯреА, рд╕рд╛рдард╡рд╛рдпрд▓рд╛ рддреЗрд╡рдврд╛рдЪ рдЦрд░реНрдЪ. рддреНрдпрд╛рдореБрд│реЗ dashboards рдЖрдгрд┐ alerts рд╕рд╛рдареА metrics рд╣рд╛рдЪ рдпреЛрдЧреНрдп signal рдЖрд╣реЗ. рддреНрдпрд╛рдЪреА рдХрд┐рдВрдордд рдореНрд╣рдгрдЬреЗ рддрдкрд╢реАрд▓: metric рд╕рд╛рдВрдЧрддреЛ 20 requests рдЕрдпрд╢рд╕реНрд╡реА рдЭрд╛рд▓реНрдпрд╛, рдкрдг рдХреЛрдгрддреНрдпрд╛ рддреЗ рдирд╛рд╣реА. рдЖрдгрд┐ metrics рдорд╣рд╛рдЧ рдХрд░рдгреНрдпрд╛рдЪрд╛ рдПрдХрдореЗрд╡ рдорд╛рд░реНрдЧ рдореНрд╣рдгрдЬреЗ high cardinality.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
Counter.inc(labels, by) рдкреНрд░рддреНрдпреЗрдХ label рд╕рдВрдЪрд╛рдЪреНрдпрд╛ рдПрдХреВрдг рдЖрдХрдбреНрдпрд╛рдд рднрд░ рдШрд╛рд▓рддреЛ; Gauge.set(v) рдХрд┐рдВрдордд рдмрджрд▓рддреЛ;
Histogram(name, help, buckets).observe_all(values) cumulative bucket counts рдЖрдгрд┐
sum рд╡ count рднрд░рддреЛ. exposition(*metrics) рддреЗ Prometheus /metrics
endpoint рдкреНрд░рдорд╛рдгреЗ print рдХрд░рддреЛ. cardinality(**label_values) рдкреНрд░рддреНрдпреЗрдХ label рдЪреНрдпрд╛ рдХрд┐рдорддреАрдВрдЪреНрдпрд╛ рд╕рдВрдЦреНрдпрд╛рдВрдЪрд╛ рдЧреБрдгрд╛рдХрд╛рд░ рдХрд░рддреЛ.
metrics() status рдиреБрд╕рд╛рд░ 9,500 requests рдореЛрдЬрддреЗ, print-queue gauge 137 рд╡рд░ рдареЗрд╡рддреЗ рдЖрдгрд┐ рджрд┐рд╡рд╕рд╛рдЪреНрдпрд╛
20 рдирдореБрдирд╛ latencies рдкрд╛рдЪ buckets рдордзреНрдпреЗ рдЯрд╛рдХрддреЗ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
рдЖрд░реЛрдЧреНрдп рдХрдХреНрд╖рд╛рдЪрд╛ рд╕реНрд╡рддрдГрдЪрд╛ рддрдХреНрддрд╛ тАФ рдордЧ labels рдХрд╕реЗ рдЧреБрдгрд▓реЗ рдЬрд╛рддрд╛рдд рддреЗ рдкрд╛рд╣рд╛:
python3 obs/demo.py metrics
python3 - <<'EOF'
import sys; sys.path.insert(0, "obs"); from signals import Counter, Gauge, Histogram, exposition, cardinality
c = Counter("pupils_seen_total", "Pupils seen by the nurse")
c.inc((("reason", "fever"),), 3); c.inc((("reason", "scraped knee"),), 5); c.inc((("reason", "fever"),))
g = Gauge("beds_in_use", "Beds in use right now"); g.set(4); g.set(2)
h = Histogram("visit_minutes", "Minutes per visit", [5, 10, 30]).observe_all([3, 4, 8, 12, 25, 40])
print(exposition(c, g, h))
routes, status = ["/results", "/notices"], ["200", "404", "500"]
print("route ├Ч status тЖТ", cardinality(route=routes, status=status))
print("+ method (4) тЖТ", cardinality(route=routes, status=status, method=["GET", "POST", "PUT", "DELETE"]))
print("+ method (4) + pod (20) тЖТ", f"{cardinality(route=routes, status=status, method=list('abcd'), pod=list(range(20))):,}")
print("+ pod (20) + user_id (50,000) тЖТ", f"{cardinality(route=routes, status=status, pod=list(range(20)), user_id=list(range(50_000))):,}")
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
metrics рд╣реЗ print рдХрд░рддреЗ (рдХрд╛рд╣реА рднрд╛рдЧ):
http_requests_total{route="/results",status="200"} 9450
http_requests_total{route="/results",status="404"} 30
http_requests_total{route="/results",status="500"} 20
# HELP print_queue_length Certificates waiting
# TYPE print_queue_length gauge
print_queue_length 137
http_request_duration_seconds_bucket{le="0.1"} 10
http_request_duration_seconds_bucket{le="0.25"} 18
http_request_duration_seconds_bucket{le="0.5"} 19
http_request_duration_seconds_bucket{le="1.0"} 19
http_request_duration_seconds_bucket{le="2.5"} 20
http_request_duration_seconds_bucket{le="+Inf"} 20
http_request_duration_seconds_sum 3.657
http_request_duration_seconds_count 20
тФАтФА labels route, status тЖТ 6 time series
тФАтФА labels route, status, user_id тЖТ 300,000 time series
рддреБрдордЪрд╛ snippet рд╣реЗ print рдХрд░рддреЛ:
# HELP pupils_seen_total Pupils seen by the nurse
# TYPE pupils_seen_total counter
pupils_seen_total{reason="fever"} 4
pupils_seen_total{reason="scraped knee"} 5
# HELP beds_in_use Beds in use right now
# TYPE beds_in_use gauge
beds_in_use 2
# HELP visit_minutes Minutes per visit
# TYPE visit_minutes histogram
visit_minutes_bucket{le="5"} 2
visit_minutes_bucket{le="10"} 3
visit_minutes_bucket{le="30"} 5
visit_minutes_bucket{le="+Inf"} 6
visit_minutes_sum 92.0
visit_minutes_count 6
route ├Ч status тЖТ 6
+ method (4) тЖТ 24
+ method (4) + pod (20) тЖТ 480
+ pod (20) + user_id (50,000) тЖТ 6,000,000
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
Counter рдиреЗ рдлрдХреНрдд рдмреЗрд░реАрдЬ рдХреЗрд▓реА (3 + 1 рддрд╛рдк = 4). Gauge рдиреЗ рдлрдХреНрдд рддреНрдпрд╛рдЪреЗ рд╢реЗрд╡рдЯрдЪреЗ рд╡рд╛рдЪрди рдареЗрд╡рд▓реЗ (2, 4
рдирд╛рд╣реА). Histogram рдЪреЗ buckets cumulative рдЖрд╣реЗрдд: le="10" bucket рдордзреНрдпреЗ 3 рднреЗрдЯреА рдЖрд╣реЗрдд тАФ 3
рдЖрдгрд┐ 4 рдорд┐рдирд┐рдЯрд╛рдВрдЪреНрдпрд╛ рднреЗрдЯреА рддрд╕реЗрдЪ 8 рдорд┐рдирд┐рдЯрд╛рдВрдЪреА рднреЗрдЯ тАФ рдЖрдгрд┐ 40 рдорд┐рдирд┐рдЯрд╛рдВрдЪреА рднреЗрдЯ рдлрдХреНрдд
+Inf рдордзреНрдпреЗ рджрд┐рд╕рддреЗ. рд╕рд░рд╛рд╕рд░реА рднреЗрдЯ _sum / _count = 92 / 6 тЙИ 15.3 рдорд┐рдирд┐рдЯреЗ. рдЖрдгрд┐ cardinality рд╣рд╛
рдЧреБрдгрд╛рдХрд╛рд░ рдЖрд╣реЗ: рдирд┐рд░реБрдкрджреНрд░рд╡реА labels (method, pod) рдиреА 6 series 480 рдкрд░реНрдпрдВрдд рдиреЗрд▓реНрдпрд╛; рдПрдХрд╛ user_id label рдиреЗ рддреНрдпрд╛
60 рд▓рд╛рдЦ (6 million) рдкрд░реНрдпрдВрдд рдиреЗрд▓реНрдпрд╛.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- counter рдЪреНрдпрд╛
rate()рдРрд╡рдЬреА рддреНрдпрд╛рдЪреА рдХрдЪреНрдЪреА рдХрд┐рдВрдордд graph рдХрд░рдгреЗ (рдлрдХреНрдд рдЪрдврдд рдЬрд╛рдгрд╛рд░реА рд░реЗрд╖рд╛) - рдореЛрдЬрд╛рдпрд▓рд╛ рд╣рд╡реЗ рдЕрд╢рд╛ рдЧреЛрд╖реНрдЯреАрд╕рд╛рдареА gauge тАФ 15 рд╕реЗрдХрдВрджрд╛рдВрдЪрд╛ scrape рджреЛрди scrapes рдордзреНрдпреЗ рдШрдбрд▓реЗрд▓реЗ рдЪреБрдХрд╡рддреЛ
- user ids, emails, рдкреВрд░реНрдг URLs (
/results/3A/pupil/1234) рдХрд┐рдВрд╡рд╛ error messages label values рдореНрд╣рдгреВрди - рдЕрдиреЗрдХ pods рдЪрд╛рд▓рд╡рдд рдЕрд╕рддрд╛рдирд╛ summary рд╡рд╛рдкрд░рдгреЗ рдЖрдгрд┐ рдордЧ quantiles рдПрдХрддреНрд░ рдХрд░рдгреНрдпрд╛рдЪрд╛ рдкреНрд░рдпрддреНрди рдХрд░рдгреЗ
- units рдирд╕рд▓реЗрд▓реА metric names тАФ
_seconds,_bytes, рдЖрдгрд┐ counters рд╕рд╛рдареА_totalрд╡рд╛рдкрд░рд╛ - рджреЛрди services рдордзреНрдпреЗ рдПрдХрд╛рдЪ label рдЪреА рд╡реЗрдЧрд╡реЗрдЧрд│реА рдирд╛рд╡реЗ (
statusрдЖрдгрд┐code)
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
On a real account тАФ Python рдЪреА prometheus_client library, port 8000 рд╡рд░ /metrics
рджреЗрдгрд╛рд░реА:
from prometheus_client import Counter, Gauge, Histogram, start_http_server
REQUESTS = Counter("http_requests_total", "Requests served", ["route", "status"])
QUEUE = Gauge("print_queue_length", "Certificates waiting")
LATENCY = Histogram("http_request_duration_seconds", "Request time", ["route"],
buckets=[0.05, 0.1, 0.25, 0.5, 1.0, 2.5])
start_http_server(8000) # Prometheus scrapes http://host:8000/metrics
def handle(route): # route = the TEMPLATE "/results/{cls}", not the full URL
with LATENCY.labels(route=route).time():
status = serve(route)
REQUESTS.labels(route=route, status=str(status)).inc()
QUEUE.set(print_queue.size())
Prometheus рдордзреНрдпреЗ рд╕рд░реНрд╡рд╛рдд рдЬрд╛рд╕реНрдд series рдЕрд╕рд▓реЗрд▓реЗ metrics рд╢реЛрдзрд╛ (Prometheus UI рдордзреНрдпреЗ рдЪрд╛рд▓рд╡рд╛):
topk(10, count by (__name__) ({__name__=~".+"}))
CloudWatch тАФ dimensions рд╕рд╣ рдПрдХ metric (рдкреНрд░рддреНрдпреЗрдХ dimension combination рд╣рд╛ рд╕реНрд╡рддрдВрддреНрд░ metric рдЕрд╕рддреЛ, рдЖрдгрд┐ custom metrics рдЪреЗ bill рдкреНрд░рддрд┐ metric рдпреЗрддреЗ):
aws cloudwatch put-metric-data --namespace School/ResultsApi \
--metric-name Requests --dimensions Route=/results,Status=500 --value 1 --unit Count
Datadog рдордзреНрдпреЗ рд╣реАрдЪ рдХрд▓реНрдкрдирд╛ tags рдореНрд╣рдгреВрди: results.requests{route:/results,status:500}; рдкреНрд░рддреНрдпреЗрдХ
рд╡реЗрдЧрд│реЗ tag combination bill рд╡рд░ рдПрдХ custom metric рдЕрд╕рддреЗ.
ЁЯПн Production рдордзреНрдпреЗ рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: label рдЬреЛрдбрдгреНрдпрд╛рдкреВрд░реНрд╡реА рдЧреБрдгрд╛рдХрд╛рд░ рдХрд░рд╛. рдХрд┐рдорддреАрдВрдЪреА рд╕рдВрдЦреНрдпрд╛ ├Ч рдЗрддрд░ рдкреНрд░рддреНрдпреЗрдХ label рдЪреНрдпрд╛ рдХрд┐рдорддреА ├Ч pods рдЪреА рд╕рдВрдЦреНрдпрд╛. рдЙрддреНрддрд░ рдХрд╛рд╣реА рд╣рдЬрд╛рд░ series рдкреЗрдХреНрд╖рд╛ рдЬрд╛рд╕реНрдд рдЖрд▓реЗ, рддрд░ рддреА рдХрд┐рдВрдордд рддреНрдпрд╛рдРрд╡рдЬреА log рдУрд│реАрдд рдХрд┐рдВрд╡рд╛ span attribute рдордзреНрдпреЗ рдЬрд╛рдпрд▓рд╛ рд╣рд╡реА.
тПня╕П рдкреБрдвреЗ
Histogram рдордзреНрдпреЗ buckets рдЖрд╣реЗрдд. Buckets рдЪреЗ "99% рдкрд╛рд▓рдХрд╛рдВрдиреА X рдкреЗрдХреНрд╖рд╛ рдХрдореА рд╡реЗрд│ рд╡рд╛рдЯ рдкрд╛рд╣рд┐рд▓реА" рдордзреНрдпреЗ рд░реВрдкрд╛рдВрддрд░ рдХрд╕реЗ рдХрд░рд╛рдпрдЪреЗ? рдЖрдгрд┐ рддреНрдпрд╛ рдЖрдХрдбреНрдпрд╛рдЪреА рд╕рд░рд╛рд╕рд░реА рдХрдзреАрдЪ рдХрд╛ рдХрд╛рдврддрд╛ рдпреЗрдд рдирд╛рд╣реА?
git checkout lesson-04-percentiles