ЁЯУИ рдзрдбрд╛ 15 тАФ рд░рдЪрдиреЗрддреВрдирдЪ observability: "рдирд┐рд░реЛрдЧреА" рдореНрд╣рдгрдЬреЗ рдХрд╛рдп рддреЗ рдард░рд╡рд╛
ЁЯУН рддреБрдореНрд╣реА рдЗрдереЗ рдЖрд╣рд╛рдд: 18 рдкреИрдХреА рдзрдбрд╛ 15 ┬╖ рдкреБрдвреЗ: lesson-16-cost-and-adrs
ЁЯУж рдпрд╛ рдмреНрд░рдБрдЪрдордзреНрдпреЗ рдХрд╛рдп рдЖрд╣реЗ
рдзрдбреЗ 01тАУ14, рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ box рд╕рд╛рдареА рддрд┐рд╕рд░рд╛ рдкреНрд░рд╢реНрди: рддреЗ рдЪрд╛рд▓рддреЗ рдЖрд╣реЗ рд╣реЗ рдЖрдкрд▓реНрдпрд╛рд▓рд╛ рдХрд╕реЗ рдХрд│рдгрд╛рд░? рддреБрдореНрд╣реА рд╢рд┐рдХрддрд╛ SLI, SLO рдЖрдгрд┐ SLA, error budgets (рдорд╣рд┐рдиреНрдпрд╛рд▓рд╛ 432 / 43.2 / 4.3 рдорд┐рдирд┐рдЯреЗ), RED рдЖрдгрд┐ USE, request ids рд╕рд╣ structured logs, metrics, traces, рдЖрдгрд┐ рддреБрдореНрд╣реА рдХрд╛рд░рдгрд╛рдВрд╡рд░ рдирд╛рд╣реА рддрд░ рд▓рдХреНрд╖рдгрд╛рдВрд╡рд░ alert рдХрд╛ рдХрд░рддрд╛.
- design/designs.py тАФ
error_budget(slo, days=30) - design/demo.py тАФ
python3 design/demo.py observability - design/test_design.py тАФ check L15
ЁЯзТ 5 рд╡рд░реНрд╖рд╛рдВрдЪреНрдпрд╛ рдореБрд▓рд╛рд▓рд╛ рд╕рдордЬрд╛рд╡рд▓реНрдпрд╛рд╕рд╛рд░рдЦреЗ
app рд╕реБрд░реВ рд╣реЛрдгреНрдпрд╛рдЖрдзреА рджреАрдкрд┐рдХрд╛ рдХрд╛рд░реНрдпрд╛рд▓рдпрд╛рд▓рд╛ рд╡рд┐рдЪрд╛рд░рддреЗ: "рдирд┐рд░реЛрдЧреА рдореНрд╣рдгрдЬреЗ рдХрд╛рдп?"
рдХрддрд░рд┐рдирд╛ рдореНрд╣рдгрддреЗ: "рдЬрд▓рдж." рджреАрдкрд┐рдХрд╛ рдореНрд╣рдгрддреЗ: "рдХрд┐рддреА рдЬрд▓рдж, рдХреЛрдгрд╛рд╕рд╛рдареА, рдХрд┐рддреА рд╡реЗрд│рд╛?" рдореНрд╣рдгреВрди рддреНрдпрд╛ рдПрдХ рд╡рд╛рдХреНрдп рд▓рд┐рд╣рд┐рддрд╛рдд: "30 рджрд┐рд╡рд╕рд╛рдВрдд рдореЛрдЬрд▓реЗ рддрд░, рдкреНрд░рддреНрдпреЗрдХ 1,000 рдкреИрдХреА 999 feed reads 200 ms рдкреЗрдХреНрд╖рд╛ рдХрдореА рд╡реЗрд│рд╛рдд рдмрд░реЛрдмрд░ рдЙрддреНрддрд░ рджреЗрддрд╛рдд."
рдордЧ рдРрд╢реНрд╡рд░реНрдпрд╛ рдЧрдгрд┐рдд рдХрд░рддреЗ. рд╣рдЬрд╛рд░рд╛рдд рдПрдХ рдЕрдкрдпрд╢реА рдард░реВ рд╢рдХрддреЛ. 30 рджрд┐рд╡рд╕рд╛рдВрдд рддреЗ 43.2 рдорд┐рдирд┐рдЯрд╛рдВрдЪрд╛ рддреНрд░рд╛рд╕ рд╣реЛрддреЛ. рд╣реАрдЪ рдореБрднрд╛ тАФ error budget. рдЬрд░ app рдиреЗ рдпрд╛ рдорд╣рд┐рдиреНрдпрд╛рдд рдлрдХреНрдд 10 рдорд┐рдирд┐рдЯреЗ рд╡рд╛рдкрд░рд▓реА, рддрд░ team рдзреЛрдХрд╛ рдкрддреНрдХрд░реВ рд╢рдХрддреЗ: рдирд╡реА features, рдореЛрдареЗ рдмрджрд▓. рдЬрд░ рдореБрднрд╛ рдЬрд╡рд│рдЬрд╡рд│ рд╕рдВрдкрд▓реА рдЕрд╕реЗрд▓, рддрд░ team рд╡реЗрдЧ рдХрдореА рдХрд░рддреЗ рдЖрдгрд┐ рдЖрдзреА рдЧреЛрд╖реНрдЯреА рджреБрд░реБрд╕реНрдд рдХрд░рддреЗ.
рд╢реЗрд╡рдЯреА рдХрд╛рд░реНрдпрд╛рд▓рдп рдард░рд╡рддреЗ рдХреЛрдгрд╛рд▓рд╛ рдХрдзреА рдЭреЛрдкреЗрддреВрди рдЙрдард╡рд╛рдпрдЪреЗ. server рдЪрд╛ CPU рдЬрд╛рд╕реНрдд рдЕрд╕рддрд╛рдирд╛ рдирд╛рд╣реА тАФ рдкрд╛рд▓рдХрд╛рдВрдирд╛ CPU рдЬрд╛рдгрд╡рдд рдирд╛рд╣реА. рдлрдХреНрдд рддреЗрд╡реНрд╣рд╛рдЪ рдЬреЗрд╡реНрд╣рд╛ рдкрд╛рд▓рдХрд╛рдВрдирд╛ рдЬрд╛рдгрд╡рддреЗ: errors рдХрд┐рдВрд╡рд╛ рд╣рд│реВ pages, рдЬреЗ рдореБрднрд╛ рдЦреВрдк рд╡реЗрдЧрд╛рдиреЗ рд╕рдВрдкрд╡рдд рдЖрд╣реЗрдд.
ЁЯЧ║я╕П рдЖрдХреГрддреА
flowchart LR
sli["ЁЯУП SLI<br/>good reads ├╖ all reads"] --> slo["ЁЯОп SLO 99.9% / 30 days"]
slo --> eb["тП│ error budget<br/>43.2 min per 30 days"]
eb --> alert["ЁЯЪи alert on burn rate<br/>symptoms, not CPU"]
subgraph sig["ЁЯУб three signals + one id"]
logs["ЁЯУЬ logs<br/>JSON + request_id"]
met["ЁЯУК metrics<br/>RED per API ┬╖ USE per resource"]
tr["ЁЯз╡ traces<br/>one request across services"]
end
sig --> sli
ЁЯЧ║я╕П рдХрд╛рдврд▓реЗрд▓реА рдЖрд╡реГрддреНрддреА + рдПрдХ lab: https://school-edh.pages.dev/system-design/lesson-diagrams.html#l15
тЭУ рдХрд╛рдп
- SLI (service level indicator) тАФ users рдирд╛ рдЬреЗ рдЬрд╛рдгрд╡рддреЗ рддреНрдпрд╛рд╡рд░реВрди рдореЛрдЬрд▓реЗрд▓рд╛ рдЖрдХрдбрд╛. рдмрд╣реБрдзрд╛ рдПрдХ рдЧреБрдгреЛрддреНрддрд░: рдЪрд╛рдВрдЧрд▓реНрдпрд╛ рдШрдЯрдирд╛ ├╖ рд╕рд░реНрд╡ рдШрдЯрдирд╛. "200 ms рдкреЗрдХреНрд╖рд╛ рдХрдореА рд╡реЗрд│рд╛рдд 2xx рдкрд░рдд рдХреЗрд▓реЗрд▓реЗ feed reads ├╖ рд╕рд░реНрд╡ feed reads."
- SLO (service level objective) тАФ рдПрдХрд╛ рдХрд╛рд▓рд╛рд╡рдзреАрд╕рд╛рдареА SLI рдЪреЗ рдЙрджреНрджрд┐рд╖реНрдЯ: "30 рджрд┐рд╡рд╕рд╛рдВрдд 99.9%". team рдиреЗ рдорд╛рдиреНрдп рдХреЗрд▓реЗрд▓реЗ рдПрдХ рдЕрдВрддрд░реНрдЧрдд рдзреНрдпреЗрдп.
- SLA (service level agreement) тАФ рджрдВрдбрд╛рд╕рд╣ (рдкреИрд╕реЗ рдкрд░рдд) рдЧреНрд░рд╛рд╣рдХрд╛рд▓рд╛ рджрд┐рд▓реЗрд▓реЗ рд╡рдЪрди. рдиреЗрд╣рдореА SLO рдкреЗрдХреНрд╖рд╛ рд╕реИрд▓, рдореНрд╣рдгрдЬреЗ рдХрд░рд╛рд░ рдореЛрдбрдгреНрдпрд╛рдЖрдзреАрдЪ team рд▓рд╛ рдЕрдбрдЪрдг рджрд┐рд╕рддреЗ.
- Error budget тАФ рдХрд╛рд▓рд╛рд╡рдзреАрдЪреНрдпрд╛ 1 тИТ SLO. 30 рджрд┐рд╡рд╕рд╛рдВрд╕рд╛рдареА: 99% тЖТ 432 min, 99.9% тЖТ 43.2 min, 99.99% тЖТ 4.3 min. рдкреНрд░рддреНрдпреЗрдХ рдЬрд╛рд╕реНрддреАрдЪрд╛ nine рдореНрд╣рдгрдЬреЗ рджрд╣рд╛ рдкрдЯ рдХрдореА рдЬрд╛рдЧрд╛. Budget рд╣реЗ рдирд┐рд░реНрдгрдпрд╛рдЪреЗ рд╕рд╛рдзрди рдЖрд╣реЗ: budget рд╢рд┐рд▓реНрд▓рдХ тЖТ ship рдХрд░рд╛; budget рд╕рдВрдкрд▓реЗ тЖТ рд╕реНрдерд┐рд░ рдХрд░рд╛.
- RED тАФ рдкреНрд░рддреНрдпреЗрдХ request-driven service рд╕рд╛рдареА: Rate (рд╕реЗрдХрдВрджрд╛рд▓рд╛ requests), Errors (рдЕрдкрдпрд╢реА requests), Duration (latency, percentiles рдордзреНрдпреЗ: p50, p99).
- USE тАФ рдкреНрд░рддреНрдпреЗрдХ resource рд╕рд╛рдареА (CPU, disk, connection pool, queue): Utilisation (рдХрд┐рддреА рд╡реНрдпрд╕реНрдд), Saturation (рдХрд┐рддреА рдерд╛рдВрдмрд▓реЗрд▓реЗ), Errors.
- Structured logs тАФ рдкреНрд░рддреНрдпреЗрдХ рдШрдЯрдиреЗрд╕рд╛рдареА рдард░рд▓реЗрд▓реНрдпрд╛ fields рд╕рд╣ рдПрдХ JSON рдУрд│, рдЖрдгрд┐ рдПрдХ request id рдЬреЛ рдкреНрд░рддреНрдпреЗрдХ service рдЖрдкрд▓реНрдпрд╛ logs рдордзреНрдпреЗ рдХреЙрдкреА рдХрд░рддреЗ рдЖрдгрд┐ рдкреБрдвреЗ рдкрд╛рдард╡рддреЗ. рдПрдХрд╛ id рдиреЗ рдкреВрд░реНрдг рдХрд╣рд╛рдгреА рд╕рд╛рдкрдбрддреЗ.
- Metrics тАФ рд╡реЗрд│реЗрдиреБрд╕рд╛рд░ рд╕реНрд╡рд╕реНрдд рдЖрдХрдбреЗ (counters, histograms). Dashboards рдЖрдгрд┐ alerts рд╕рд╛рдареА
рдЪрд╛рдВрдЧрд▓реЗ. Labels рд▓рд╣рд╛рди рдареЗрд╡рд╛:
route,statusтАФ рдХрдзреАрд╣реАparent_idрдирд╛рд╣реА. - Traces тАФ рдПрдХ request рдкреНрд░рддреНрдпреЗрдХ service рдордзреВрди, рд╡реЗрд│ рдореЛрдЬрд▓реЗрд▓реНрдпрд╛ spans рдЪреНрдпрд╛ рдЭрд╛рдбрд╛рд╕рд╛рд░рдЦреА рдкрд╛рд╣рд┐рд▓реА рдЬрд╛рддреЗ. 800 ms рдХреБрдареЗ рдЧреЗрд▓реЗ рддреЗ рддреНрдпрд╛ рджрд╛рдЦрд╡рддрд╛рдд. OpenTelemetry рд╣реЗ рд╕рд╛рдорд╛рдиреНрдп standard рдЖрд╣реЗ.
- рд▓рдХреНрд╖рдгрд╛рдВрд╡рд░ alert тАФ users рдирд╛ рддреНрд░рд╛рд╕ рд╣реЛрддреЛ рддреЗрд╡реНрд╣рд╛ рдорд╛рдгрд╕рд╛рд▓рд╛ page рдХрд░рд╛: SLO рдЪреЗ budget рд╡реЗрдЧрд╛рдиреЗ рдЬрд│рддреЗ. рдХрд╛рд░рдгреЗ (рдЬрд╛рд╕реНрдд CPU, рд▓рд╡рдХрд░рдЪ рднрд░рдгрд╛рд░рд╛ disk) рд╣реА tickets рдХрд┐рдВрд╡рд╛ dashboard рд╡рд░рдЪреНрдпрд╛ рдЧреЛрд╖реНрдЯреА, pages рдирд╛рд╣реАрдд. Burn-rate alert рд╡рд┐рдЪрд╛рд░рддреЛ: "рдпрд╛ рд╡реЗрдЧрд╛рдиреЗ budget рдХрдзреА рд╕рдВрдкреЗрд▓?"
ЁЯдФ рдХрд╛
рдХрд╛рд░рдг "рддреЗ рдЪрд╛рд▓рддреЗ рдЖрд╣реЗ рдХрд╛?" рдпрд╛рдЪреА рд╡реНрдпрд╛рдЦреНрдпрд╛ launch рдЪреНрдпрд╛ рдЖрдзреА рд╣рд╡реА, рдирд╛рд╣реАрддрд░ рдкреНрд░рддреНрдпреЗрдХ incident рд╡рд╛рджрд╛рдиреЗ рд╕реБрд░реВ рд╣реЛрддреЛ. SLO рдзрдбреЗ 10тАУ13 рд▓рд╛ рдЖрдХрдбреНрдпрд╛рдВрддрд╣реА рдмрджрд▓рддреЗ: рд░рдЪрдиреЗрд▓рд╛ рдХрд┐рддреА nines рд╣рд╡реЗрдд рддреНрдпрд╛рд╡рд░реВрди рдХрд┐рддреА рдкреНрд░рддреА, zones рдЖрдгрд┐ fallbacks рд▓рд╛рдЧрддреАрд▓ рддреЗ рдард░рддреЗ. рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ log рдУрд│реАрдд request id рдирд╕реЗрд▓, рддрд░ рдХрд╛рд░реНрдпрд╛рд▓рдп рдПрдХрд╛ рдкрд╛рд▓рдХрд╛рдЪреА рдЕрдкрдпрд╢реА request gateway, API, queue рдЖрдгрд┐ SMS worker рдордзреВрди рд╢реЛрдзреВ рд╢рдХрдд рдирд╛рд╣реА.
ЁЯФз рдХрд╕реЗ (рдпрд╛ repo рдордзреНрдпреЗ)
design/designs.py рдордзрд▓реЗ error_budget(slo, days=30)
(1 тИТ slo) ├Ч days ├Ч 24 ├Ч 60 рдорд┐рдирд┐рдЯреЗ рдкрд░рдд рдХрд░рддреЗ, рдПрдХрд╛ рджрд╢рд╛рдВрд╢рд╛рдкрд░реНрдпрдВрдд round рдХреЗрд▓реЗрд▓реА. design/demo.py
рдордзрд▓реЗ observability() рддреАрди SLOs рдЫрд╛рдкрддреЗ. snippet рдПрдХ рдЖрдард╡рдбрд╛ рдЖрдгрд┐ рдПрдХ рд╡рд░реНрд╖ рдЕрд╕реЗ рдХрд╛рд▓рд╛рд╡рдзреА рдЬреЛрдбрддреЛ, рдЖрдгрд┐
рдПрдХрд╛ рдорд╣рд┐рдиреНрдпрд╛рдЪреНрдпрд╛ рд╡рд╛рдИрдЯ reads рдиреЗ budget рдЪрд╛ рдХрд┐рддреА рднрд╛рдЧ рд╡рд╛рдкрд░рд▓рд╛ рддреЗ рдореЛрдЬрддреЛ.
ЁЯзк рдХрд░реВрди рдкрд╛рд╣рд╛
python3 design/demo.py observability
python3 - <<'EOF'
import sys; sys.path.insert(0, "design"); from designs import error_budget
for slo in (0.99, 0.995, 0.999, 0.9995, 0.9999):
print(f"SLO {slo:.2%} тЖТ {error_budget(slo):>6} min / 30 days ┬╖ {error_budget(slo, 7):>5} min / week ┬╖ {error_budget(slo, 365):>7} min / year")
good, total = 99_950_000, 100_000_000 # a month of feed reads
slo = 0.999; allowed_bad = total * (1 - slo); bad = total - good
print(f"SLI {good / total:.3%} ┬╖ allowed bad {allowed_bad:,.0f} ┬╖ bad so far {bad:,} тЖТ {bad / allowed_bad:.0%} of the budget spent")
EOF
тЬЕ рддрдкрд╛рд╕рд╛ тАФ рддреБрдореНрд╣рд╛рд▓рд╛ рдХрд╛рдп рджрд┐рд╕рд╛рдпрд▓рд╛ рд╣рд╡реЗ
observability рд╣реЗ рдЫрд╛рдкрддреЗ:
тФАтФА decide what 'healthy' means BEFORE launch
SLO 99.00% тЖТ error budget 432.0 minutes per 30 days
SLO 99.90% тЖТ error budget 43.2 minutes per 30 days
SLO 99.99% тЖТ error budget 4.3 minutes per 30 days
RED per API (Rate, Errors, Duration) ┬╖ USE per resource (Utilisation, Saturation, Errors)
logs with a request id ┬╖ metrics for alerts ┬╖ traces across services ┬╖ alert on the SLO, not on CPU
рддреБрдордЪрд╛ snippet рд╣реЗ рдЫрд╛рдкрддреЛ:
SLO 99.00% тЖТ 432.0 min / 30 days ┬╖ 100.8 min / week ┬╖ 5256.0 min / year
SLO 99.50% тЖТ 216.0 min / 30 days ┬╖ 50.4 min / week ┬╖ 2628.0 min / year
SLO 99.90% тЖТ 43.2 min / 30 days ┬╖ 10.1 min / week ┬╖ 525.6 min / year
SLO 99.95% тЖТ 21.6 min / 30 days ┬╖ 5.0 min / week ┬╖ 262.8 min / year
SLO 99.99% тЖТ 4.3 min / 30 days ┬╖ 1.0 min / week ┬╖ 52.6 min / year
SLI 99.950% ┬╖ allowed bad 100,000 ┬╖ bad so far 50,000 тЖТ 50% of the budget spent
Tests рдордзреНрдпреЗ тЬЕ L15 a 99.9% SLO allows 43.2 minutes a month рдЖрд╣реЗ.
ЁЯПБ рддреБрдореНрд╣реА рдЖрддреНрддрд╛рдЪ рдХрд╛рдп рд╕рд┐рджреНрдз рдХреЗрд▓реЗ
рдкреНрд░рддреНрдпреЗрдХ рдЬрд╛рд╕реНрддреАрдЪрд╛ nine рдЬрд╛рдЧрд╛ рджрд╣рд╛рдиреЗ рднрд╛рдЧрддреЛ: рдорд╣рд┐рдиреНрдпрд╛рд▓рд╛ 432 тЖТ 43.2 тЖТ 4.3 рдорд┐рдирд┐рдЯреЗ. 99.99% рд╡рд░ team рдХрдбреЗ рдЖрдард╡рдбреНрдпрд╛рд▓рд╛ рд╕рд╛рдзрд╛рд░рдг рдПрдХ рдорд┐рдирд┐рдЯ рдЕрд╕рддреЛ тАФ рдЪреБрдХрд▓реЗрд▓реНрдпрд╛ рдПрдХрд╛ deploy рдкреЗрдХреНрд╖рд╛рд╣реА рдХрдореА. рдореНрд╣рдгреВрдирдЪ SLO рдЧрд░рдЬреЗрд╢реА рдЬреБрд│рд╛рдпрд▓рд╛ рд╣рд╡реЗ (рд╕реВрдЪрдирд╛ рдлрд▓рдХрд╛рд╕рд╛рдареА 99.9% рдкреБрд░реЗрд╕реЗ), рдЗрдЪреНрдЫреЗрд╢реА рдирд╛рд╣реА. рдЖрдгрд┐ budget рдореЛрдЬрд▓реЗ рдЬрд╛рддреЗ, рдЕрдВрджрд╛рдЬрд╛рдиреЗ рдард░рдд рдирд╛рд╣реА: 100 million рдкреИрдХреА 50,000 рд╡рд╛рдИрдЯ reads рдореНрд╣рдгрдЬреЗ 99.95% SLI тАФ рдпрд╛ рдорд╣рд┐рдиреНрдпрд╛рдЪреЗ рдЕрд░реНрдзреЗ budget рдЦрд░реНрдЪ рдЭрд╛рд▓реЗ.
тЪая╕П рдиреЗрд╣рдореАрдЪреНрдпрд╛ рдЪреБрдХрд╛
- 100% рдЪреЗ SLO тАФ рдХрд╛рд╣реАрд╣реА рдмрджрд▓рд╛рдпрд▓рд╛ рдХрдзреАрдЪ рдЬрд╛рдЧрд╛ рдирд╛рд╣реА
- рдЖрд░реЛрдЧреНрдп user рдХрдбреЗ ("read 200 ms рдордзреНрдпреЗ рдпрд╢рд╕реНрд╡реА рдЭрд╛рд▓рд╛") рдореЛрдЬрдгреНрдпрд╛рдРрд╡рдЬреА server рд╡рд░ ("process рдЪрд╛рд▓реВ рдЖрд╣реЗ") рдореЛрдЬрдгреЗ
- percentiles рдРрд╡рдЬреА рд╕рд░рд╛рд╕рд░реА тАФ рд╕рд░рд╛рд╕рд░реА рд╣рд│реВ 1% рд▓рдкрд╡рддреЗ
- CPU, memory рдЖрдгрд┐ disk рд╡рд░рдЪреЗ alerts рдЬреЗ рд░рд╛рддреНрд░реА рд▓реЛрдХрд╛рдВрдирд╛ рдЙрдард╡рддрд╛рдд рдкрдг рдкрд╛рд▓рдХрд╛рдВрдирд╛ рдХрд╛рд╣реАрдЪ рдЬрд╛рдгрд╡рдд рдирд╛рд╣реА
- request id рд╢рд┐рд╡рд╛рдп рдореЛрдХрд│реНрдпрд╛ рдордЬрдХреБрд░рд╛рддрд▓реЗ logs тАФ рдПрдХ request services рдордзреВрди рд╢реЛрдзрддрд╛ рдпреЗрдд рдирд╛рд╣реА
- metric label рдореНрд╣рдгреВрди
parent_idтАФ рд▓рд╛рдЦреЛ time series рдЖрдгрд┐ рдореЛрдареЗ рдмрд┐рд▓ - SLO рдЗрддрдХреЗрдЪ SLA тАФ рдкрд╣рд┐рд▓реЗ рдЪреБрдХрд▓реЗрд▓реЗ рдЙрджреНрджрд┐рд╖реНрдЯ рд▓рдЧреЗрдЪ рджрдВрдб рдард░рддреЗ
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд
рдЦрд▒реНрдпрд╛ account рд╡рд░ тАФ рдкреНрд░рддреНрдпреЗрдХ request рд╕рд╛рдареА рдПрдХ structured log рдУрд│ (рдкреНрд░рддреНрдпреЗрдХ service рд▓рд╛ рдорд┐рд│рд╛рд▓реЗрд▓рд╛
request_id рдХреЙрдкреА рдХрд░рддреЗ, рдХрд┐рдВрд╡рд╛ edge рд╡рд░ рдПрдХ рддрдпрд╛рд░ рдХрд░рддреЗ):
{"ts":"2026-09-27T09:00:01.234Z","level":"info","service":"notice-api","request_id":"req-7f3a9c",
"route":"GET /parents/me/feed","status":200,"duration_ms":84,"cache":"hit"}
99.9% feed SLO рд╕рд╛рдареА Prometheus burn-rate alert. рдПрдХрд╛ рддрд╛рд╕рд╛рд╕рд╛рдареА 14.4 рдЪрд╛ burn rate 30 рджрд┐рд╡рд╕рд╛рдВрдЪреНрдпрд╛ budget рдЪреЗ 2% рдЦрд░реНрдЪ рдХрд░рддреЛ; рд▓рд╣рд╛рди window рдкрдг рддрдкрд╛рд╕рд▓реНрдпрд╛рдиреЗ рдЕрдбрдЪрдг рдерд╛рдВрдмрд▓реНрдпрд╛рд╡рд░ alert рд▓рд╡рдХрд░ рдерд╛рдВрдмрддреЛ:
groups:
- name: feed-slo
rules:
- record: feed:error_ratio:rate1h
expr: sum(rate(http_requests_total{route="/parents/me/feed",code=~"5.."}[1h]))
/ sum(rate(http_requests_total{route="/parents/me/feed"}[1h]))
- record: feed:error_ratio:rate5m
expr: sum(rate(http_requests_total{route="/parents/me/feed",code=~"5.."}[5m]))
/ sum(rate(http_requests_total{route="/parents/me/feed"}[5m]))
- alert: FeedErrorBudgetBurn
expr: feed:error_ratio:rate1h > (14.4 * 0.001) and feed:error_ratio:rate5m > (14.4 * 0.001)
for: 2m
labels: { severity: page }
OpenTelemetry рд╕рд╣ traces тАФ API automatic instrumentation рд╕рд╣ рд╕реБрд░реВ рдХрд░рд╛ рдЖрдгрд┐ spans рдПрдХрд╛ collector рдХрдбреЗ рдкрд╛рдард╡рд╛:
pip install opentelemetry-distro opentelemetry-exporter-otlp
opentelemetry-bootstrap -a install
OTEL_SERVICE_NAME=notice-api OTEL_EXPORTER_OTLP_ENDPOINT=http://otel-collector:4317 \
opentelemetry-instrument python app.py
ЁЯПн рдкреНрд░рддреНрдпрдХреНрд╖ рд╡рд╛рдкрд░рд╛рдд рд╣реЗ рдХрд╛ рдорд╣рддреНрддреНрд╡рд╛рдЪреЗ: рдкреНрд░рддреНрдпреЗрдХ рд░рдЪрдиреЗрдд рдПрдХ "observability" рд╡рд┐рднрд╛рдЧ рдЬреЛрдбрд╛: SLIs, SLO рдЖрдгрд┐ рддреНрдпрд╛рдЪреЗ budget, RED рдЖрдгрд┐ USE dashboards, рдЖрдгрд┐ рдорд╛рдгрд╕рд╛рд▓рд╛ рдЙрдард╡реВ рд╢рдХрдгрд╛рд░реЗ рджреЛрди-рддреАрди alerts. рдмрд╛рдХреА рд╕рдЧрд│реЗ dashboard рдХрд┐рдВрд╡рд╛ ticket.
тПня╕П рдкреБрдвреЗ
рдпреЛрдЬрдирд╛ рдмрд░реЛрдмрд░, рд╕реБрд░рдХреНрд╖рд┐рдд рдЖрдгрд┐ рдореЛрдЬрд▓реЗрд▓реА рдЖрд╣реЗ. рд╢рд╛рд│реЗрд▓рд╛ рддреА рдкрд░рд╡рдбреЗрд▓ рдХрд╛? рдЖрдгрд┐ рдкреНрд░рддреНрдпреЗрдХ box рдХрд╛ рдЖрд╣реЗ рд╣реЗ рдХреЛрдгрд╛рд▓рд╛ рд▓рдХреНрд╖рд╛рдд рд░рд╛рд╣реАрд▓ рдХрд╛? Cost, trade-offs рдЖрдгрд┐ ADRs.
git checkout lesson-16-cost-and-adrs