Π’Ρ€ΠΈΠΊΠΎΠ²Π΅ Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π² Kapacitor.

ВСроятно, днСс Π²Π΅Ρ‡Π΅ Π½ΠΈΠΊΠΎΠΉ Π½Π΅ поставя ΠΏΠΎΠ΄ Π²ΡŠΠΏΡ€ΠΎΡ нСобходимостта ΠΎΡ‚ ΡΡŠΠ±ΠΈΡ€Π°Π½Π΅ Π½Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π½Π° услугитС. Π‘Π»Π΅Π΄Π²Π°Ρ‰Π°Ρ‚Π° Π»ΠΎΠ³ΠΈΡ‡Π½Π° ΡΡ‚ΡŠΠΏΠΊΠ° Π΅ Π΄Π° настроитС оповСстяванС Π·Π° ΡΡŠΠ±Ρ€Π°Π½ΠΈΡ‚Π΅ ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ, ΠΊΠΎΠ΅Ρ‚ΠΎ Ρ‰Π΅ увСдомява Π·Π° всяко ΠΎΡ‚ΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΠ΅ Π² Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΏΠΎ ΡƒΠ΄ΠΎΠ±Π½ΠΈ Π·Π° вас ΠΊΠ°Π½Π°Π»ΠΈ (ΠΈΠΌΠ΅ΠΉΠ», Slack, Telegram). Π’ услугата Π·Π° ΠΎΠ½Π»Π°ΠΉΠ½ рСзСрвация Π½Π° Ρ…ΠΎΡ‚Π΅Π»ΠΈ Ostrovok.ru всички ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π½Π° Π½Π°ΡˆΠΈΡ‚Π΅ услуги сС ΡΡŠΠ±ΠΈΡ€Π°Ρ‚ Π² InfluxDB ΠΈ сС ΠΏΠΎΠΊΠ°Π·Π²Π°Ρ‚ Π² Grafana, Ρ‚Π°ΠΌ ΡΡŠΡ‰ΠΎ Π΅ настроСно основно оповСстяванС. Π—Π° Π·Π°Π΄Π°Ρ‡ΠΈ ΠΊΠ°Ρ‚ΠΎ β€žΡ‚Ρ€Π΅Π±Π° Π΄Π° сС изчисли Π½Π΅Ρ‰ΠΎ ΠΈ Π΄Π° сС сравни с Ρ‚ΠΎΠ²Π°β€œ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Kapacitor.

Π’Ρ€ΠΈΠΊΠΎΠ²Π΅ Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π² Kapacitor.
Kapacitor Π΅ част ΠΎΡ‚ TICK стСка, ΠΊΠΎΠΉΡ‚ΠΎ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Π²Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ ΠΎΡ‚ InfluxDB. Π’ΠΎΠΉ ΠΌΠΎΠΆΠ΅ Π΄Π° ΡΠ²ΡŠΡ€ΠΆΠ΅ няколко измСрСния ΠΏΠΎΠΌΠ΅ΠΆΠ΄Ρƒ си (join), Π΄Π° изчисли Π½Π΅Ρ‰ΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΠΎΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ, Π΄Π° запишС Ρ€Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚Π° ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ Π² InfluxDB, Π΄Π° ΠΈΠ·ΠΏΡ€Π°Ρ‚ΠΈ оповСстяванС Π² Slack/Twitter/ΠΈΠΌΠ΅ΠΉΠ».

ЦСлият стСк ΠΈΠΌΠ° впСчатляваща ΠΈ ΠΏΠΎΠ΄Ρ€ΠΎΠ±Π½Π° докумСнтацията, Π½ΠΎ Π²ΠΈΠ½Π°Π³ΠΈ ΠΈΠΌΠ° ΠΏΠΎΠ»Π΅Π·Π½ΠΈ Π½Π΅Ρ‰Π°, ΠΊΠΎΠΈΡ‚ΠΎ Π½Π΅ са ясно ΡƒΠΊΠ°Π·Π°Π½ΠΈ Π² Ρ€ΡŠΠΊΠΎΠ²ΠΎΠ΄ΡΡ‚Π²Π°Ρ‚Π°. Π’ Ρ‚Π°Π·ΠΈ статия Ρ€Π΅ΡˆΠΈΡ… Π΄Π° ΡΡŠΠ±Π΅Ρ€Π° сСрия ΠΎΡ‚ ΠΏΠΎΠ»Π΅Π·Π½ΠΈ ΠΈ Π½Π΅ΠΎΡ‡Π΅Π²ΠΈΠ΄Π½ΠΈ ΡΡŠΠ²Π΅Ρ‚ΠΈ (основният синтаксис Π½Π° TICKscipt Π΅ описан Ρ‚ΡƒΠΊ.) ΠΈ Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ° ΠΊΠ°ΠΊ ΠΌΠΎΠ³Π°Ρ‚ Π΄Π° сС ΠΏΡ€ΠΈΠ»Π°Π³Π°Ρ‚, Π½Π° ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° Π½Π° Ρ€Π΅ΡˆΠ°Π²Π°Π½Π΅ Π½Π° Π΅Π΄Π½Π° ΠΎΡ‚ Π½Π°ΡˆΠΈΡ‚Π΅ Π·Π°Π΄Π°Ρ‡ΠΈ.

