Tricks għall-ipproċessar tal-metriċi f'Kapacitor

Probabbilment, illum ħadd ma jistaqsi għaliex huwa meħtieġ li jinġabru metriċi tas-servizz. Il-pass loġiku li jmiss huwa li twaqqaf twissija għall-metriċi miġbura, li tinnotifika dwar kwalunkwe devjazzjoni fid-dejta f'kanali konvenjenti għalik (posta, Slack, Telegramma). Fis-servizz online tal-prenotazzjoni tal-lukandi Ostrovok.ru il-metriċi kollha tas-servizzi tagħna jitferra 'f'InfluxDB u jintwerew fi Grafana, u hemm ukoll ikkonfigurat twissija bażika. Għal kompiti bħal "għandek bżonn tikkalkula xi ħaġa u tqabbel magħha," nużaw Kapacitor.

Tricks għall-ipproċessar tal-metriċi f'Kapacitor
Kapacitor huwa parti mill-munzell TICK li jista 'jipproċessa metriċi minn InfluxDB. Jista 'jgħaqqad diversi kejl flimkien (jingħaqad), jikkalkula xi ħaġa utli mid-dejta riċevuta, jikteb ir-riżultat lura lil InfluxDB, jibgħat twissija lil Slack/Telegram/mail.

Il-munzell kollu huwa frisk u dettaljat dokumentazzjoni, iżda dejjem se jkun hemm affarijiet utli li mhumiex indikati b'mod espliċitu fil-manwali. F'dan l-artikolu, iddeċidejt li niġbor għadd ta' suġġerimenti utli u mhux ovvji bħal dawn (is-sintassi bażika ta' TICKscipt hija deskritta hawn) u juru kif jistgħu jiġu applikati bl-użu ta’ eżempju ta’ kif insolvu waħda mill-problemi tagħna.

Ejja ħa mmorru!

float & int, żbalji fil-kalkolu

Problema assolutament standard, solvuta permezz ta’ kasti:

var alert_float = 5.0
var alert_int = 10
data|eval(lambda: float("value") > alert_float OR float("value") < float("alert_int"))

Bl-użu default()

Jekk tikketta/field ma jimtlewx, se jseħħu żbalji fil-kalkolu:

|default()
        .tag('status', 'empty')
        .field('value', 0)

imla jingħaqad (ġewwa vs barra)

B'mod awtomatiku, join se jarmi l-punti fejn m'hemm l-ebda data (interjuri).
Bil-fill('null'), se titwettaq jewter join, u wara trid tagħmel default() u timla l-valuri vojta:

