[{"data":1,"prerenderedAt":2131},["ShallowReactive",2],{"content:\u002F11-observability\u002F04-sli-slo-alerting":3},{"title":4,"description":5,"path":6,"body":7},"SLI, SLO и alerting без шума","Alert - это просьба отвлечь человека. Иногда разбудить. Поэтому alert должен быть привязан к пользовательскому impact и понятному действию, а не к любому красному графику.","\u002F11-observability\u002F04-sli-slo-alerting",{"type":8,"value":9,"toc":2116},"minimark",[10,14,17,20,25,94,97,108,111,115,188,191,195,198,204,207,213,216,219,232,236,239,500,503,761,775,779,789,795,798,804,814,817,834,838,845,848,870,873,987,990,994,997,1037,1040,1049,1052,1056,1059,1062,1068,1071,1080,1082,1163,1166,1170,1173,1200,1203,1209,1212,1215,1395,1398,1418,1421,1424,1427,1465,1469,1472,1578,1581,1655,1659,1662,1695,1698,1717,1720,1724,1757,1937,2112],[11,12,4],"h1",{"id":13},"sli-slo-и-alerting-без-шума",[15,16,5],"p",{},[15,18,19],{},"Большая ошибка начинающих команд: алертить на все подряд. CPU 85%, Redis latency дернулась, Kafka lag чуть вырос, GC стал чаще, один pod перезапустился. Через неделю все привыкают игнорировать уведомления. Это называется alert fatigue: сигнал вроде есть, но доверия к нему нет.",[21,22,24],"h2",{"id":23},"термины","Термины",[26,27,28,42],"table",{},[29,30,31],"thead",{},[32,33,34,39],"tr",{},[35,36,38],"th",{"align":37},"left","Термин",[35,40,41],{"align":37},"Смысл",[43,44,45,54,62,70,78,86],"tbody",{},[32,46,47,51],{},[48,49,50],"td",{"align":37},"SLI",[48,52,53],{"align":37},"Число, которое измеряет качество сервиса.",[32,55,56,59],{},[48,57,58],{"align":37},"SLO",[48,60,61],{"align":37},"Цель по SLI за окно времени.",[32,63,64,67],{},[48,65,66],{"align":37},"Error budget",[48,68,69],{"align":37},"Сколько \"плохого\" поведения допустимо до нарушения SLO.",[32,71,72,75],{},[48,73,74],{"align":37},"Burn rate",[48,76,77],{"align":37},"Во сколько раз быстрее нормы расходуется error budget.",[32,79,80,83],{},[48,81,82],{"align":37},"Alert",[48,84,85],{"align":37},"Сигнал, что нужен action.",[32,87,88,91],{},[48,89,90],{"align":37},"Runbook",[48,92,93],{"align":37},"Инструкция, что проверить и как действовать.",[15,95,96],{},"Пример:",[98,99,105],"pre",{"className":100,"code":102,"language":103,"meta":104},[101],"language-text","SLI: доля \u002Fconvert requests без 5xx\nSLO: 99.9% успешных requests за 30 дней\nError budget: 0.1% requests могут быть плохими\n","text","",[106,107,102],"code",{"__ignoreMap":104},[15,109,110],{},"Если за 30 дней пришел 1 000 000 requests, error budget = 1 000 плохих requests.",[21,112,114],{"id":113},"хорошие-sli-для-ratedesk","Хорошие SLI для RateDesk",[26,116,117,129],{},[29,118,119],{},[32,120,121,123,126],{},[35,122,50],{"align":37},[35,124,125],{"align":37},"Формула",[35,127,128],{"align":37},"Почему важно",[43,130,131,144,155,166,177],{},[32,132,133,136,141],{},[48,134,135],{"align":37},"Availability",[48,137,138],{"align":37},[106,139,140],{},"1 - 5xx \u002F total",[48,142,143],{"align":37},"Пользователь может выполнить conversion.",[32,145,146,149,152],{},[48,147,148],{"align":37},"Latency",[48,150,151],{"align":37},"доля requests быстрее 300ms",[48,153,154],{"align":37},"Сервис не просто отвечает, а отвечает вовремя.",[32,156,157,160,163],{},[48,158,159],{"align":37},"Freshness",[48,161,162],{"align":37},"возраст последнего курса меньше N минут",[48,164,165],{"align":37},"Ответы основаны на свежих данных.",[32,167,168,171,174],{},[48,169,170],{"align":37},"Dependency correctness proxy",[48,172,173],{"align":37},"доля dependency failures",[48,175,176],{"align":37},"Видно, что ломается инфраструктурная часть.",[32,178,179,182,185],{},[48,180,181],{"align":37},"Consumer freshness",[48,183,184],{"align":37},"lag\u002Fage обработанных событий",[48,186,187],{"align":37},"Система не отстает от входящего потока.",[15,189,190],{},"Важно: 4xx и доменные ошибки не всегда портят availability. Если пользователь отправил невалидный запрос, это не production outage. А вот timeout PostgreSQL или provider API - уже системная проблема.",[21,192,194],{"id":193},"symptom-alerts-вместо-cause-alerts","Symptom alerts вместо cause alerts",[15,196,197],{},"Cause-based alert:",[98,199,202],{"className":200,"code":201,"language":103,"meta":104},[101],"CPU > 85%\n",[106,203,201],{"__ignoreMap":104},[15,205,206],{},"Symptom-based alert:",[98,208,211],{"className":209,"code":210,"language":103,"meta":104},[101],"\u002Fconvert 5xx ratio > 2% for 10m\n",[106,212,210],{"__ignoreMap":104},[15,214,215],{},"CPU может быть высоким и без user impact. А 5xx ratio прямо говорит: часть операций не выполняется. Cause-графики нужны на dashboard, но page-алерты лучше строить по симптомам.",[15,217,218],{},"Хороший компромисс:",[220,221,222,226,229],"ul",{},[223,224,225],"li",{},"page: высокий user impact, быстрый burn rate, сервисная деградация;",[223,227,228],{},"ticket: медленная деградация, capacity risk, noisy dependency;",[223,230,231],{},"dashboard only: диагностические причины.",[21,233,235],{"id":234},"availability-slo","Availability SLO",[15,237,238],{},"Recording rules:",[98,240,244],{"className":241,"code":242,"language":243,"meta":104,"style":104},"language-yaml shiki shiki-themes github-dark","groups:\n  - name: ratedesk:sli\n    interval: 30s\n    rules:\n      - record: job:http_requests:rate5m\n        expr: |\n          sum by (job) (rate(http_requests_total[5m]))\n\n      - record: job:http_errors:ratio_rate5m\n        expr: |\n          sum by (job) (rate(http_requests_total{code=~\"5..\"}[5m]))\n          \u002F\n          sum by (job) (rate(http_requests_total[5m]))\n\n      - record: job:http_errors:ratio_rate30m\n        expr: |\n          sum by (job) (rate(http_requests_total{code=~\"5..\"}[30m]))\n          \u002F\n          sum by (job) (rate(http_requests_total[30m]))\n\n      - record: job:http_errors:ratio_rate1h\n        expr: |\n          sum by (job) (rate(http_requests_total{code=~\"5..\"}[1h]))\n          \u002F\n          sum by (job) (rate(http_requests_total[1h]))\n\n      - record: job:http_errors:ratio_rate6h\n        expr: |\n          sum by (job) (rate(http_requests_total{code=~\"5..\"}[6h]))\n          \u002F\n          sum by (job) (rate(http_requests_total[6h]))\n","yaml",[106,245,246,259,275,286,294,308,320,326,333,345,354,360,366,371,376,388,397,403,408,414,419,431,440,446,451,457,462,474,483,489,494],{"__ignoreMap":104},[247,248,251,255],"span",{"class":249,"line":250},"line",1,[247,252,254],{"class":253},"s4JwU","groups",[247,256,258],{"class":257},"s95oV",":\n",[247,260,262,265,268,271],{"class":249,"line":261},2,[247,263,264],{"class":257},"  - ",[247,266,267],{"class":253},"name",[247,269,270],{"class":257},": ",[247,272,274],{"class":273},"sU2Wk","ratedesk:sli\n",[247,276,278,281,283],{"class":249,"line":277},3,[247,279,280],{"class":253},"    interval",[247,282,270],{"class":257},[247,284,285],{"class":273},"30s\n",[247,287,289,292],{"class":249,"line":288},4,[247,290,291],{"class":253},"    rules",[247,293,258],{"class":257},[247,295,297,300,303,305],{"class":249,"line":296},5,[247,298,299],{"class":257},"      - ",[247,301,302],{"class":253},"record",[247,304,270],{"class":257},[247,306,307],{"class":273},"job:http_requests:rate5m\n",[247,309,311,314,316],{"class":249,"line":310},6,[247,312,313],{"class":253},"        expr",[247,315,270],{"class":257},[247,317,319],{"class":318},"snl16","|\n",[247,321,323],{"class":249,"line":322},7,[247,324,325],{"class":273},"          sum by (job) (rate(http_requests_total[5m]))\n",[247,327,329],{"class":249,"line":328},8,[247,330,332],{"emptyLinePlaceholder":331},true,"\n",[247,334,336,338,340,342],{"class":249,"line":335},9,[247,337,299],{"class":257},[247,339,302],{"class":253},[247,341,270],{"class":257},[247,343,344],{"class":273},"job:http_errors:ratio_rate5m\n",[247,346,348,350,352],{"class":249,"line":347},10,[247,349,313],{"class":253},[247,351,270],{"class":257},[247,353,319],{"class":318},[247,355,357],{"class":249,"line":356},11,[247,358,359],{"class":273},"          sum by (job) (rate(http_requests_total{code=~\"5..\"}[5m]))\n",[247,361,363],{"class":249,"line":362},12,[247,364,365],{"class":273},"          \u002F\n",[247,367,369],{"class":249,"line":368},13,[247,370,325],{"class":273},[247,372,374],{"class":249,"line":373},14,[247,375,332],{"emptyLinePlaceholder":331},[247,377,379,381,383,385],{"class":249,"line":378},15,[247,380,299],{"class":257},[247,382,302],{"class":253},[247,384,270],{"class":257},[247,386,387],{"class":273},"job:http_errors:ratio_rate30m\n",[247,389,391,393,395],{"class":249,"line":390},16,[247,392,313],{"class":253},[247,394,270],{"class":257},[247,396,319],{"class":318},[247,398,400],{"class":249,"line":399},17,[247,401,402],{"class":273},"          sum by (job) (rate(http_requests_total{code=~\"5..\"}[30m]))\n",[247,404,406],{"class":249,"line":405},18,[247,407,365],{"class":273},[247,409,411],{"class":249,"line":410},19,[247,412,413],{"class":273},"          sum by (job) (rate(http_requests_total[30m]))\n",[247,415,417],{"class":249,"line":416},20,[247,418,332],{"emptyLinePlaceholder":331},[247,420,422,424,426,428],{"class":249,"line":421},21,[247,423,299],{"class":257},[247,425,302],{"class":253},[247,427,270],{"class":257},[247,429,430],{"class":273},"job:http_errors:ratio_rate1h\n",[247,432,434,436,438],{"class":249,"line":433},22,[247,435,313],{"class":253},[247,437,270],{"class":257},[247,439,319],{"class":318},[247,441,443],{"class":249,"line":442},23,[247,444,445],{"class":273},"          sum by (job) (rate(http_requests_total{code=~\"5..\"}[1h]))\n",[247,447,449],{"class":249,"line":448},24,[247,450,365],{"class":273},[247,452,454],{"class":249,"line":453},25,[247,455,456],{"class":273},"          sum by (job) (rate(http_requests_total[1h]))\n",[247,458,460],{"class":249,"line":459},26,[247,461,332],{"emptyLinePlaceholder":331},[247,463,465,467,469,471],{"class":249,"line":464},27,[247,466,299],{"class":257},[247,468,302],{"class":253},[247,470,270],{"class":257},[247,472,473],{"class":273},"job:http_errors:ratio_rate6h\n",[247,475,477,479,481],{"class":249,"line":476},28,[247,478,313],{"class":253},[247,480,270],{"class":257},[247,482,319],{"class":318},[247,484,486],{"class":249,"line":485},29,[247,487,488],{"class":273},"          sum by (job) (rate(http_requests_total{code=~\"5..\"}[6h]))\n",[247,490,492],{"class":249,"line":491},30,[247,493,365],{"class":273},[247,495,497],{"class":249,"line":496},31,[247,498,499],{"class":273},"          sum by (job) (rate(http_requests_total[6h]))\n",[15,501,502],{},"Burn-rate alert для SLO 99.9%:",[98,504,506],{"className":241,"code":505,"language":243,"meta":104,"style":104},"groups:\n  - name: ratedesk:slo-alerts\n    rules:\n      - alert: RatedeskAvailabilityFastBurn\n        expr: |\n          (\n            job:http_errors:ratio_rate5m{job=\"ratedesk\"} > (14.4 * 0.001)\n          )\n          and\n          (\n            job:http_errors:ratio_rate1h{job=\"ratedesk\"} > (14.4 * 0.001)\n          )\n        for: 2m\n        labels:\n          severity: page\n          slo: availability\n        annotations:\n          summary: \"RateDesk burns availability budget too fast\"\n          runbook_url: \"https:\u002F\u002Fgitlab.example.com\u002Fratedesk\u002Fdocs\u002Frunbooks\u002Fhigh-5xx\"\n\n      - alert: RatedeskAvailabilitySlowBurn\n        expr: |\n          (\n            job:http_errors:ratio_rate30m{job=\"ratedesk\"} > (6 * 0.001)\n          )\n          and\n          (\n            job:http_errors:ratio_rate6h{job=\"ratedesk\"} > (6 * 0.001)\n          )\n        for: 15m\n        labels:\n          severity: ticket\n          slo: availability\n        annotations:\n          summary: \"RateDesk availability budget drains over hours\"\n          runbook_url: \"https:\u002F\u002Fgitlab.example.com\u002Fratedesk\u002Fdocs\u002Frunbooks\u002Fhigh-5xx\"\n",[106,507,508,514,525,531,543,551,556,561,566,571,575,580,584,594,601,611,621,628,638,648,652,663,671,675,680,684,688,692,697,701,710,716,726,735,742,752],{"__ignoreMap":104},[247,509,510,512],{"class":249,"line":250},[247,511,254],{"class":253},[247,513,258],{"class":257},[247,515,516,518,520,522],{"class":249,"line":261},[247,517,264],{"class":257},[247,519,267],{"class":253},[247,521,270],{"class":257},[247,523,524],{"class":273},"ratedesk:slo-alerts\n",[247,526,527,529],{"class":249,"line":277},[247,528,291],{"class":253},[247,530,258],{"class":257},[247,532,533,535,538,540],{"class":249,"line":288},[247,534,299],{"class":257},[247,536,537],{"class":253},"alert",[247,539,270],{"class":257},[247,541,542],{"class":273},"RatedeskAvailabilityFastBurn\n",[247,544,545,547,549],{"class":249,"line":296},[247,546,313],{"class":253},[247,548,270],{"class":257},[247,550,319],{"class":318},[247,552,553],{"class":249,"line":310},[247,554,555],{"class":273},"          (\n",[247,557,558],{"class":249,"line":322},[247,559,560],{"class":273},"            job:http_errors:ratio_rate5m{job=\"ratedesk\"} > (14.4 * 0.001)\n",[247,562,563],{"class":249,"line":328},[247,564,565],{"class":273},"          )\n",[247,567,568],{"class":249,"line":335},[247,569,570],{"class":273},"          and\n",[247,572,573],{"class":249,"line":347},[247,574,555],{"class":273},[247,576,577],{"class":249,"line":356},[247,578,579],{"class":273},"            job:http_errors:ratio_rate1h{job=\"ratedesk\"} > (14.4 * 0.001)\n",[247,581,582],{"class":249,"line":362},[247,583,565],{"class":273},[247,585,586,589,591],{"class":249,"line":368},[247,587,588],{"class":253},"        for",[247,590,270],{"class":257},[247,592,593],{"class":273},"2m\n",[247,595,596,599],{"class":249,"line":373},[247,597,598],{"class":253},"        labels",[247,600,258],{"class":257},[247,602,603,606,608],{"class":249,"line":378},[247,604,605],{"class":253},"          severity",[247,607,270],{"class":257},[247,609,610],{"class":273},"page\n",[247,612,613,616,618],{"class":249,"line":390},[247,614,615],{"class":253},"          slo",[247,617,270],{"class":257},[247,619,620],{"class":273},"availability\n",[247,622,623,626],{"class":249,"line":399},[247,624,625],{"class":253},"        annotations",[247,627,258],{"class":257},[247,629,630,633,635],{"class":249,"line":405},[247,631,632],{"class":253},"          summary",[247,634,270],{"class":257},[247,636,637],{"class":273},"\"RateDesk burns availability budget too fast\"\n",[247,639,640,643,645],{"class":249,"line":410},[247,641,642],{"class":253},"          runbook_url",[247,644,270],{"class":257},[247,646,647],{"class":273},"\"https:\u002F\u002Fgitlab.example.com\u002Fratedesk\u002Fdocs\u002Frunbooks\u002Fhigh-5xx\"\n",[247,649,650],{"class":249,"line":416},[247,651,332],{"emptyLinePlaceholder":331},[247,653,654,656,658,660],{"class":249,"line":421},[247,655,299],{"class":257},[247,657,537],{"class":253},[247,659,270],{"class":257},[247,661,662],{"class":273},"RatedeskAvailabilitySlowBurn\n",[247,664,665,667,669],{"class":249,"line":433},[247,666,313],{"class":253},[247,668,270],{"class":257},[247,670,319],{"class":318},[247,672,673],{"class":249,"line":442},[247,674,555],{"class":273},[247,676,677],{"class":249,"line":448},[247,678,679],{"class":273},"            job:http_errors:ratio_rate30m{job=\"ratedesk\"} > (6 * 0.001)\n",[247,681,682],{"class":249,"line":453},[247,683,565],{"class":273},[247,685,686],{"class":249,"line":459},[247,687,570],{"class":273},[247,689,690],{"class":249,"line":464},[247,691,555],{"class":273},[247,693,694],{"class":249,"line":476},[247,695,696],{"class":273},"            job:http_errors:ratio_rate6h{job=\"ratedesk\"} > (6 * 0.001)\n",[247,698,699],{"class":249,"line":485},[247,700,565],{"class":273},[247,702,703,705,707],{"class":249,"line":491},[247,704,588],{"class":253},[247,706,270],{"class":257},[247,708,709],{"class":273},"15m\n",[247,711,712,714],{"class":249,"line":496},[247,713,598],{"class":253},[247,715,258],{"class":257},[247,717,719,721,723],{"class":249,"line":718},32,[247,720,605],{"class":253},[247,722,270],{"class":257},[247,724,725],{"class":273},"ticket\n",[247,727,729,731,733],{"class":249,"line":728},33,[247,730,615],{"class":253},[247,732,270],{"class":257},[247,734,620],{"class":273},[247,736,738,740],{"class":249,"line":737},34,[247,739,625],{"class":253},[247,741,258],{"class":257},[247,743,745,747,749],{"class":249,"line":744},35,[247,746,632],{"class":253},[247,748,270],{"class":257},[247,750,751],{"class":273},"\"RateDesk availability budget drains over hours\"\n",[247,753,755,757,759],{"class":249,"line":754},36,[247,756,642],{"class":253},[247,758,270],{"class":257},[247,760,647],{"class":273},[15,762,763,764,767,768,767,771,774],{},"Числа ",[106,765,766],{},"14.4",", ",[106,769,770],{},"6",[106,772,773],{},"0.001"," не магия, а SLO-математика. В уроке важно проговорить: burn rate - это кратность превышения допустимого уровня ошибок, а не \"проценты в минуту\".",[21,776,778],{"id":777},"откуда-берутся-burn-rate-числа","Откуда берутся burn-rate числа",[15,780,781,782,785,786,788],{},"Для SLO 99.9% error budget равен ",[106,783,784],{},"0.1%",", то есть ",[106,787,773],{}," плохих событий от общего числа.",[98,790,793],{"className":791,"code":792,"language":103,"meta":104},[101],"burn rate = observed error ratio \u002F allowed error ratio\nallowed error ratio = 1 - SLO\n",[106,794,792],{"__ignoreMap":104},[15,796,797],{},"Для 99.9%:",[98,799,802],{"className":800,"code":801,"language":103,"meta":104},[101],"allowed error ratio = 0.001\nerror ratio 1.44% = 0.0144\nburn rate = 0.0144 \u002F 0.001 = 14.4\n",[106,803,801],{"__ignoreMap":104},[15,805,806,809,810,813],{},[106,807,808],{},"14.4x"," означает: бюджет тратится в 14.4 раза быстрее нормы. Если так продолжать час, команда быстро потеряет заметную часть месячного бюджета, поэтому это page. ",[106,811,812],{},"6x"," на более длинных окнах - медленнее, но тоже требует реакции, часто как ticket или daytime page.",[15,815,816],{},"В production не копируйте числа слепо. Сначала выберите:",[220,818,819,822,825,828,831],{},[223,820,821],{},"окно SLO: 7d, 28d, 30d;",[223,823,824],{},"допустимый error budget;",[223,826,827],{},"какую часть budget можно сжечь до page;",[223,829,830],{},"минимальный traffic, при котором ratio имеет смысл;",[223,832,833],{},"кто владелец реакции.",[21,835,837],{"id":836},"latency-slo","Latency SLO",[15,839,840,841,844],{},"Допустим: 95% ",[106,842,843],{},"\u002Fconvert"," должны быть быстрее 300ms.",[15,846,847],{},"SLI через histogram bucket:",[98,849,853],{"className":850,"code":851,"language":852,"meta":104,"style":104},"language-promql shiki shiki-themes github-dark","sum(rate(http_request_duration_seconds_bucket{route=\"\u002Fconvert\",le=\"0.3\"}[5m]))\n\u002F\nsum(rate(http_request_duration_seconds_count{route=\"\u002Fconvert\"}[5m]))\n","promql",[106,854,855,860,865],{"__ignoreMap":104},[247,856,857],{"class":249,"line":250},[247,858,859],{},"sum(rate(http_request_duration_seconds_bucket{route=\"\u002Fconvert\",le=\"0.3\"}[5m]))\n",[247,861,862],{"class":249,"line":261},[247,863,864],{},"\u002F\n",[247,866,867],{"class":249,"line":277},[247,868,869],{},"sum(rate(http_request_duration_seconds_count{route=\"\u002Fconvert\"}[5m]))\n",[15,871,872],{},"Alert:",[98,874,876],{"className":241,"code":875,"language":243,"meta":104,"style":104},"- alert: RatedeskConvertLatencySLO\n  expr: |\n    (\n      sum(rate(http_request_duration_seconds_bucket{route=\"\u002Fconvert\",le=\"0.3\"}[10m]))\n      \u002F\n      sum(rate(http_request_duration_seconds_count{route=\"\u002Fconvert\"}[10m]))\n    ) \u003C 0.95\n  for: 10m\n  labels:\n    severity: page\n    slo: latency\n  annotations:\n    summary: \"Less than 95% of \u002Fconvert requests are faster than 300ms\"\n    runbook_url: \"https:\u002F\u002Fgitlab.example.com\u002Fratedesk\u002Fdocs\u002Frunbooks\u002Fhigh-latency\"\n",[106,877,878,890,899,904,909,914,919,924,934,941,950,960,967,977],{"__ignoreMap":104},[247,879,880,883,885,887],{"class":249,"line":250},[247,881,882],{"class":257},"- ",[247,884,537],{"class":253},[247,886,270],{"class":257},[247,888,889],{"class":273},"RatedeskConvertLatencySLO\n",[247,891,892,895,897],{"class":249,"line":261},[247,893,894],{"class":253},"  expr",[247,896,270],{"class":257},[247,898,319],{"class":318},[247,900,901],{"class":249,"line":277},[247,902,903],{"class":273},"    (\n",[247,905,906],{"class":249,"line":288},[247,907,908],{"class":273},"      sum(rate(http_request_duration_seconds_bucket{route=\"\u002Fconvert\",le=\"0.3\"}[10m]))\n",[247,910,911],{"class":249,"line":296},[247,912,913],{"class":273},"      \u002F\n",[247,915,916],{"class":249,"line":310},[247,917,918],{"class":273},"      sum(rate(http_request_duration_seconds_count{route=\"\u002Fconvert\"}[10m]))\n",[247,920,921],{"class":249,"line":322},[247,922,923],{"class":273},"    ) \u003C 0.95\n",[247,925,926,929,931],{"class":249,"line":328},[247,927,928],{"class":253},"  for",[247,930,270],{"class":257},[247,932,933],{"class":273},"10m\n",[247,935,936,939],{"class":249,"line":335},[247,937,938],{"class":253},"  labels",[247,940,258],{"class":257},[247,942,943,946,948],{"class":249,"line":347},[247,944,945],{"class":253},"    severity",[247,947,270],{"class":257},[247,949,610],{"class":273},[247,951,952,955,957],{"class":249,"line":356},[247,953,954],{"class":253},"    slo",[247,956,270],{"class":257},[247,958,959],{"class":273},"latency\n",[247,961,962,965],{"class":249,"line":362},[247,963,964],{"class":253},"  annotations",[247,966,258],{"class":257},[247,968,969,972,974],{"class":249,"line":368},[247,970,971],{"class":253},"    summary",[247,973,270],{"class":257},[247,975,976],{"class":273},"\"Less than 95% of \u002Fconvert requests are faster than 300ms\"\n",[247,978,979,982,984],{"class":249,"line":373},[247,980,981],{"class":253},"    runbook_url",[247,983,270],{"class":257},[247,985,986],{"class":273},"\"https:\u002F\u002Fgitlab.example.com\u002Fratedesk\u002Fdocs\u002Frunbooks\u002Fhigh-latency\"\n",[15,988,989],{},"p95 на dashboard полезен, но SLO часто лучше формулировать как долю good events.",[21,991,993],{"id":992},"low-traffic-и-деление-на-ноль","Low traffic и деление на ноль",[15,995,996],{},"На маленьком трафике один 500 может дать страшный error ratio, хотя impact минимальный. Добавляйте traffic guard:",[98,998,1000],{"className":850,"code":999,"language":852,"meta":104,"style":104},"(\n  sum(rate(http_requests_total{code=~\"5..\"}[5m]))\n  \u002F\n  sum(rate(http_requests_total[5m]))\n) > 0.02\nand\nsum(rate(http_requests_total[5m])) > 1\n",[106,1001,1002,1007,1012,1017,1022,1027,1032],{"__ignoreMap":104},[247,1003,1004],{"class":249,"line":250},[247,1005,1006],{},"(\n",[247,1008,1009],{"class":249,"line":261},[247,1010,1011],{},"  sum(rate(http_requests_total{code=~\"5..\"}[5m]))\n",[247,1013,1014],{"class":249,"line":277},[247,1015,1016],{},"  \u002F\n",[247,1018,1019],{"class":249,"line":288},[247,1020,1021],{},"  sum(rate(http_requests_total[5m]))\n",[247,1023,1024],{"class":249,"line":296},[247,1025,1026],{},") > 0.02\n",[247,1028,1029],{"class":249,"line":310},[247,1030,1031],{},"and\n",[247,1033,1034],{"class":249,"line":322},[247,1035,1036],{},"sum(rate(http_requests_total[5m])) > 1\n",[15,1038,1039],{},"Для batch\u002Flow-traffic сервисов иногда лучше alertить на absolute count за окно:",[98,1041,1043],{"className":850,"code":1042,"language":852,"meta":104,"style":104},"increase(http_requests_total{code=~\"5..\"}[30m]) > 20\n",[106,1044,1045],{"__ignoreMap":104},[247,1046,1047],{"class":249,"line":250},[247,1048,1042],{},[15,1050,1051],{},"Или на доменный SLI: \"нет успешного обновления курса 10 минут\", а не \"error ratio высокая\".",[21,1053,1055],{"id":1054},"freshness-slo","Freshness SLO",[15,1057,1058],{},"Для сервиса курсов валют freshness часто важнее обычной \"живости\" API.",[15,1060,1061],{},"Метрика:",[98,1063,1066],{"className":1064,"code":1065,"language":103,"meta":104},[101],"ratedesk_last_successful_rate_update_timestamp_seconds\n",[106,1067,1065],{"__ignoreMap":104},[15,1069,1070],{},"SLI:",[98,1072,1074],{"className":850,"code":1073,"language":852,"meta":104,"style":104},"time() - ratedesk_last_successful_rate_update_timestamp_seconds \u003C 300\n",[106,1075,1076],{"__ignoreMap":104},[247,1077,1078],{"class":249,"line":250},[247,1079,1073],{},[15,1081,872],{},[98,1083,1085],{"className":241,"code":1084,"language":243,"meta":104,"style":104},"- alert: RatedeskRatesStale\n  expr: time() - ratedesk_last_successful_rate_update_timestamp_seconds > 300\n  for: 5m\n  labels:\n    severity: page\n    slo: freshness\n  annotations:\n    summary: \"RateDesk rates are stale for more than 5 minutes\"\n    runbook_url: \"https:\u002F\u002Fgitlab.example.com\u002Fratedesk\u002Fdocs\u002Frunbooks\u002Fstale-rates\"\n",[106,1086,1087,1098,1107,1116,1122,1130,1139,1145,1154],{"__ignoreMap":104},[247,1088,1089,1091,1093,1095],{"class":249,"line":250},[247,1090,882],{"class":257},[247,1092,537],{"class":253},[247,1094,270],{"class":257},[247,1096,1097],{"class":273},"RatedeskRatesStale\n",[247,1099,1100,1102,1104],{"class":249,"line":261},[247,1101,894],{"class":253},[247,1103,270],{"class":257},[247,1105,1106],{"class":273},"time() - ratedesk_last_successful_rate_update_timestamp_seconds > 300\n",[247,1108,1109,1111,1113],{"class":249,"line":277},[247,1110,928],{"class":253},[247,1112,270],{"class":257},[247,1114,1115],{"class":273},"5m\n",[247,1117,1118,1120],{"class":249,"line":288},[247,1119,938],{"class":253},[247,1121,258],{"class":257},[247,1123,1124,1126,1128],{"class":249,"line":296},[247,1125,945],{"class":253},[247,1127,270],{"class":257},[247,1129,610],{"class":273},[247,1131,1132,1134,1136],{"class":249,"line":310},[247,1133,954],{"class":253},[247,1135,270],{"class":257},[247,1137,1138],{"class":273},"freshness\n",[247,1140,1141,1143],{"class":249,"line":322},[247,1142,964],{"class":253},[247,1144,258],{"class":257},[247,1146,1147,1149,1151],{"class":249,"line":328},[247,1148,971],{"class":253},[247,1150,270],{"class":257},[247,1152,1153],{"class":273},"\"RateDesk rates are stale for more than 5 minutes\"\n",[247,1155,1156,1158,1160],{"class":249,"line":335},[247,1157,981],{"class":253},[247,1159,270],{"class":257},[247,1161,1162],{"class":273},"\"https:\u002F\u002Fgitlab.example.com\u002Fratedesk\u002Fdocs\u002Frunbooks\u002Fstale-rates\"\n",[15,1164,1165],{},"Это хороший пример доменного SLI: пользователю может быть все равно, что API отвечает 200, если данные устарели.",[21,1167,1169],{"id":1168},"alert-routing","Alert routing",[15,1171,1172],{},"Минимальные правила:",[220,1174,1175,1178,1185,1188,1191,1197],{},[223,1176,1177],{},"каждый page-alert имеет owner;",[223,1179,1180,1181,1184],{},"каждый page-alert имеет ",[106,1182,1183],{},"runbook_url",";",[223,1186,1187],{},"alert grouping объединяет одинаковые симптомы;",[223,1189,1190],{},"inhibition подавляет вторичные alerts при известной корневой проблеме;",[223,1192,1193,1196],{},[106,1194,1195],{},"for"," защищает от одиночных spikes;",[223,1198,1199],{},"noisy alerts раз в неделю пересматриваются.",[15,1201,1202],{},"Пример мыслительного фильтра:",[98,1204,1207],{"className":1205,"code":1206,"language":103,"meta":104},[101],"Если alert сработал ночью, инженер может безопасно сделать что-то полезное за 10 минут?\n",[106,1208,1206],{"__ignoreMap":104},[15,1210,1211],{},"Если ответ \"нет\", это, скорее всего, dashboard panel или ticket, а не page.",[15,1213,1214],{},"Пример Alertmanager routing:",[98,1216,1218],{"className":241,"code":1217,"language":243,"meta":104,"style":104},"route:\n  group_by: [\"service\", \"alertname\"]\n  group_wait: 30s\n  group_interval: 5m\n  repeat_interval: 2h\n  receiver: default\n  routes:\n    - matchers:\n        - severity=\"page\"\n      receiver: oncall\n    - matchers:\n        - severity=\"ticket\"\n      receiver: backlog\n\ninhibit_rules:\n  - source_matchers:\n      - alertname=\"RatedeskPostgresUnavailable\"\n    target_matchers:\n      - dependency=\"postgres\"\n    equal: [\"service\"]\n",[106,1219,1220,1227,1246,1255,1264,1274,1284,1291,1301,1309,1319,1327,1334,1343,1347,1354,1363,1370,1377,1384],{"__ignoreMap":104},[247,1221,1222,1225],{"class":249,"line":250},[247,1223,1224],{"class":253},"route",[247,1226,258],{"class":257},[247,1228,1229,1232,1235,1238,1240,1243],{"class":249,"line":261},[247,1230,1231],{"class":253},"  group_by",[247,1233,1234],{"class":257},": [",[247,1236,1237],{"class":273},"\"service\"",[247,1239,767],{"class":257},[247,1241,1242],{"class":273},"\"alertname\"",[247,1244,1245],{"class":257},"]\n",[247,1247,1248,1251,1253],{"class":249,"line":277},[247,1249,1250],{"class":253},"  group_wait",[247,1252,270],{"class":257},[247,1254,285],{"class":273},[247,1256,1257,1260,1262],{"class":249,"line":288},[247,1258,1259],{"class":253},"  group_interval",[247,1261,270],{"class":257},[247,1263,1115],{"class":273},[247,1265,1266,1269,1271],{"class":249,"line":296},[247,1267,1268],{"class":253},"  repeat_interval",[247,1270,270],{"class":257},[247,1272,1273],{"class":273},"2h\n",[247,1275,1276,1279,1281],{"class":249,"line":310},[247,1277,1278],{"class":253},"  receiver",[247,1280,270],{"class":257},[247,1282,1283],{"class":273},"default\n",[247,1285,1286,1289],{"class":249,"line":322},[247,1287,1288],{"class":253},"  routes",[247,1290,258],{"class":257},[247,1292,1293,1296,1299],{"class":249,"line":328},[247,1294,1295],{"class":257},"    - ",[247,1297,1298],{"class":253},"matchers",[247,1300,258],{"class":257},[247,1302,1303,1306],{"class":249,"line":335},[247,1304,1305],{"class":257},"        - ",[247,1307,1308],{"class":273},"severity=\"page\"\n",[247,1310,1311,1314,1316],{"class":249,"line":347},[247,1312,1313],{"class":253},"      receiver",[247,1315,270],{"class":257},[247,1317,1318],{"class":273},"oncall\n",[247,1320,1321,1323,1325],{"class":249,"line":356},[247,1322,1295],{"class":257},[247,1324,1298],{"class":253},[247,1326,258],{"class":257},[247,1328,1329,1331],{"class":249,"line":362},[247,1330,1305],{"class":257},[247,1332,1333],{"class":273},"severity=\"ticket\"\n",[247,1335,1336,1338,1340],{"class":249,"line":368},[247,1337,1313],{"class":253},[247,1339,270],{"class":257},[247,1341,1342],{"class":273},"backlog\n",[247,1344,1345],{"class":249,"line":373},[247,1346,332],{"emptyLinePlaceholder":331},[247,1348,1349,1352],{"class":249,"line":378},[247,1350,1351],{"class":253},"inhibit_rules",[247,1353,258],{"class":257},[247,1355,1356,1358,1361],{"class":249,"line":390},[247,1357,264],{"class":257},[247,1359,1360],{"class":253},"source_matchers",[247,1362,258],{"class":257},[247,1364,1365,1367],{"class":249,"line":399},[247,1366,299],{"class":257},[247,1368,1369],{"class":273},"alertname=\"RatedeskPostgresUnavailable\"\n",[247,1371,1372,1375],{"class":249,"line":405},[247,1373,1374],{"class":253},"    target_matchers",[247,1376,258],{"class":257},[247,1378,1379,1381],{"class":249,"line":410},[247,1380,299],{"class":257},[247,1382,1383],{"class":273},"dependency=\"postgres\"\n",[247,1385,1386,1389,1391,1393],{"class":249,"line":416},[247,1387,1388],{"class":253},"    equal",[247,1390,1234],{"class":257},[247,1392,1237],{"class":273},[247,1394,1245],{"class":257},[15,1396,1397],{},"Что обычно не должно будить само по себе:",[220,1399,1400,1403,1406,1409,1412,1415],{},[223,1401,1402],{},"CPU 85%;",[223,1404,1405],{},"рост goroutines без user impact;",[223,1407,1408],{},"single pod restart;",[223,1410,1411],{},"Redis memory warning;",[223,1413,1414],{},"один failed scrape;",[223,1416,1417],{},"Kafka rebalance, который быстро завершился.",[15,1419,1420],{},"Эти сигналы нужны на dashboard и как cause-alert ticket, но page лучше держать за user pain: ошибки, latency, stale data, потеря обработки.",[21,1422,90],{"id":1423},"runbook",[15,1425,1426],{},"Минимальный runbook:",[1428,1429,1430,1433,1436,1439,1442,1453,1456,1459,1462],"ol",{},[223,1431,1432],{},"Подтвердить impact: route, процент ошибок, latency, freshness.",[223,1434,1435],{},"Проверить recent deploy\u002Fmigration.",[223,1437,1438],{},"Открыть API dashboard.",[223,1440,1441],{},"Найти trace медленного или ошибочного запроса.",[223,1443,1444,1445,1448,1449,1452],{},"Найти logs по ",[106,1446,1447],{},"request_id","\u002F",[106,1450,1451],{},"trace_id",".",[223,1454,1455],{},"Проверить зависимости: DB, Redis, Kafka, provider.",[223,1457,1458],{},"Выбрать mitigation: rollback, feature flag, stale cache, pause consumer.",[223,1460,1461],{},"Проверить recovery.",[223,1463,1464],{},"Создать postmortem\u002Ffollow-up, если был SEV.",[21,1466,1468],{"id":1467},"slo-worksheet","SLO worksheet",[15,1470,1471],{},"Перед тем как писать alert rule, заполните таблицу:",[26,1473,1474,1484],{},[29,1475,1476],{},[32,1477,1478,1481],{},[35,1479,1480],{"align":37},"Поле",[35,1482,1483],{"align":37},"Пример для RateDesk",[43,1485,1486,1497,1504,1512,1520,1528,1536,1543,1554,1561,1569],{},[32,1487,1488,1491],{},[48,1489,1490],{"align":37},"User journey",[48,1492,1493,1496],{"align":37},[106,1494,1495],{},"POST \u002Fconvert"," возвращает расчет.",[32,1498,1499,1501],{},[48,1500,50],{"align":37},[48,1502,1503],{"align":37},"Доля successful non-5xx requests.",[32,1505,1506,1509],{},[48,1507,1508],{"align":37},"Good event",[48,1510,1511],{"align":37},"HTTP 2xx\u002F3xx и expected 4xx validation.",[32,1513,1514,1517],{},[48,1515,1516],{"align":37},"Bad event",[48,1518,1519],{"align":37},"5xx, timeout, dependency failure.",[32,1521,1522,1525],{},[48,1523,1524],{"align":37},"Исключения",[48,1526,1527],{"align":37},"400 validation, 404 по доменному not found, health checks.",[32,1529,1530,1533],{},[48,1531,1532],{"align":37},"Окно",[48,1534,1535],{"align":37},"30 дней.",[32,1537,1538,1540],{},[48,1539,58],{"align":37},[48,1541,1542],{"align":37},"99.9%.",[32,1544,1545,1548],{},[48,1546,1547],{"align":37},"Источник",[48,1549,1550,1553],{"align":37},[106,1551,1552],{},"http_requests_total"," recording rules.",[32,1555,1556,1558],{},[48,1557,82],{"align":37},[48,1559,1560],{"align":37},"fast burn page, slow burn ticket.",[32,1562,1563,1566],{},[48,1564,1565],{"align":37},"Owner",[48,1567,1568],{"align":37},"backend\u002Fon-call.",[32,1570,1571,1573],{},[48,1572,90],{"align":37},[48,1574,1575,1452],{"align":37},[106,1576,1577],{},"docs\u002Frunbooks\u002Fhigh-5xx.md",[15,1579,1580],{},"Связка для dashboard:",[26,1582,1583,1599],{},[29,1584,1585],{},[32,1586,1587,1589,1592,1595,1597],{},[35,1588,50],{"align":37},[35,1590,1591],{"align":37},"PromQL",[35,1593,1594],{"align":37},"Panel",[35,1596,82],{"align":37},[35,1598,90],{"align":37},[43,1600,1601,1618,1637],{},[32,1602,1603,1605,1609,1612,1615],{},[48,1604,135],{"align":37},[48,1606,1607],{"align":37},[106,1608,140],{},[48,1610,1611],{"align":37},"SLO state, burn rate",[48,1613,1614],{"align":37},"Fast\u002Fslow burn",[48,1616,1617],{"align":37},"high-5xx",[32,1619,1620,1622,1628,1631,1634],{},[48,1621,148],{"align":37},[48,1623,1624,1625],{"align":37},"good events under ",[106,1626,1627],{},"0.3",[48,1629,1630],{"align":37},"p95 + good ratio",[48,1632,1633],{"align":37},"latency SLO",[48,1635,1636],{"align":37},"high-latency",[32,1638,1639,1641,1646,1649,1652],{},[48,1640,159],{"align":37},[48,1642,1643],{"align":37},[106,1644,1645],{},"time() - last_success",[48,1647,1648],{"align":37},"freshness age",[48,1650,1651],{"align":37},"stale rates",[48,1653,1654],{"align":37},"stale-rates",[21,1656,1658],{"id":1657},"практика","Практика",[15,1660,1661],{},"Для RateDesk заведите:",[220,1663,1664,1667,1672,1675,1678,1681,1685,1690],{},[223,1665,1666],{},"availability SLO;",[223,1668,1669,1670,1184],{},"latency SLO для ",[106,1671,843],{},[223,1673,1674],{},"freshness SLO;",[223,1676,1677],{},"recording rules;",[223,1679,1680],{},"2-3 alert rules;",[223,1682,1683,1184],{},[106,1684,1577],{},[223,1686,1687,1184],{},[106,1688,1689],{},"docs\u002Frunbooks\u002Fhigh-latency.md",[223,1691,1692,1452],{},[106,1693,1694],{},"docs\u002Frunbooks\u002Fstale-rates.md",[15,1696,1697],{},"Acceptance:",[220,1699,1700,1705,1708,1711,1714],{},[223,1701,1702,1703,1184],{},"каждый alert имеет ",[106,1704,1183],{},[223,1706,1707],{},"page-alert привязан к user impact;",[223,1709,1710],{},"есть хотя бы один burn-rate alert;",[223,1712,1713],{},"dashboard показывает SLO state и error budget;",[223,1715,1716],{},"MR объясняет, почему выбранные 4xx\u002Fдоменные ошибки входят или не входят в SLI.",[1718,1719],"hr",{},[21,1721,1723],{"id":1722},"интерактивная-практика","Интерактивная практика",[1725,1726,1730,1733,1752],"quiz",{"answer":1727,"id":1728,"xp":1729},"4","obs-slo-q1","10",[15,1731,1732],{},"Какой alert лучше всего подходит для page ночью?",[1734,1735,1736],"template",{"v-slot:options":104},[220,1737,1738,1741,1744,1747],{},[223,1739,1740],{},"CPU 85% на одном pod",[223,1742,1743],{},"Один failed scrape",[223,1745,1746],{},"Redis memory warning без user impact",[223,1748,1749,1750],{},"Fast burn availability SLO для ",[106,1751,843],{},[1734,1753,1754],{"v-slot:explanation":104},[15,1755,1756],{},"Page-alert должен быть привязан к user pain и быстрому расходу error budget, а не к каждому cause-signal.",[1758,1759,1763,1766,1932],"predict",{"answer":1760,"id":1761,"xp":1762},"page\\nticket","obs-slo-p1","15",[15,1764,1765],{},"Что выведет программа?",[1734,1767,1768],{"v-slot:code":104},[98,1769,1773],{"className":1770,"code":1771,"language":1772,"meta":104,"style":104},"language-go shiki shiki-themes github-dark","package main\n\nimport \"fmt\"\n\nfunc AlertRoute(burnRate float64) string {\n    if burnRate >= 14 {\n        return \"page\"\n    }\n    return \"ticket\"\n}\n\nfunc main() {\n    fmt.Println(AlertRoute(20))\n    fmt.Println(AlertRoute(3))\n}\n","go",[106,1774,1775,1784,1788,1802,1806,1833,1850,1858,1863,1871,1876,1880,1890,1911,1928],{"__ignoreMap":104},[247,1776,1777,1780],{"class":249,"line":250},[247,1778,1779],{"class":318},"package",[247,1781,1783],{"class":1782},"svObZ"," main\n",[247,1785,1786],{"class":249,"line":261},[247,1787,332],{"emptyLinePlaceholder":331},[247,1789,1790,1793,1796,1799],{"class":249,"line":277},[247,1791,1792],{"class":318},"import",[247,1794,1795],{"class":273}," \"",[247,1797,1798],{"class":1782},"fmt",[247,1800,1801],{"class":273},"\"\n",[247,1803,1804],{"class":249,"line":288},[247,1805,332],{"emptyLinePlaceholder":331},[247,1807,1808,1811,1814,1817,1821,1824,1827,1830],{"class":249,"line":296},[247,1809,1810],{"class":318},"func",[247,1812,1813],{"class":1782}," AlertRoute",[247,1815,1816],{"class":257},"(",[247,1818,1820],{"class":1819},"s9osk","burnRate",[247,1822,1823],{"class":318}," float64",[247,1825,1826],{"class":257},") ",[247,1828,1829],{"class":318},"string",[247,1831,1832],{"class":257}," {\n",[247,1834,1835,1838,1841,1844,1848],{"class":249,"line":310},[247,1836,1837],{"class":318},"    if",[247,1839,1840],{"class":257}," burnRate ",[247,1842,1843],{"class":318},">=",[247,1845,1847],{"class":1846},"sDLfK"," 14",[247,1849,1832],{"class":257},[247,1851,1852,1855],{"class":249,"line":322},[247,1853,1854],{"class":318},"        return",[247,1856,1857],{"class":273}," \"page\"\n",[247,1859,1860],{"class":249,"line":328},[247,1861,1862],{"class":257},"    }\n",[247,1864,1865,1868],{"class":249,"line":335},[247,1866,1867],{"class":318},"    return",[247,1869,1870],{"class":273}," \"ticket\"\n",[247,1872,1873],{"class":249,"line":347},[247,1874,1875],{"class":257},"}\n",[247,1877,1878],{"class":249,"line":356},[247,1879,332],{"emptyLinePlaceholder":331},[247,1881,1882,1884,1887],{"class":249,"line":362},[247,1883,1810],{"class":318},[247,1885,1886],{"class":1782}," main",[247,1888,1889],{"class":257},"() {\n",[247,1891,1892,1895,1898,1900,1903,1905,1908],{"class":249,"line":368},[247,1893,1894],{"class":257},"    fmt.",[247,1896,1897],{"class":1782},"Println",[247,1899,1816],{"class":257},[247,1901,1902],{"class":1782},"AlertRoute",[247,1904,1816],{"class":257},[247,1906,1907],{"class":1846},"20",[247,1909,1910],{"class":257},"))\n",[247,1912,1913,1915,1917,1919,1921,1923,1926],{"class":249,"line":373},[247,1914,1894],{"class":257},[247,1916,1897],{"class":1782},[247,1918,1816],{"class":257},[247,1920,1902],{"class":1782},[247,1922,1816],{"class":257},[247,1924,1925],{"class":1846},"3",[247,1927,1910],{"class":257},[247,1929,1930],{"class":249,"line":378},[247,1931,1875],{"class":257},[1734,1933,1934],{"v-slot:hint":104},[15,1935,1936],{},"Fast burn будит on-call, slow burn чаще превращается в ticket\u002Fcapacity work.",[1938,1939,1942,1969,2099],"code-task",{"expected":1940,"id":1941,"xp":1907},"page\\nticket\\ndashboard","obs-slo-ct1",[15,1943,1944,1945,270,1948,1951,1952,767,1955,1958,1959,767,1962,1965,1966,1452],{},"Реализуй ",[106,1946,1947],{},"AlertPolicy",[106,1949,1950],{},"fast-burn"," должен вернуть ",[106,1953,1954],{},"page",[106,1956,1957],{},"slow-burn"," - ",[106,1960,1961],{},"ticket",[106,1963,1964],{},"cpu-high"," без user impact - ",[106,1967,1968],{},"dashboard",[1734,1970,1971],{"v-slot:template":104},[98,1972,1974],{"className":1770,"code":1973,"language":1772,"meta":104,"style":104},"package main\n\nimport \"fmt\"\n\nfunc AlertPolicy(signal string) string {\n    return \"todo\"\n}\n\nfunc main() {\n    fmt.Println(AlertPolicy(\"fast-burn\"))\n    fmt.Println(AlertPolicy(\"slow-burn\"))\n    fmt.Println(AlertPolicy(\"cpu-high\"))\n}\n",[106,1975,1976,1982,1986,1996,2000,2021,2028,2032,2036,2044,2061,2078,2095],{"__ignoreMap":104},[247,1977,1978,1980],{"class":249,"line":250},[247,1979,1779],{"class":318},[247,1981,1783],{"class":1782},[247,1983,1984],{"class":249,"line":261},[247,1985,332],{"emptyLinePlaceholder":331},[247,1987,1988,1990,1992,1994],{"class":249,"line":277},[247,1989,1792],{"class":318},[247,1991,1795],{"class":273},[247,1993,1798],{"class":1782},[247,1995,1801],{"class":273},[247,1997,1998],{"class":249,"line":288},[247,1999,332],{"emptyLinePlaceholder":331},[247,2001,2002,2004,2007,2009,2012,2015,2017,2019],{"class":249,"line":296},[247,2003,1810],{"class":318},[247,2005,2006],{"class":1782}," AlertPolicy",[247,2008,1816],{"class":257},[247,2010,2011],{"class":1819},"signal",[247,2013,2014],{"class":318}," string",[247,2016,1826],{"class":257},[247,2018,1829],{"class":318},[247,2020,1832],{"class":257},[247,2022,2023,2025],{"class":249,"line":310},[247,2024,1867],{"class":318},[247,2026,2027],{"class":273}," \"todo\"\n",[247,2029,2030],{"class":249,"line":322},[247,2031,1875],{"class":257},[247,2033,2034],{"class":249,"line":328},[247,2035,332],{"emptyLinePlaceholder":331},[247,2037,2038,2040,2042],{"class":249,"line":335},[247,2039,1810],{"class":318},[247,2041,1886],{"class":1782},[247,2043,1889],{"class":257},[247,2045,2046,2048,2050,2052,2054,2056,2059],{"class":249,"line":347},[247,2047,1894],{"class":257},[247,2049,1897],{"class":1782},[247,2051,1816],{"class":257},[247,2053,1947],{"class":1782},[247,2055,1816],{"class":257},[247,2057,2058],{"class":273},"\"fast-burn\"",[247,2060,1910],{"class":257},[247,2062,2063,2065,2067,2069,2071,2073,2076],{"class":249,"line":356},[247,2064,1894],{"class":257},[247,2066,1897],{"class":1782},[247,2068,1816],{"class":257},[247,2070,1947],{"class":1782},[247,2072,1816],{"class":257},[247,2074,2075],{"class":273},"\"slow-burn\"",[247,2077,1910],{"class":257},[247,2079,2080,2082,2084,2086,2088,2090,2093],{"class":249,"line":362},[247,2081,1894],{"class":257},[247,2083,1897],{"class":1782},[247,2085,1816],{"class":257},[247,2087,1947],{"class":1782},[247,2089,1816],{"class":257},[247,2091,2092],{"class":273},"\"cpu-high\"",[247,2094,1910],{"class":257},[247,2096,2097],{"class":249,"line":368},[247,2098,1875],{"class":257},[1734,2100,2101],{"v-slot:hints":104},[220,2102,2103,2106,2109],{},[223,2104,2105],{},"Page только на срочный user impact.",[223,2107,2108],{},"Slow burn требует реакции, но не всегда срочной.",[223,2110,2111],{},"Cause metrics без симптома полезны на dashboard.",[2113,2114,2115],"style",{},"html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .s9osk, html code.shiki .s9osk{--shiki-default:#FFAB70}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}",{"title":104,"searchDepth":261,"depth":261,"links":2117},[2118,2119,2120,2121,2122,2123,2124,2125,2126,2127,2128,2129,2130],{"id":23,"depth":261,"text":24},{"id":113,"depth":261,"text":114},{"id":193,"depth":261,"text":194},{"id":234,"depth":261,"text":235},{"id":777,"depth":261,"text":778},{"id":836,"depth":261,"text":837},{"id":992,"depth":261,"text":993},{"id":1054,"depth":261,"text":1055},{"id":1168,"depth":261,"text":1169},{"id":1423,"depth":261,"text":90},{"id":1467,"depth":261,"text":1468},{"id":1657,"depth":261,"text":1658},{"id":1722,"depth":261,"text":1723},1781022063291]