Π₯Π°ΠΉΠ΄Π΅ Π΄Π° Π·Π°ΠΏΠΎΡ‡Π²Π°ΠΌΠ΅!

float & int, Π³Ρ€Π΅ΡˆΠΊΠΈ Π² изчислСнията

ΠΠ±ΡΠΎΠ»ΡŽΡ‚Π½ΠΎ стандартСн ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ, Ρ€Π΅ΡˆΠ°Π²Π° сС Ρ‡Ρ€Π΅Π· cast:

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

ИзползванС на default()

Ако Ρ‚Π°Π³/ΠΏΠΎΠ»Π΅ Π½Π΅ Π΅ попълнСно, Ρ‰Π΅ Π²ΡŠΠ·Π½ΠΈΠΊΠ½Π°Ρ‚ Π³Ρ€Π΅ΡˆΠΊΠΈ Π² изчислСнията:

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

fill Π² join (inner vs outer)

По ΠΏΠΎΠ΄Ρ€Π°Π·Π±ΠΈΡ€Π°Π½Π΅ join ΠΎΡ‚Ρ…Π²ΡŠΡ€Π»Ρ Ρ‚ΠΎΡ‡ΠΊΠΈΡ‚Π΅, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ няма Π΄Π°Π½Π½ΠΈ (inner).
ΠŸΡ€ΠΈ fill(β€˜null’) Ρ‰Π΅ бъдС изпълнСн outer join, слСд ΠΊΠΎΠ΅Ρ‚ΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ default() ΠΈ Π΄Π° сС Π·Π°ΠΏΡŠΠ»Π½ΡΡ‚ ΠΏΡ€Π°Π·Π½ΠΈΡ‚Π΅ стойности:

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

Π’ΡƒΠΊ всС ΠΏΠ°ΠΊ ΠΈΠΌΠ° нюанс. Ако Π² ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π° ΠΏΠΎ-Π³ΠΎΡ€Π΅ Π΅Π΄Π½Π° ΠΎΡ‚ сСриитС (res1 ΠΈΠ»ΠΈ res2) Π΅ ΠΏΡ€Π°Π·Π½Π°, ΠΊΡ€Π°ΠΉΠ½Π°Ρ‚Π° сСрия (data) ΡΡŠΡ‰ΠΎ Ρ‰Π΅ бъдС ΠΏΡ€Π°Π·Π½Π°. Има няколко Ρ‚ΠΈΠΊΠ°Π΅Ρ‚Π° Π½Π° GitHub ΠΏΠΎ Ρ‚Π°Π·ΠΈ Ρ‚Π΅ΠΌΠ° (1633, 1871, 6967) – Ρ‡Π°ΠΊΠ°ΠΌΠ΅ ΠΏΠΎΠΏΡ€Π°Π²ΠΊΠΈ ΠΈ ΠΌΠ°Π»ΠΊΠΎ страдамС.

ИзползванС Π½Π° условия Π² изчислСнията (if Π² lambda)

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

ΠŸΠΎΡΠ»Π΅Π΄Π½ΠΈΡ‚Π΅ ΠΏΠ΅Ρ‚ ΠΌΠΈΠ½ΡƒΡ‚ΠΈ ΠΎΡ‚ ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π° Π·Π° ΠΏΠ΅Ρ€ΠΈΠΎΠ΄

НапримСр, Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π΅ Π΄Π° сравнитС стойноститС Π½Π° послСднитС ΠΏΠ΅Ρ‚ ΠΌΠΈΠ½ΡƒΡ‚ΠΈ с ΠΏΡ€Π΅Π΄Ρ…ΠΎΠ΄Π½Π°Ρ‚Π° сСдмица. ΠœΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²Π·Π΅ΠΌΠ΅Ρ‚Π΅ Π΄Π²Π΅ ΠΏΠ°Ρ€Ρ‚ΠΈΠ΄ΠΈ Π΄Π°Π½Π½ΠΈ Π² Π΄Π²Π΅ ΠΎΡ‚Π΄Π΅Π»Π½ΠΈ ΠΏΠ°Ρ€Ρ‚ΠΈΠ΄ΠΈ ΠΈΠ»ΠΈ Π΄Π° ΠΈΠ·Π²Π»Π΅Ρ‡Π΅Ρ‚Π΅ част ΠΎΡ‚ Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΎΡ‚ ΠΏΠΎ-голям ΠΏΠ΅Ρ€ΠΈΠΎΠ΄:

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

АлтСрнатива Π·Π° послСднитС ΠΏΠ΅Ρ‚ ΠΌΠΈΠ½ΡƒΡ‚ΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° бъдС ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅Ρ‚ΠΎ Π½Π° BarrierNode, ΠΊΠΎΠΉΡ‚ΠΎ отрязва Π΄Π°Π½Π½ΠΈ ΠΏΠΎ-Ρ€Π°Π½ΠΎ ΠΎΡ‚ Π·Π°Π΄Π°Π΄Π΅Π½ΠΎΡ‚ΠΎ Π²Ρ€Π΅ΠΌΠ΅:

|barrier()
        .period(5m)

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Go шаблони Π² ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅

Π¨Π°Π±Π»ΠΎΠ½ΠΈΡ‚Π΅ отговарят Π½Π° Ρ„ΠΎΡ€ΠΌΠ°Ρ‚Π° ΠΎΡ‚ ΠΏΠ°ΠΊΠ΅Ρ‚Π° text.template, ΠΏΠΎ-Π΄ΠΎΠ»Ρƒ няколко чСсто срСщани Π·Π°Π΄Π°Ρ‡ΠΈ.

if-else

Π‘Π»Π°Π³Π°ΠΌΠ΅ Ρ€Π΅Π΄, Π±Π΅Π· Π΄Π° ΠΏΡ€Π΅Π΄ΠΈΠ·Π²ΠΈΠΊΠ²Π°ΠΌΠ΅ Ρ…ΠΎΡ€Π°Ρ‚Π° с Π½Π΅Π½ΡƒΠΆΠ΅Π½ тСкст:

|alert()
    ...
    .message(
        '{{ if eq .Level "OK" }}Π‘Π΅Π³Π° Π΅ ΠΎΠΊ{{ else }}Π¨Π΅Ρ„Π΅, всичко Π΅ счупСно{{end}}'
    )

Π”Π²Π΅ Ρ†ΠΈΡ„Ρ€ΠΈ слСд запСтаята Π² ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ

ΠŸΠΎΠ΄ΠΎΠ±Ρ€ΡΠ²Π°ΠΌΠ΅ чСтивността Π½Π° ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ:

|alert()
    ...
    .message(
        'сСга стойността Π΅ {{ index .Fields "value" | printf "%0.2f" }}'
    )

Π Π°Π·Π³Ρ€ΡŠΡ‰Π°Π½Π΅ Π½Π° ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²ΠΈ Π² ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ

ИзвСТдамС ΠΏΠΎΠ²Π΅Ρ‡Π΅ информация Π² ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π·Π° ΠΎΡ‚Π³ΠΎΠ²ΠΎΡ€Π° Π½Π° Π²ΡŠΠΏΡ€ΠΎΡΠ° "Π—Π°Ρ‰ΠΎ Π²ΠΈΠΊΠ°?"

var warnAlert = 10
  |alert()
    ...
    .message(
       'Π”Π½Π΅ΡˆΠ½Π°Ρ‚Π° стойност Π΅ ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠ° ΠΎΡ‚ ' + string(warnAlert) + '%'
    )

Π£Π½ΠΈΠΊΠ°Π»Π΅Π½ ΠΈΠ΄Π΅Π½Ρ‚ΠΈΡ„ΠΈΠΊΠ°Ρ‚ΠΎΡ€ Π½Π° Π°Π»Π΅Ρ€Ρ‚Π°

НСобходимо Π΅, ΠΊΠΎΠ³Π°Ρ‚ΠΎ Π² Π΄Π°Π½Π½ΠΈΡ‚Π΅ ΠΈΠΌΠ° ΠΏΠΎΠ²Π΅Ρ‡Π΅ ΠΎΡ‚ Π΅Π΄Π½Π° Π³Ρ€ΡƒΠΏΠ°, ΠΈΠ½Π°Ρ‡Π΅ Ρ‰Π΅ сС Π³Π΅Π½Π΅Ρ€ΠΈΡ€Π° само Π΅Π΄ΠΈΠ½ Π°Π»Π΅Ρ€Ρ‚:

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

ΠŸΠ΅Ρ€ΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡ€Π°Π½ΠΈ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈ

Π’ голям списък ΠΎΡ‚ ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΡ†ΠΈ ΠΈΠΌΠ° exec, ΠΊΠΎΠΉΡ‚ΠΎ позволява ΠΈΠ·ΠΏΡŠΠ»Π½Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π° собствСн скрипт с ΠΏΡ€Π΅Π΄Π°Π΄Π΅Π½ΠΈΡ‚Π΅ ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ΠΈ (stdin) – само творчСство!

Π•Π΄ΠΈΠ½ ΠΎΡ‚ Π½Π°ΡˆΠΈΡ‚Π΅ пСрсонализирани Π΅ малък python скрипт Π·Π° ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°Π½Π΅ Π½Π° извСстия Π² Slack.
ΠŸΡŠΡ€Π²ΠΎΠ½Π°Ρ‡Π°Π»Π½ΠΎ искахмС Π΄Π° ΠΈΠ·ΠΏΡ€Π°Ρ‚ΠΈΠΌ Π² ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ ΠΊΠ°Ρ€Ρ‚ΠΈΠ½ΠΊΠ° ΠΎΡ‚ Grafana с авторизация. Π‘Π»Π΅Π΄ Ρ‚ΠΎΠ²Π° – Π΄Π° пишСм OK Π² Ρ‚Ρ€Π΅Π΄Π° Π½Π° ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈΡ Π°Π»Π΅Ρ€Ρ‚ ΠΎΡ‚ ΡΡŠΡ‰Π°Ρ‚Π° Π³Ρ€ΡƒΠΏΠ°, Π° Π½Π΅ ΠΊΠ°Ρ‚ΠΎ ΠΎΡ‚Π΄Π΅Π»Π½ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅. Малко ΠΏΠΎ-късно – Π΄Π° добавямС Π² ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅Ρ‚ΠΎ Π½Π°ΠΉ-чСстата Π³Ρ€Π΅ΡˆΠΊΠ° Π·Π° послСднитС Π₯ ΠΌΠΈΠ½ΡƒΡ‚ΠΈ.