var data = res1
    |join(res2)
        .as('res1', 'res2)
        .fill('null')
    |default()
        .field('res1.value', 0.0)
        .field('res2.value', 100.0)

Għad hemm sfumatura hawn. Fl-eżempju ta 'hawn fuq, jekk waħda mis-serje (res1 jew res2) tkun vojta, is-serje li tirriżulta (data) tkun vojta wkoll. Hemm diversi biljetti fuq dan is-suġġett fuq Github (1633, 1871, 6967) – qed nistennew irranġati u tbatija ftit.

L-użu tal-kundizzjonijiet fil-kalkoli (jekk f'lambda)

|eval(lambda: if("value" > 0, true, false)

L-aħħar ħames minuti mill-pipeline għall-perjodu

Pereżempju, trid tqabbel il-valuri tal-aħħar ħames minuti mal-ġimgħa ta 'qabel. Tista' tieħu żewġ lottijiet ta' dejta f'żewġ lottijiet separati jew estratti parti mid-dejta minn perjodu akbar:

 |where(lambda: duration((unixNano(now()) - unixNano("time"))/1000, 1u) < 5m)

Alternattiva għall-aħħar ħames minuti tkun li tuża BarrierNode, li jaqta 'data qabel il-ħin speċifikat:

|barrier()
        .period(5m)

Eżempji tal-użu tal-mudelli Go fil-messaġġ

Il-mudelli jikkorrispondu mal-format mill-pakkett test.mudellHawn taħt hawn xi puzzles li jiltaqgħu magħhom spiss.

jekk-inkella

Aħna npoġġu l-affarijiet fl-ordni u ma nixprunawx lin-nies bit-test għal darb'oħra:

|alert()
    ...
    .message(
        '{{ if eq .Level "OK" }}It is ok now{{ else }}Chief, everything is broken{{end}}'
    )

Żewġ ċifri wara l-punt deċimali fil-messaġġ

Titjib tal-leġibbiltà tal-messaġġ:

|alert()
    ...
    .message(
        'now value is {{ index .Fields "value" | printf "%0.2f" }}'
    )

Espansjoni varjabbli fil-messaġġ

Aħna nuru aktar informazzjoni fil-messaġġ biex inwieġbu l-mistoqsija "Għaliex qed tgħajjat"?

var warnAlert = 10
  |alert()
    ...
    .message(
       'Today value less then '+string(warnAlert)+'%'
    )

Identifikatur uniku ta' twissija

Din hija ħaġa neċessarja meta jkun hemm aktar minn grupp wieħed fid-dejta, inkella se tiġi ġġenerata twissija waħda biss:

|alert()
      ...
      .id('{{ index .Tags "myname" }}/{{ index .Tags "myfield" }}')

Custom handler's

Il-lista kbira ta 'handlers tinkludi exec, li jippermettilek tesegwixxi l-iskrittura tiegħek bil-parametri mgħoddija (stdin) - kreattività u xejn aktar!

Waħda mid-dwana tagħna hija script Python żgħir biex jintbagħtu notifiki lil slack.
Għall-ewwel, ridna nibagħtu stampa grafana protetta minn awtorizzazzjoni f'messaġġ. Wara, ikteb OK fil-ħajt għat-twissija preċedenti mill-istess grupp, u mhux bħala messaġġ separat. Ftit aktar tard - żid mal-messaġġ l-iżball l-aktar komuni fl-aħħar X minuti.

Suġġett separat huwa l-komunikazzjoni ma’ servizzi oħra u kwalunkwe azzjoni mibdija minn twissija (biss jekk il-monitoraġġ tiegħek jaħdem tajjeb biżżejjed).
Eżempju ta' deskrizzjoni ta' handler, fejn slack_handler.py huwa l-iskrittura miktuba minnha nfisha:

topic: slack_graph
id: slack_graph.alert
match: level() != INFO AND changed() == TRUE
kind: exec
options:
  prog: /sbin/slack_handler.py
  args: ["-c", "CHANNELID", "--graph", "--search"]

Kif tiddibaggja?

Għażla b'output ta 'log

|log()
      .level("error")
      .prefix("something")

Watch (cli): kapacitor -url host-jew-ip:9092 logs lvl=żball

Għażla ma httpOut

Juri dejta fil-pipeline attwali:

|httpOut('something')

Watch (ikseb): host-jew-ip:9092/kapacitor/v1/tasks/task_name/xi ħaġa

Dijagramma ta' eżekuzzjoni

  • Kull kompitu jirritorna siġra tal-eżekuzzjoni b'numri utli fil-format graphviz.
  • Ħu blokk dot.
  • Pasteha fit-telespettatur, igawdu.

Fejn inkella tista 'tikseb rake?

timestamp fl-influxdb fuq writeback

Per eżempju, aħna waqqafna twissija għas-somma ta 'talbiet għal kull siegħa (groupBy(1h)) u rridu nirreġistraw it-twissija li seħħet fl-influxdb (biex turi b'mod sabiħ il-fatt tal-problema fuq il-grafika f'grafana).

influxDBOut() se jikteb il-valur tal-ħin mit-twissija sal-timestamp kif xieraq, il-punt fuq iċ-ċart se jinkiteb qabel/aktar tard milli waslet it-twissija;

Meta tkun meħtieġa l-eżattezza: naħdmu madwar din il-problema billi nsejħu lil handler tad-dwana, li jikteb id-dejta lil influxdb bit-timestamp attwali.

docker, bini u skjerament

Fl-istartjar, kapacitor jista' jgħabbi kompiti, mudelli u handlers mid-direttorju speċifikat fil-konfigurazzjoni fil-blokk [load].

Biex toħloq kompitu b'mod korrett, għandek bżonn l-affarijiet li ġejjin:

  1. Isem tal-fajl - estiż f'id/isem tal-iskript
  2. Tip – fluss/lott
  3. dbrp – keyword biex tindika liema database + politika taħdem fiha l-iscript (dbrp “fornitur.” “autogen”)

Jekk xi kompitu tal-lott ma jkunx fih linja b'dbrp, is-servizz kollu jirrifjuta li jibda u jikteb dwaru b'mod onest fir-reġistru.

Fil-chronograf, għall-kuntrarju, din il-linja m'għandhiex teżisti ma tkunx aċċettata permezz tal-interface u tiġġenera żball;

Hack meta tibni kontenitur: Dockerfile joħroġ b'-1 jekk ikun hemm linji b' //.+dbrp, li jippermettilek tifhem immedjatament ir-raġuni għall-falliment meta tgħaqqad il-bini.

tingħaqad wieħed għal ħafna

Eżempju ta' ħidma: trid tieħu l-95 perċentil tal-ħin operattiv tas-servizz għal ġimgħa, qabbel kull minuta tal-aħħar 10 ma' dan il-valur.

Ma tistax tagħmel wieħed għal ħafna jingħaqdu, l-aħħar/medja/medjan fuq grupp ta 'punti ddawwar in-nodu fi fluss, l-iżball "ma tistax iżżid truf mhux imqabbla tat-tfal: lott -> fluss" se jiġi rritornat.

Ir-riżultat ta' lott, bħala varjabbli f'espressjoni lambda, lanqas ma jiġi sostitwit.

Hemm għażla li tissejvja n-numri meħtieġa mill-ewwel lott għal fajl permezz ta 'udf u tagħbija dan il-fajl permezz ta' sideload.

X’solvejna b’dan?

Għandna madwar 100 fornitur tal-lukandi, kull wieħed minnhom jista 'jkollu diversi konnessjonijiet, ejja nsejħulha kanal. Hemm madwar 300 minn dawn il-kanali, kull wieħed mill-kanali jista 'jaqa'. Mill-metriċi kollha rreġistrati, aħna se nissorveljaw ir-rata ta 'żball (talbiet u żbalji).

Għaliex ma grafana?

Twissijiet ta 'żbalji kkonfigurati fi Grafana għandhom diversi żvantaġġi. Xi wħud huma kritiċi, xi wħud tista 'tagħlaq għajnejk għalihom, skond is-sitwazzjoni.

Grafana ma jafx kif tikkalkula bejn kejl + twissija, iżda għandna bżonn rata (talbiet-iżbalji)/talbiet.

L-iżbalji jidhru diżgustanti:

Tricks għall-ipproċessar tal-metriċi f'Kapacitor

U inqas ħażen meta wieħed iħares lejn talbiet b'suċċess:

Tricks għall-ipproċessar tal-metriċi f'Kapacitor

Okay, nistgħu nikkalkulaw minn qabel ir-rata fis-servizz qabel il-grafana, u f'xi każijiet dan jaħdem. Imma mhux tagħna, għax... għal kull kanal il-proporzjon tiegħu huwa meqjus bħala "normali", u t-twissijiet jaħdmu skont valuri statiċi (aħna nħarsu b'għajnejna, nibdlu jekk ikun hemm twissijiet frekwenti).

Dawn huma eżempji ta '"normali" għal kanali differenti:

Tricks għall-ipproċessar tal-metriċi f'Kapacitor

Tricks għall-ipproċessar tal-metriċi f'Kapacitor

Aħna ninjoraw il-punt preċedenti u nassumu li l-istampa "normali" hija simili għall-fornituri kollha. Issa kollox sew, u nistghu nghaddu b'allerti fil-grafana?
Nistgħu, imma verament ma rridux, għax irridu nagħżlu waħda mill-għażliet:
a) agħmel ħafna graphs għal kull kanal separatament (u akkumpanjahom bi tbatija)
b) ħalli chart waħda bil-kanali kollha (u tintilef fil-linji mlewna u twissijiet personalizzati)

