O yikarịrị, taa ọ dịghị onye na-ajụ ihe mere o ji dị mkpa ịnakọta metrik ọrụ. Nzọụkwụ ọzọ ezi uche dị na ya bụ ịtọlite mkpuchi maka metrik anakọtara, nke ga-eme ka ọkwa ọ bụla dị na data dị na ọwa dabara gị mma (mail, Slack, Telegram). Na ọrụ ntinye akwụkwọ nkwari akụ n'ịntanetị A na-awụsa metrik niile nke ọrụ anyị na InfluxDB wee gosipụta na Grafana, a na-ahazikwa ịdọ aka ná ntị bụ isi ebe ahụ. Maka ọrụ ndị dị ka "ịkwesịrị ịgbakọ ihe ma jiri ya tụnyere ya," anyị na-eji Kapacitor.

Kapacitor bụ akụkụ TICK tojupụtara nwere ike hazie metrik site na InfluxDB. Ọ nwere ike jikọọ ọtụtụ nha ọnụ (jikọọ), gbakọọ ihe bara uru site na data enwetara, dee nsonaazụ ya na InfluxDB, ziga njikere na Slack/Telegram/mail.
Nchịkọta dum dị mma na nkọwa , ma a ga-enwe mgbe niile ihe bara uru nke na-egosighị n'ụzọ doro anya na akwụkwọ ntuziaka. N'ime edemede a, ekpebiri m ịnakọta ọtụtụ ndụmọdụ bara uru, nke na-apụtaghị ìhè (a na-akọwa syntax bụ isi nke TICKscipt. ) ma gosi otú e nwere ike isi tinye ha n’ọrụ site n’iji ihe atụ dozie otu n’ime nsogbu anyị.
Ka anyị gawa!
sere n'elu & int, mgbako njehie
Nsogbu zuru oke, nke ejiri nkedo edozi ya:
var alert_float = 5.0
var alert_int = 10
data|eval(lambda: float("value") > alert_float OR float("value") < float("alert_int"))
Iji ndabara()
Ọ bụrụ na ejupụtaghị mkpado/ubi, njehie mgbako ga-eme:
|default()
.tag('status', 'empty')
.field('value', 0)
dejupụta njikọ (n'ime vs mpụta)
Site na ndabara, isonyere ga-atụfu isi ebe enweghị data (n'ime).
Site na njuputa ('null'), a ga-eme njikọ dị n'èzí, emesịa ị ga-eme ndabara() wee dejupụta ụkpụrụ efu:
var data = res1
|join(res2)
.as('res1', 'res2)
.fill('null')
|default()
.field('res1.value', 0.0)
.field('res2.value', 100.0)
A ka nwere nuance ebe a. N'ihe atụ dị n'elu, ọ bụrụ na otu n'ime usoro (res1 ma ọ bụ res2) bụ ihe efu, usoro ga-esi na ya pụta (data) ga-abụkwa ihe efu. Enwere ọtụtụ tiketi na isiokwu a na Github (, , ) - anyị na-echere ndozi na nhụjuanya ntakịrị.
Iji ọnọdụ na mgbako (ọ bụrụ na lambda)
|eval(lambda: if("value" > 0, true, false)
Nkeji ise ikpeazụ site na pipeline maka oge ahụ
Dịka ọmụmaatụ, ịkwesịrị iji ụkpụrụ nke nkeji ise gara aga tụnyere izu gara aga. Ị nwere ike were batches abụọ nke data n'ime batches abụọ dị iche iche ma ọ bụ wepụ akụkụ nke data site na oge buru ibu:
|where(lambda: duration((unixNano(now()) - unixNano("time"))/1000, 1u) < 5m)
Nhọrọ ọzọ maka nkeji ise ikpeazụ ga-abụ iji BarrierNode, nke na-ebipụ data tupu oge a kara aka:
|barrier()
.period(5m)
Ọmụmaatụ nke iji ndebiri Go na ozi
Ndebiri kwekọrọ na usoro sitere na ngwugwu N'okpuru bụ ụfọdụ mgbagwoju anya na-ezutekarị.
ọ bụrụ-ọzọ
Anyị na-edobe ihe n'usoro ma anaghị akpalite ndị mmadụ ederede ọzọ:
|alert()
...
.message(
'{{ if eq .Level "OK" }}It is ok now{{ else }}Chief, everything is broken{{end}}'
)
Ọnụọgụ abụọ gachara akara ngụkọ na ozi
Na-emeziwanye ọgụgụ nke ozi:
|alert()
...
.message(
'now value is {{ index .Fields "value" | printf "%0.2f" }}'
)
Na-agbasawanye mgbanwe na ozi
Anyị na-egosiputa ozi ndị ọzọ na ozi iji zaa ajụjụ a "Gịnị kpatara ọ na-eti mkpu"?
var warnAlert = 10
|alert()
...
.message(
'Today value less then '+string(warnAlert)+'%'
)
Ihe nchọpụta njikere pụrụ iche
Nke a bụ ihe dị mkpa mgbe enwere ihe karịrị otu na data ahụ, ma ọ bụghị naanị otu njikere ka a ga-eme:
|alert()
...
.id('{{ index .Tags "myname" }}/{{ index .Tags "myfield" }}')
Onye njikwa omenala
Nnukwu ndepụta nke ndị na-ahụ maka njikwa gụnyere exec, nke na-enye gị ohere iji paramita gafere (stdin) mee edemede gị - okike na ọ nweghị ihe ọzọ!
Otu n'ime omenala anyị bụ obere edemede Python maka izipu ọkwa na slack.
Na mbụ, anyị chọrọ izipu foto grafana echekwabara ikike na ozi. Mgbe nke ahụ gasịrị, dee OK na eri ahụ na ọkwa gara aga site na otu otu, ọ bụghị dị ka ozi dị iche. Obere oge ka e mesịrị - gbakwunye na ozi ahụ mmejọ kachasị na nkeji X ikpeazụ.
Isiokwu dị iche bụ nkwurịta okwu na ọrụ ndị ọzọ yana omume ọ bụla nke njikere malitere (naanị ma ọ bụrụ na nleba anya gị na-arụ ọrụ nke ọma).
Ọmụmaatụ nke nkọwa onye njikwa, ebe slack_handler.py bụ edemede nke onwe anyị:
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"]
Kedu ka esi ehichapụ?
Nhọrọ nwere mmepụta log
|log()
.level("error")
.prefix("something")
Lelee (cli): kapacitor -url :9092 ndekọ lvl= njehie
Nhọrọ na httpOut
Na-egosi data na pipeline ugbu a:
|httpOut('something')
Lelee (nweta): :9092/kapacitor/v1/tasks/task_name/ihe
Eserese mmebe
- Ọrụ ọ bụla na-eweghachite osisi ogbugbu nwere ọnụọgụ bara uru na usoro .
- Were ngọngọ .
- Tapawa ya na ihe nkiri, .
Ebee ka ị nwere ike nweta rake?
timestamp na influxdb na ideghachi
Dịka ọmụmaatụ, anyị na-edobe njikere maka nchikota arịrịọ kwa elekere (groupBy(1h)) ma chọọ ịdekọ njikere mere na influxdb (iji gosi nke ọma nke ọma eziokwu nke nsogbu ahụ na eserese na grafana).
influxDBOut () ga-ede uru oge site na njikere ruo akara ngosi oge, ya mere, a ga-ede isi ihe dị na chaatị ahụ tupu / mgbe e mesịrị ka njikere rutere.
Mgbe achọrọ izi ezi: anyị na-arụ ọrụ gburugburu nsogbu a site n'ịkpọ onye na-ahụ maka omenala, nke ga-ede data ka ọ bụrụ influxdb na timestamp dị ugbu a.
docker, wuo na mbugharị
Na mmalite, kapacitor nwere ike ibu ọrụ, ndebiri na ndị njikwa site na ndekọ aha akọwapụtara na nhazi na ngọngọ [load].
Iji mepụta ọrụ nke ọma, ịchọrọ ihe ndị a:
- Aha faịlụ – gbasaa ka ọ bụrụ id/aha edemede
- Ụdị – iyi/ogbe
- dbrp – okwu iji gosi nke nchekwa data + amụma nke edemede na-agba na (dbrp “supplier.”“autogen”)
Ọ bụrụ na ụfọdụ ọrụ batch enweghị ahịrị na dbrp, ọrụ niile ga-ajụ ịmalite ma dee ya n'eziokwu na ndekọ.
Na chronograf, n'ụzọ megidere nke a, a naghị anabata ahịrị a site na interface ma na-ebute njehie.
Mbanye anataghị ikike mgbe ị na-ewu akpa: Dockerfile na-apụ na -1 ma ọ bụrụ na enwere ahịrị na //.+dbrp, nke ga-enye gị ohere ịghọta ozugbo ihe kpatara ọdịda ahụ mgbe ị na-ezukọta ihe owuwu ahụ.
sonye n'otu n'otu
Ọrụ Ọmụmaatụ: ịkwesịrị iwere 95th percentile nke oge ọrụ ọrụ maka otu izu, jiri nkeji ọ bụla nke 10 ikpeazụ tụnyere uru a.
Ị nweghị ike ime otu-na-ọtụtụ sonyere, ikpeazụ/mean/median n'elu otu isi ihe na-atụgharị ọnụ ka ọ bụrụ iyi, njehie "enweghị ike ịgbakwunye nwa mismatched n'akụkụ: batch -> iyi" ga-eweghachite.
Ihe si na batch, dị ka mgbanwe na okwu lambda, adịghịkwa edochi ya.
Enwere nhọrọ iji chekwaa ọnụọgụ ndị dị mkpa site na batch mbụ gaa na faịlụ site na udf wee buo faịlụ a site n'ibu ibu.
Kedu ihe anyị ji nke a dozie?
Anyị nwere ihe dị ka 100 ndị na-ebubata ụlọ oriri na ọṅụṅụ, onye ọ bụla n'ime ha nwere ike inwe ọtụtụ njikọ, ka anyị kpọọ ya ọwa. Enwere ihe dịka 300 nke ọwa ndị a, ọwa ọ bụla nwere ike dapụ. N'ime metrik niile edekọtara, anyị ga-enyocha ọnụego njehie (arịrịọ na mperi).
Gịnị kpatara na ọ bụghị grafana?
Ngosipụta mperi ahaziri na Grafana nwere ọtụtụ ọghọm. Ụfọdụ dị oke egwu, ụfọdụ ị nwere ike imechi anya gị, dabere na ọnọdụ ahụ.
Grafana amaghị ka esi agbakọọ n'etiti nha + alerting, mana anyị chọrọ ọnụego (arịrịọ-njehie)/arịrịọ.
Njehie ndị ahụ na-adị njọ:

Na obere ihe ọjọọ mgbe a na-ele ya na arịrịọ na-aga nke ọma:

Ọ dị mma, anyị nwere ike buru ụzọ gbakọọ ọnụego na ọrụ tupu grafana, na n'ọnọdụ ụfọdụ nke a ga-arụ ọrụ. Ma ọ bụghị na nke anyị, n'ihi na ... maka ọwa ọ bụla a na-ewere oke nke ya dị ka "nkịtị", na ọkwa na-arụ ọrụ dịka ụkpụrụ static si dị (anyị na-ele anya anyị anya, gbanwee ma ọ bụrụ na enwere ọkwa ugboro ugboro).
Ndị a bụ ọmụmaatụ “nkịtị” maka ọwa dị iche iche:


Anyị na-eleghara isi okwu gara aga anya wee chee na foto "nkịtị" yiri nke ndị na-eweta ihe niile. Ugbu a ihe niile dị mma, anyị nwere ike nweta ọkwa na grafana?
Anyị nwere ike, mana anyị achọghị n'ezie, n'ihi na anyị ga-ahọrọ otu n'ime nhọrọ:
a) mee ọtụtụ eserese maka ọwa ọ bụla iche iche (ma soro ha na-egbu mgbu)
b) hapụ otu eserese na ọwa niile (ma tufuo n'ahịrị mara mma yana ọkwa ahaziri ahazi)

Kedu ka i si mee ya?
Ọzọ, enwere ezigbo ihe atụ mmalite na akwụkwọ (), enwere ike ilele ma ọ bụ were dị ka ihe ndabere na nsogbu ndị yiri ya.
Ihe anyị mere n'ikpeazụ:
- sonyere usoro abụọ n'ime awa ole na ole, na-ejikọta site na ọwa;
- dejupụta usoro site na otu ma ọ bụrụ na enweghị data;
- tụnyere etiti nke nkeji 10 ikpeazụ na data gara aga;
- anyị na-eti mkpu ma anyị chọta ihe;
- anyị na-ede ọnụego agbakọrọ na ọkwa nke mere na influxdb;
- zipu ozi bara uru ka ọ daa.
N'uche nke m, anyị jisiri ike nweta ihe niile anyị chọrọ iji nweta na njedebe (na ọbụna ntakịrị ihe na ndị na-edozi omenala) dị ka ihe mara mma dị ka o kwere mee.
Ị nwere ike lelee github.com и edemede nke pụta.
Ọmụmaatụ nke koodu gapụtara:
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)
Gịnị bụ nkwubi okwu ahụ?
Kapacitor dị mma n'ịrụ ọkwa nleba anya yana ọtụtụ ndị otu, na-eme ngụkọ ndị ọzọ dabere na metrik edekọgoro, na-eme omume omenala na scripts na-agba ọsọ (udf).
Ihe mgbochi ịbanye adịghị oke elu - nwaa ya ma ọ bụrụ na grafana ma ọ bụ ngwaọrụ ndị ọzọ emezughị ọchịchọ gị.
isi: www.habr.com