ΠžΡ‚Π΄Π΅Π»Π½Π° Ρ‚Π΅ΠΌΠ° Π΅ ΡΠ²ΡŠΡ€Π·Π°Π½ΠΎΡΡ‚Ρ‚Π° с Π΄Ρ€ΡƒΠ³ΠΈ услуги ΠΈ ΠΊΠ°ΠΊΠ²ΠΈΡ‚ΠΎ ΠΈ Π΄Π° Π΅ дСйствия, ΠΈΠ½ΠΈΡ†ΠΈΠΈΡ€Π°Π½ΠΈ ΠΎΡ‚ Π°Π»Π΅Ρ€Ρ‚Π° (само Π°ΠΊΠΎ Π²Π°ΡˆΠΈΡΡ‚ ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ Ρ€Π°Π±ΠΎΡ‚ΠΈ Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΡ‡Π½ΠΎ Π΄ΠΎΠ±Ρ€Π΅).
ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° описаниС Π½Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚Ρ‡ΠΈΠΊΠ°, ΠΊΡŠΠ΄Π΅Ρ‚ΠΎ slack_handler.py – Π½Π°ΡˆΠΈΡΡ‚ самописан скрипт:

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"]

Как да дСбъгвамС?

Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ с ΠΈΠ·Ρ…ΠΎΠ΄ Π² Π»ΠΎΠ³

|log()
      .level("error")
      .prefix("Π½Π΅Ρ‰ΠΎ")

Π“Π»Π΅Π΄Π°ΠΉΡ‚Π΅ (cli): kapacitor -url host-or-ip:9092 logs lvl=error

Π’Π°Ρ€ΠΈΠ°Π½Ρ‚ с httpOut

Показва Π΄Π°Π½Π½ΠΈ Π² тСкущия ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½:

|httpOut('Π½Π΅Ρ‰ΠΎ')

Π“Π»Π΅Π΄Π°ΠΉΡ‚Π΅ (get): host-or-ip:9092\/kapacitor\/v1\/tasks\/task_name\/something

Π‘Ρ…Π΅ΠΌΠ° Π½Π° изпълнСниС

  • Всяка Π·Π°Π΄Π°Ρ‡Π° Π²Ρ€ΡŠΡ‰Π° Π΄ΡŠΡ€Π²ΠΎ Π½Π° изпълнСниС с ΠΏΠΎΠ»Π΅Π·Π½ΠΈ Ρ†ΠΈΡ„Ρ€ΠΈ във Ρ„ΠΎΡ€ΠΌΠ°Ρ‚ graphviz.
  • Π’Π·ΠΈΠΌΠ°ΠΌΠ΅ Π±Π»ΠΎΠΊΠ° dot.
  • Π’ΠΌΡŠΠΊΠ²Π°ΠΌΠ΅ Π² viewer, наслаТдавамС сС.

КъдС ΠΎΡ‰Π΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Π³Ρ€Π°Π±Π»ΠΈ

timestamp Π² influxdb ΠΏΡ€ΠΈ ΠΎΠ±Ρ€Π°Ρ‚Π½ΠΎ записванС

НапримСр, Π½ΠΈΠ΅ настройвамС Π°Π»Π°Ρ€ΠΌΠ° Π·Π° броя Π½Π° заявкитС Π½Π° час (groupBy(1h)) ΠΈ искамС Π΄Π° запишСм Π½Π°ΡΡ‚ΡŠΠΏΠΈΠ»Π°Ρ‚Π° Π°Π»Π°Ρ€ΠΌΠ° Π² influxdb (Π·Π° Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ красиво Ρ„Π°ΠΊΡ‚Π° Π·Π° Π½Π°Π»ΠΈΡ‡ΠΈΠ΅ Π½Π° ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π° Π³Ρ€Π°Ρ„ΠΈΠΊΠ° Π² grafana).

influxDBOut() Ρ‰Π΅ запишС Π² timestamp стойността time ΠΎΡ‚ Π°Π»Π°Ρ€ΠΌΠ°Ρ‚Π°, ΡΡŠΠΎΡ‚Π²Π΅Ρ‚Π½ΠΎ, Ρ‚ΠΎΡ‡ΠΊΠ°Ρ‚Π° Π½Π° Π³Ρ€Π°Ρ„ΠΈΠΊΠ° Ρ‰Π΅ бъдС записана ΠΏΠΎ-Ρ€Π°Π½ΠΎ/ΠΏΠΎ-късно ΠΎΡ‚ ΠΏΠΎΠ»ΡƒΡ‡Π΅Π½Π°Ρ‚Π° Π°Π»Π°Ρ€ΠΌΠ°.

ΠšΠΎΠ³Π°Ρ‚ΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠ° прСцизност: заобикалямС Ρ‚ΠΎΠ·ΠΈ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Ρ‡Ρ€Π΅Π· ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° пСрсонализиран handler, ΠΊΠΎΠΉΡ‚ΠΎ Ρ‰Π΅ запишС Π΄Π°Π½Π½ΠΈΡ‚Π΅ Π² influxdb с тСкущия timestamp.

docker, сборка ΠΈ Π΄Π΅ΠΏΠ»ΠΎΠΉ

