Kabeh tumpukan kelangan lan rinci dokumentasi, nanging mesthi ana barang sing migunani sing ora dituduhake kanthi jelas ing manual. Ing artikel iki, aku mutusake kanggo ngumpulake sawetara tips sing migunani lan ora jelas (sintaks dhasar TICKscipt diterangake kene) lan tuduhake carane bisa ditrapake nggunakake conto kanggo ngrampungake salah sawijining masalah.
Ayo ayo!
float & int, kasalahan pitungan
Masalah standar, ditanggulangi liwat kasta:
var alert_float = 5.0
var alert_int = 10
data|eval(lambda: float("value") > alert_float OR float("value") < float("alert_int"))
Nggunakake standar ()
Yen tag/kolom ora diisi, kesalahan pitungan bakal kedadeyan:
Kanthi gawan, gabung bakal ngilangi titik sing ora ana data (inner).
Kanthi fill('null'), gabungan njaba bakal dileksanakake, sawise sampeyan kudu nindakake standar () lan isi ing nilai kosong:
var data = res1
|join(res2)
.as('res1', 'res2)
.fill('null')
|default()
.field('res1.value', 0.0)
.field('res2.value', 100.0)
Ing kene isih ana nuansa. Ing conto ing ndhuwur, yen salah siji saka seri (res1 utawa res2) kosong, seri asil (data) uga bakal kosong. Ana sawetara tiket babagan topik iki ing Github (1633, 1871, 6967) - kita nunggu perbaikan lan nandhang sangsara sethithik.
Nggunakake kahanan ing petungan (yen ing lambda)
|eval(lambda: if("value" > 0, true, false)
Limang menit pungkasan saka pipa kanggo periode kasebut
Contone, sampeyan kudu mbandhingake nilai limang menit pungkasan karo minggu sadurunge. Sampeyan bisa njupuk rong kumpulan data ing rong kumpulan sing kapisah utawa ngekstrak bagean data saka periode sing luwih gedhe:
Topik sing kapisah yaiku komunikasi karo layanan liyane lan tumindak apa wae sing diwiwiti kanthi tandha (mung yen pemantauan sampeyan bisa digunakake kanthi apik).
Conto katrangan panangan, ing ngendi slack_handler.py minangka skrip sing ditulis dhewe:
Contone, kita nyiyapake tandha kanggo jumlah panjalukan saben jam (groupBy(1h)) lan pengin ngrekam tandha sing kedadeyan ing influxdb (kanggo apik nuduhake kasunyatan masalah ing grafik ing grafana).
influxDBOut () bakal nulis nilai wektu saka tandha menyang timestamp; mula, titik ing grafik bakal ditulis luwih awal / luwih saka tandha teka.
Nalika akurasi dibutuhake: kita ngatasi masalah iki kanthi nelpon pawang khusus, sing bakal nulis data menyang influxdb karo cap wektu saiki.
docker, mbangun lan panyebaran
Nalika wiwitan, kapacitor bisa mbukak tugas, template lan panangan saka direktori sing ditemtokake ing konfigurasi ing blok [load].
Kanggo nggawe tugas kanthi bener, sampeyan butuh perkara ing ngisor iki:
Jeneng berkas β ditambahi dadi skrip id/jeneng
Tipe - stream / batch
dbrp β tembung kunci kanggo nunjukake basis data + kabijakan skrip kasebut (dbrp "pemasok." "autogen")
Yen sawetara tugas batch ora ngemot baris karo dbrp, kabeh layanan bakal nolak miwiti lan bakal nulis kanthi jujur ββbabagan kasebut ing log.
Ing chronograf, sebaliknya, baris iki ora kudu ana, ora ditampa liwat antarmuka lan nggawe kesalahan.
Hack nalika mbangun wadhah: Dockerfile metu karo -1 yen ana baris karo //.+dbrp, sing bakal ngidini sampeyan langsung ngerti alesan kanggo Gagal nalika assembling mbangun.
gabung siji kanggo akeh
Conto tugas: sampeyan kudu njupuk persentil kaping 95 saka wektu operasi layanan sajrone seminggu, mbandhingake saben menit saka 10 pungkasan kanthi nilai iki.
Sampeyan ora bisa nindakake siji-kanggo-akeh gabung, pungkasan / tegese / median liwat klompok TCTerms nguripake simpul menyang stream, kesalahan "ora bisa nambah pinggiran anak mismatched: kumpulan -> stream" bakal bali.
Asil saka kumpulan, minangka variabel ing ekspresi lambda, uga ora diganti.
Ana pilihan kanggo nyimpen nomer sing dibutuhake saka kumpulan pisanan menyang file liwat udf lan mbukak file iki liwat sideload.
Apa kita ngatasi iki?
Kita duwe sekitar 100 supplier hotel, saben wong bisa duwe sawetara sambungan, ayo diarani saluran. Ana kira-kira 300 saluran kasebut, saben saluran bisa tiba. Saka kabeh metrik sing direkam, kita bakal ngawasi tingkat kesalahan (panjaluk lan kesalahan).
Kok ora grafana?
Tandha kesalahan sing dikonfigurasi ing Grafana duwe sawetara kekurangan. Sawetara kritis, sawetara sampeyan bisa nutup mata, gumantung saka kahanan.
Grafana ora ngerti carane ngetung antarane pangukuran + alerting, nanging kita kudu tingkat (requests-errors) / requests.
Kesalahan katon ala:
Lan kurang ala yen dideleng kanthi panjaluk sing sukses:
Oke, kita bisa ngetung tarif ing layanan sadurunge grafana, lan ing sawetara kasus iki bakal bisa. Nanging ora ing kita, amarga ... kanggo saben saluran, rasio dhewe dianggep "normal", lan tandha bisa digunakake miturut nilai statis (kita goleki kanthi mripat, ganti yen ana tandha asring).
Iki minangka conto "normal" kanggo macem-macem saluran:
Kita nglirwakake titik sadurunge lan nganggep yen gambar "normal" padha kanggo kabeh supplier. Saiki kabeh wis apik, lan kita bisa entuk tandha ing grafana?
Kita bisa, nanging kita pancene ora pengin, amarga kita kudu milih salah siji opsi:
a) nggawe akeh grafik kanggo saben saluran kanthi kapisah (lan ngiringi kanthi lara)
b) ninggalake siji grafik karo kabeh saluran (lan ilang ing garis warni lan tandha khusus)
Kepiye carane sampeyan nindakake?
Maneh, ana conto wiwitan sing apik ing dokumentasi (Ngitung tarif antarane seri gabungan), bisa dideleng utawa dijupuk minangka basis ing masalah sing padha.
Apa sing ditindakake ing pungkasan:
gabung karo rong seri sajrone sawetara jam, dikelompokake miturut saluran;
isi seri kanthi klompok yen ora ana data;
mbandhingake rata-rata 10 menit pungkasan karo data sadurunge;
kita bengok-bengok yen ketemu;
kita nulis tarif sing diwilang lan tandha sing kedadeyan ing influxdb;
ngirim pesen migunani kanggo slack.
Ing mratelakake panemume, kita ngatur kanggo entuk kabeh kita wanted kanggo njaluk ing mburi (lan malah sethitik liyane karo handler adat) minangka apik sabisa.
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)
Lan apa kesimpulane?
Kapacitor gedhe ing nindakake ngawasi-tandha karo Bunch saka klompok, Performing petungan tambahan adhedhasar metrik wis direkam, nindakake tumindak adat lan mlaku Tulisan (udf).
Rintangan kanggo mlebu ora dhuwur banget - coba yen grafana utawa alat liyane ora bisa nyukupi kekarepan sampeyan.