Tricks għall-ipproċessar tal-metriċi f'Kapacitor

Kif għamiltu?

Għal darb'oħra, hemm eżempju tajjeb tal-bidu fid-dokumentazzjoni (Kalkolu tar-rati fuq serje magħquda), jistgħu jiġu ħarsa lejn jew jittieħdu bħala bażi fi problemi simili.

Dak li għamilna fl-aħħar:

  • tingħaqad ma 'żewġ serje fi ftit sigħat, raggruppament mill-kanali;
  • imla s-serje skond il-grupp jekk ma kienx hemm dejta;
  • qabbel il-medjan tal-aħħar 10 minuti mad-dejta preċedenti;
  • ngħajtu jekk insibu xi ħaġa;
  • niktbu r-rati kkalkulati u t-twissijiet li seħħew fl-influxdb;
  • ibgħat messaġġ utli lil slack.

Fl-opinjoni tiegħi, irnexxielna niksbu dak kollu li ridna niksbu fl-aħħar (u anke ftit aktar bi custom handlers) bl-aħjar mod possibbli.

Tista' tħares lejn github.com eżempju tal-kodiċi и ċirkwit minimu (graphviz) l-iskrittura li tirriżulta.

Eżempju tal-kodiċi li jirriżulta:

dbrp "supplier"."autogen"
var name = 'requests.rate'
var grafana_dash = 'pczpmYZWU/mydashboard'
var grafana_panel = '26'
var period = 8h
var todayPeriod = 10m
var every = 1m
var warnAlert = 15
var warnReset = 5
var reqQuery = 'SELECT sum("count") AS value FROM "supplier"."autogen"."requests"'
var errQuery = 'SELECT sum("count") AS value FROM "supplier"."autogen"."errors"'