ΠŸΡ€ΠΈ стартиранС Π½Π° kapacitor, Ρ‚ΠΎΠΉ ΠΌΠΎΠΆΠ΅ Π΄Π° Π·Π°Ρ€Π΅ΠΆΠ΄Π° Π·Π°Π΄Π°Ρ‡ΠΈ, шаблони ΠΈ Ρ…Π΅Π½Π΄Π»Π΅Ρ€ΠΈ ΠΎΡ‚ дирСкторията, Π·Π°Π΄Π°Π΄Π΅Π½Π° Π² конфигурацията, Π² Π±Π»ΠΎΠΊΠ° [load].

Π—Π° ΠΊΠΎΡ€Π΅ΠΊΡ‚Π½ΠΎ създаванС Π½Π° Π·Π°Π΄Π°Ρ‡Π° са Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΈ слСднитС Π½Π΅Ρ‰Π°:

  1. ИмС Π½Π° Ρ„Π°ΠΉΠ»Π° – Ρ€Π°Π·ΡˆΠΈΡ€ΡΠ²Π° сС Π² id/ΠΈΠΌΠ΅ Π½Π° скрипта
  2. Π’ΠΈΠΏ – stream/batch
  3. dbrp – ΠΊΠ»ΡŽΡ‡ΠΎΠ²Π° Π΄ΡƒΠΌΠ° Π·Π° ΡƒΠΊΠ°Π·Π²Π°Π½Π΅ Π² коя Π±Π°Π·Π° + ΠΏΠΎΠ»ΠΈΡ‚ΠΈΠΊΠ° Ρ€Π°Π±ΠΎΡ‚ΠΈ скрипта (dbrp Β«supplierΒ».Β«autogenΒ»)

Ако Π² някаква batch-Π·Π°Π΄Π°Ρ‡Π° няма Ρ€Π΅Π΄ с dbrp, цялата услуга Ρ‰Π΅ ΠΎΡ‚ΠΊΠ°ΠΆΠ΅ Π΄Π° стартира ΠΈ чСстно Ρ‰Π΅ напишС Π·Π° Ρ‚ΠΎΠ²Π° Π² Π»ΠΎΠ³ΠΎΠ²Π΅Ρ‚Π΅.

Π’ chronograf ΠΎΠ±Π°Ρ‡Π΅, ΠΏΡ€ΠΎΡ‚ΠΈΠ²Π½ΠΎ Π½Π° Ρ‚ΠΎΠ²Π°, Ρ‚ΠΎΠ·ΠΈ Ρ€Π΅Π΄ Π½Π΅ трябва Π΄Π° ΠΏΡ€ΠΈΡΡŠΡΡ‚Π²Π°, ΠΈΠ½Ρ‚Π΅Ρ€Ρ„Π΅ΠΉΡΡŠΡ‚ Π½Π΅ Π³ΠΎ ΠΏΡ€ΠΈΠ΅ΠΌΠ° ΠΈ ΠΈΠ·Π΄Π°Π²Π° Π³Ρ€Π΅ΡˆΠΊΠ°.

Π₯Π°ΠΊ ΠΏΡ€ΠΈ сборка Π½Π° ΠΊΠΎΠ½Ρ‚Π΅ΠΉΠ½Π΅Ρ€Π°: Dockerfile ΠΈΠ·Π»ΠΈΠ·Π° с -1, Π°ΠΊΠΎ ΠΈΠΌΠ° Ρ€Π΅Π΄ΠΎΠ²Π΅ с /.+dbrp, ΠΊΠΎΠ΅Ρ‚ΠΎ Ρ‰Π΅ ΠΏΠΎΠ·Π²ΠΎΠ»ΠΈ Π²Π΅Π΄Π½Π°Π³Π° Π΄Π° сС Ρ€Π°Π·Π±Π΅Ρ€Π΅ ΠΏΡ€ΠΈΡ‡ΠΈΠ½Π°Ρ‚Π° Π·Π° нСуспСха ΠΏΡ€ΠΈ сборка Π½Π° Π±ΠΈΠ»Π΄Π°.

join Сдин към много

Π—Π°Π΄Π°Ρ‡Π°-ΠΏΡ€ΠΈΠΌΠ΅Ρ€: трябва Π΄Π° Π²Π·Π΅ΠΌΠ΅ΠΌ 95-Ρ‚ΠΈ ΠΏΠ΅Ρ€Ρ†Π΅Π½Ρ‚ΠΈΠ» Π½Π° Π²Ρ€Π΅ΠΌΠ΅Ρ‚ΠΎ Π·Π° Ρ€Π°Π±ΠΎΡ‚Π° Π½Π° услугата Π·Π° сСдмица, Π΄Π° сравним всяка ΠΌΠΈΠ½ΡƒΡ‚Π° ΠΎΡ‚ послСднитС 10 с Ρ‚Π°Π·ΠΈ стойност.

НС ΠΌΠΎΠΆΠ΅ Π΄Π° сС Π½Π°ΠΏΡ€Π°Π²ΠΈ join Π΅Π΄ΠΈΠ½ към ΠΌΠ½ΠΎΠ³ΠΎ, last/mean/median ΠΏΠΎ Π³Ρ€ΡƒΠΏΠ° Ρ‚ΠΎΡ‡ΠΊΠΈ ΠΏΡ€Π΅Π²Ρ€ΡŠΡ‰Π°Ρ‚ Π½ΠΎΠ΄Π° Π² stream, Ρ‰Π΅ сС Π²ΡŠΡ€Π½Π΅ Π³Ρ€Π΅ΡˆΠΊΠ° Β«cannot add child mismatched edges: batch -> streamΒ».

Π Π΅Π·ΡƒΠ»Ρ‚Π°Ρ‚ΡŠΡ‚ ΠΎΡ‚ batch-Π°, ΠΊΠ°Ρ‚ΠΎ ΠΏΡ€ΠΎΠΌΠ΅Π½Π»ΠΈΠ²Π° Π² lambda-ΠΈΠ·Ρ€Π°Π·, ΡΡŠΡ‰ΠΎ Π½Π΅ сС подставя.

Има Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ Π΄Π° сС ΡΡŠΡ…Ρ€Π°Π½ΡΡ‚ Π½ΡƒΠΆΠ½ΠΈΡ‚Π΅ Ρ†ΠΈΡ„Ρ€ΠΈ ΠΎΡ‚ ΠΏΡŠΡ€Π²ΠΈΡ batch Π² Ρ„Π°ΠΉΠ» Ρ‡Ρ€Π΅Π· udf ΠΈ Π΄Π° сС Π·Π°Ρ€Π΅Π΄ΠΈ Ρ‚ΠΎΠ·ΠΈ Ρ„Π°ΠΉΠ» Ρ‡Ρ€Π΅Π· sideload.

Какво Ρ€Π΅ΡˆΠ°Π²Π°Ρ…ΠΌΠ΅ с Ρ‚ΠΎΠ²Π°?

ИмамС ΠΎΠΊΠΎΠ»ΠΎ 100 доставчици Π½Π° Ρ…ΠΎΡ‚Π΅Π»ΠΈ, към всСки ΠΎΡ‚ тях ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΈΠΌΠ° няколко ΡΠ²ΡŠΡ€Π·Π²Π°Π½ΠΈΡ, Π½Π°Ρ€Π΅Ρ‡Π΅Π½ΠΈ ΠΊΠ°Π½Π°Π»ΠΈ. Π’Π΅Ρ…Π½ΠΈΡ‚Π΅ ΠΊΠ°Π½Π°Π»ΠΈ са ΠΎΠΊΠΎΠ»ΠΎ 300, всСки ΠΎΡ‚ ΠΊΠ°Π½Π°Π»ΠΈΡ‚Π΅ ΠΌΠΎΠΆΠ΅ Π΄Π° ΠΎΡ‚ΠΏΠ°Π΄Π½Π΅. ΠžΡ‚ всички записвани ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Ρ‰Π΅ наблюдавамС ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚Π° Π½Π° Π³Ρ€Π΅ΡˆΠΊΠΈ (requests ΠΈ errors).

Π—Π°Ρ‰ΠΎ Π½Π΅ Π³Ρ€Π°Ρ„Π°Π½Π°?

АлармитС Π·Π° Π³Ρ€Π΅ΡˆΠΊΠΈ, настроСни Π² Π³Ρ€Π°Ρ„Π°Π½Π°, ΠΈΠΌΠ°Ρ‚ няколко Π½Π΅Π΄ΠΎΡΡ‚Π°Ρ‚ΡŠΠΊΠ°. Някои ΠΎΡ‚ тях са ΠΊΡ€ΠΈΡ‚ΠΈΡ‡Π½ΠΈ, Π½Π° някои ΠΌΠΎΠΆΠ΅ Π΄Π° сС затворят ΠΎΡ‡ΠΈ, Π² зависимост ΠΎΡ‚ ситуацията.

Π“Ρ€Π°Ρ„Π°Π½Π° Π½Π΅ ΡƒΠΌΠ΅Π΅ Π΄Π° ΠΏΡ€Π°Π²ΠΈ изчислСния ΠΌΠ΅ΠΆΠ΄Ρƒ измСрвания + Π°Π»Π°Ρ€ΠΌΠΈΡ€Π°Π½Π΅, Π° Π½ΠΈΠ΅ сС Π½ΡƒΠΆΠ΄Π°Π΅ΠΌ ΠΎΡ‚ ΠΏΡ€ΠΎΡ†Π΅Π½Ρ‚Π° (requests-errors)/requests.

Π“Ρ€Π΅ΡˆΠΊΠΈΡ‚Π΅ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Ρ‚ Π·Π»ΠΎΠ±Π½ΠΎ:

Π’Ρ€ΠΈΠΊΠΎΠ²Π΅ Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π² Kapacitor.

И ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ Π·Π»ΠΎΠ±Π½ΠΎ, Π°ΠΊΠΎ сС Π³Π»Π΅Π΄Π° с ΡƒΡΠΏΠ΅ΡˆΠ½ΠΈΡ‚Π΅ заявки:

Π’Ρ€ΠΈΠΊΠΎΠ²Π΅ Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π² Kapacitor.