var prevErr = batch
    |query(errQuery)
        .period(period)
        .every(every)
        .groupBy(1m, 'channel', 'supplier')

var prevReq = batch
    |query(reqQuery)
        .period(period)
        .every(every)
        .groupBy(1m, 'channel', 'supplier')

var rates = prevReq
    |join(prevErr)
        .as('req', 'err')
        .tolerance(1m)
        .fill('null')
    // заполняем значения нулями, если их не было
    |default()
        .field('err.value', 0.0)
        .field('req.value', 0.0)
    // if в lambda: считаем рейт, только если ошибки были
    |eval(lambda: if("err.value" > 0, 100.0 * (float("req.value") - float("err.value")) / float("req.value"), 100.0))
        .as('rate')

// записываем посчитанные значения в инфлюкс
rates
    |influxDBOut()
        .quiet()
        .create()
        .database('kapacitor')
        .retentionPolicy('autogen')
        .measurement('rates')

// выбираем данные за последние 10 минут, считаем медиану
var todayRate = rates
    |where(lambda: duration((unixNano(now()) - unixNano("time")) / 1000, 1u) < todayPeriod)
    |median('rate')
        .as('median')

var prevRate = rates
    |median('rate')
        .as('median')

var joined = todayRate
    |join(prevRate)
        .as('today', 'prev')
    |httpOut('join')

var trigger = joined
    |alert()
        .warn(lambda: ("prev.median" - "today.median") > warnAlert)
        .warnReset(lambda: ("prev.median" - "today.median") < warnReset)
        .flapping(0.25, 0.5)
        .stateChangesOnly()
        // собираем в message ссылку на график дашборда графаны
        .message(
            '{{ .Level }}: {{ index .Tags "channel" }} err/req ratio ({{ index .Tags "supplier" }})
{{ if eq .Level "OK" }}It is ok now{{ else }}
'+string(todayPeriod)+' median is {{ index .Fields "today.median" | printf "%0.2f" }}%, by previous '+string(period)+' is {{ index .Fields "prev.median" | printf "%0.2f" }}%{{ end }}
http://grafana.ostrovok.in/d/'+string(grafana_dash)+
'?var-supplier={{ index .Tags "supplier" }}&var-channel={{ index .Tags "channel" }}&panelId='+string(grafana_panel)+'&fullscreen&tz=UTC%2B03%3A00'
        )
        .id('{{ index .Tags "name" }}/{{ index .Tags "channel" }}')
        .levelTag('level')
        .messageField('message')
        .durationField('duration')
        .topic('slack_graph')

// "today.median" дублируем как "value", также пишем в инфлюкс остальные филды алерта (keep)
trigger
    |eval(lambda: "today.median")
        .as('value')
        .keep()
    |influxDBOut()
        .quiet()
        .create()
        .database('kapacitor')
        .retentionPolicy('autogen')
        .measurement('alerts')
        .tag('alertName', name)

X'inhi l-konklużjoni?

Kapacitor huwa kbir biex iwettaq monitoraġġ-allerti ma 'mazz ta' gruppi, iwettaq kalkoli addizzjonali bbażati fuq metriċi diġà rreġistrati, iwettaq azzjonijiet personalizzati u jmexxi skripts (udf).

L-ostaklu għad-dħul mhuwiex għoli ħafna - ipprova jekk il-grafana jew għodda oħra ma jissodisfawx bis-sħiħ ix-xewqat tiegħek.

Sors: www.habr.com

Ixtri hosting affidabbli għal siti bi protezzjoni DDoS, servers VPS VDS 🔥 Ixtri hosting ta' websajts affidabbli bi protezzjoni DDoS, servers VPS VDS | ProHoster