Π”ΠΎΠ±Ρ€Π΅, ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡ€Π΅Π΄Π²Π°Ρ€ΠΈΡ‚Π΅Π»Π½ΠΎ Π΄Π° изчислим Ρ€Π΅ΠΉΡ‚ Π² услугата ΠΏΡ€Π΅Π΄ΠΈ Π³Ρ€Π°Ρ„Π°Π½Π°Ρ‚Π°, ΠΈ Π² някои случаи Ρ‚ΠΎΠ²Π° Π±ΠΈ Π±ΠΈΠ»ΠΎ подходящо. Но Π½Π΅ Π² нашия случай, Ρ‚ΡŠΠΉ ΠΊΠ°Ρ‚ΠΎ Π·Π° всСки ΠΊΠ°Π½Π°Π» сС изчислява β€žΠ½ΠΎΡ€ΠΌΠ°Π»Π½ΠΎβ€œ ΡΠΎΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΠ΅, Π° Π°Π»Π°Ρ€ΠΌΠΈΡ‚Π΅ работят ΠΏΠΎ статични стойности (Ρ‚ΡŠΡ€ΡΠΈΠΌ Π½Π° ΠΎΠΊΠΎ, промСнямС, Π°ΠΊΠΎ Π°Π»Π°Ρ€ΠΌΠΈΡ€Π° чСсто).

Π’ΠΎΠ²Π° са ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΈ Π·Π° β€žΠ½ΠΎΡ€ΠΌΠ°Π»Π½ΠΎβ€œ Π·Π° Ρ€Π°Π·Π»ΠΈΡ‡Π½ΠΈ ΠΊΠ°Π½Π°Π»ΠΈ:

Π’Ρ€ΠΈΠΊΠΎΠ²Π΅ Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π² Kapacitor.

Π’Ρ€ΠΈΠΊΠΎΠ²Π΅ Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π² Kapacitor.

ΠŸΡ€Π΅Π½Π΅Π±Ρ€Π΅Π³Π²Π°ΠΌΠ΅ ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½Π°Ρ‚Π° Ρ‚ΠΎΡ‡ΠΊΠ° ΠΈ ΠΏΡ€ΠΈΠ΅ΠΌΠ°ΠΌΠ΅, Ρ‡Π΅ ΠΏΡ€ΠΈ всички доставчици ΠΊΠ°Ρ€Ρ‚ΠΈΠ½Π°Ρ‚Π° Π΅ β€žΠ½ΠΎΡ€ΠΌΠ°Π»Π½Π°β€œ. Π‘Π΅Π³Π° всичко Π΅ Π½Π°Ρ€Π΅Π΄, ΠΈ ΠΌΠΎΠΆΠ΅ΠΌ Π»ΠΈ Π΄Π° сС справим с Π°Π»Π°Ρ€ΠΌΠΈΡ‚Π΅ Π² Π³Ρ€Π°Ρ„Π°Π½Π°Ρ‚Π°?
МоТСм, Π½ΠΎ Π½Π΅ ΠΌΠΈ сС иска, Π·Π°Ρ‰ΠΎΡ‚ΠΎ трябва Π΄Π° ΠΈΠ·Π±Π΅Ρ€Π΅ΠΌ Π΅Π΄ΠΈΠ½ ΠΎΡ‚ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚ΠΈΡ‚Π΅:
Π°) Π΄Π° Π½Π°ΠΏΡ€Π°Π²ΠΈΠΌ мноТСство Π³Ρ€Π°Ρ„ΠΈΠΊΠΈ Π·Π° всСки ΠΊΠ°Π½Π°Π» ΠΏΠΎΠΎΡ‚Π΄Π΅Π»Π½ΠΎ (ΠΈ ΠΌΡŠΡ‡ΠΈΡ‚Π΅Π»Π½ΠΎ Π΄Π° Π³ΠΈ ΠΏΠΎΠ΄Π΄ΡŠΡ€ΠΆΠ°ΠΌΠ΅)
Π±) Π΄Π° оставим Π΅Π΄Π½Π° Π³Ρ€Π°Ρ„ΠΈΠΊΠ° с всички ΠΊΠ°Π½Π°Π»ΠΈ (ΠΈ Π΄Π° сС Π·Π°Π³ΡƒΠ±ΠΈΠΌ Π² Ρ†Π²Π΅Ρ‚Π½ΠΈ Π»ΠΈΠ½ΠΈΠΈ ΠΈ настроСни Π°Π»Π°Ρ€ΠΌΠΈ)

Π’Ρ€ΠΈΠΊΠΎΠ²Π΅ Π·Π° ΠΎΠ±Ρ€Π°Π±ΠΎΡ‚ΠΊΠ° Π½Π° ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ Π² Kapacitor.

Какво Π½Π°ΠΏΡ€Π°Π²ΠΈΡ…ΠΌΠ΅?

ΠžΡ‚Π½ΠΎΠ²ΠΎ, Π² докумСнтацията ΠΈΠΌΠ° Π΄ΠΎΠ±ΡŠΡ€ стартов ΠΏΡ€ΠΈΠΌΠ΅Ρ€ (Π˜Π·Ρ‡ΠΈΡΠ»ΡΠ²Π°Π½Π΅ Π½Π° Ρ€Π΅ΠΉΡ‚ΠΎΠ²Π΅ Π·Π° ΡΠ²ΡŠΡ€Π·Π°Π½ΠΈ сСрии), ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Π½Π°Π΄Π½ΠΈΠΊΠ½Π΅ΠΌ ΠΈΠ»ΠΈ Π΄Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°ΠΌΠ΅ Π·Π° основа Π² Π°Π½Π°Π»ΠΎΠ³ΠΈΡ‡Π½ΠΈ Π·Π°Π΄Π°Ρ‡ΠΈ.

Какво Π½Π°ΠΏΡ€Π°Π²ΠΈΡ…ΠΌΠ΅ Π² ΠΊΡ€Π°ΠΉΠ½Π° смСтка:

  • ΠΎΠ±Π΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π½Π° Π΄Π²Π΅ сСрии Π·Π° няколко часа, Π³Ρ€ΡƒΠΏΠΈΡ€Π°Π½Π΅ ΠΏΠΎ ΠΊΠ°Π½Π°Π»ΠΈ;
  • попълвамС сСриитС ΠΏΠΎ Π³Ρ€ΡƒΠΏΠΈ, Π°ΠΊΠΎ няма Π΄Π°Π½Π½ΠΈ;
  • сравнявамС ΠΌΠ΅Π΄ΠΈΠ°Π½Π°Ρ‚Π° Π½Π° послСднитС 10 ΠΌΠΈΠ½ΡƒΡ‚ΠΈ с ΠΏΡ€Π΅Π΄ΠΈΡˆΠ½ΠΈΡ‚Π΅ Π΄Π°Π½Π½ΠΈ;
  • Π²ΠΈΠΊΠΎΠ²Π΅, Π°ΠΊΠΎ ΠΎΡ‚ΠΊΡ€ΠΈΠ΅ΠΌ Π½Π΅Ρ‰ΠΎ;
  • пишСм изчислСнитС Ρ€Π΅ΠΉΡ‚ΠΎΠ²Π΅ ΠΈ случилитС сС Π°Π»Π°Ρ€ΠΌΠΈ Π² influxdb;
  • ΠΈΠ·ΠΏΡ€Π°Ρ‰Π°ΠΌΠ΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΡΡŠΠΎΠ±Ρ‰Π΅Π½ΠΈΠ΅ Π² slack.

По ΠΌΠΎΠ΅ ΠΌΠ½Π΅Π½ΠΈΠ΅, успяхмС Π΄Π° постигнСм максимално приятно всичко, ΠΊΠΎΠ΅Ρ‚ΠΎ искахмС Π΄Π° ΠΏΠΎΠ»ΡƒΡ‡ΠΈΠΌ Π½Π° ΠΈΠ·Ρ…ΠΎΠ΄Π° (ΠΈ Π΄ΠΎΡ€ΠΈ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎΠ²Π΅Ρ‡Π΅ с пСрсонализирани Ρ…Π΅Π½Π΄Π»Π΅Ρ€ΠΈ).

На github.com ΠΌΠΎΠΆΠ΅Ρ‚Π΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡ‚Π΅ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅Π½ ΠΊΠΎΠ΄ ΠΈ ΠΌΠΈΠ½ΠΈΠΌΠ°Π»Π½Π° схСма (graphviz) Π½Π° получСния скрипт.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€ Π·Π° получСния ΠΊΠΎΠ΄:

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)  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=UTC0300'
 )
 .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)

Какъв Ρ‰Π΅ бъдС ΠΈΠ·Ρ…ΠΎΠ΄ΡŠΡ‚?

Kapacitor прСкрасно позволява ΠΌΠΎΠ½ΠΈΡ‚ΠΎΡ€ΠΈΠ½Π³ ΠΈ Π°Π»Π΅Ρ€Ρ‚ΠΈΡ€Π°Π½Π΅ с мноТСство Π³Ρ€ΡƒΠΏΠΈΡ€ΠΎΠ²ΠΊΠΈ, ΠΈΠ·Π²ΡŠΡ€ΡˆΠ²Π° Π΄ΠΎΠΏΡŠΠ»Π½ΠΈΡ‚Π΅Π»Π½ΠΈ изчислСния Π½Π° Π²Π΅Ρ‡Π΅ записани ΠΌΠ΅Ρ‚Ρ€ΠΈΠΊΠΈ, ΠΏΡ€Π΅Π΄Π»Π°Π³Π° пСрсонализирани дСйствия ΠΈ стартира скриптовС (udf).

ΠŸΡ€Π°Π³ΡŠΡ‚ Π·Π° Π²ΠΊΠ»ΡŽΡ‡Π²Π°Π½Π΅ Π½Π΅ Π΅ ΠΌΠ½ΠΎΠ³ΠΎ висок – ΠΎΠΏΠΈΡ‚Π°ΠΉΡ‚Π΅ Π³ΠΎ, Π°ΠΊΠΎ Grafana ΠΈΠ»ΠΈ Π΄Ρ€ΡƒΠ³ΠΈ инструмСнти Π½Π΅ удовлСтворяват изцяло Π²Π°ΡˆΠΈΡ‚Π΅ изисквания.

Π˜Π·Ρ‚ΠΎΡ‡Π½ΠΈΠΊ: habr.com

ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ πŸ”₯ ΠšΡƒΠΏΠ΅Ρ‚Π΅ Π½Π°Π΄Π΅ΠΆΠ΄Π΅Π½ хостинг Π·Π° сайтовС със Π·Π°Ρ‰ΠΈΡ‚Π° ΠΎΡ‚ DDoS, VPS ΠΈ VDS ΡΡŠΡ€Π²ΡŠΡ€ΠΈ | ProHoster