ΠΠ΅ΡΠΎΡΡΠ½ΠΎ, ΡΠ΅Π³ΠΎΠ΄Π½Ρ ΡΠΆΠ΅ Π½ΠΈ Ρ ΠΊΠΎΠ³ΠΎ Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ Π²ΠΎΠΏΡΠΎΡ, Π·Π°ΡΠ΅ΠΌ ΡΠΎΠ±ΠΈΡΠ°ΡΡ ΠΌΠ΅ΡΡΠΈΠΊΠΈ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ². Π‘Π»Π΅Π΄ΡΡΡΠΈΠΉ Π»ΠΎΠ³ΠΈΡΠ½ΡΠΉ ΡΠ°Π³ β Π½Π°ΡΡΡΠΎΠΈΡΡ Π°Π»Π΅ΡΡΠΈΠ½Π³ Π½Π° ΡΠΎΠ±ΡΠ°Π½Π½ΡΠ΅ ΠΌΠ΅ΡΡΠΈΠΊΠΈ, ΠΊΠΎΡΠΎΡΡΠΉ Π±ΡΠ΄Π΅Ρ ΡΠ²Π΅Π΄ΠΎΠΌΠ»ΡΡΡ ΠΎ Π»ΡΠ±ΡΡ ΠΎΡΠΊΠ»ΠΎΠ½Π΅Π½ΠΈΡΡ Π² Π΄Π°Π½Π½ΡΡ ΡΠ΅ΡΠ΅Π· ΡΠ΄ΠΎΠ±Π½ΡΠ΅ Π²Π°ΠΌ ΠΊΠ°Π½Π°Π»Ρ (ΠΏΠΎΡΡΡ, Slack, Telegram). Π ΡΠ΅ΡΠ²ΠΈΡΠ΅ ΠΎΠ½Π»Π°ΠΉΠ½-Π±ΡΠΎΠ½ΠΈΡΠΎΠ²Π°Π½ΠΈΡ ΠΎΡΠ΅Π»Π΅ΠΉ Π²ΡΠ΅ ΠΌΠ΅ΡΡΠΈΠΊΠΈ Π½Π°ΡΠΈΡ ΡΠ΅ΡΠ²ΠΈΡΠΎΠ² ΡΠΎΠ±ΠΈΡΠ°ΡΡΡΡ Π² InfluxDB ΠΈ ΠΎΡΠΎΠ±ΡΠ°ΠΆΠ°ΡΡΡΡ Π² Grafana, ΡΠ°ΠΌ ΠΆΠ΅ Π½Π°ΡΡΡΠΎΠ΅Π½ Π±Π°Π·ΠΎΠ²ΡΠΉ Π°Π»Π΅ΡΡΠΈΠ½Π³. ΠΠ»Ρ Π·Π°Π΄Π°Ρ Β«Π½ΡΠΆΠ½ΠΎ ΠΏΠΎΡΡΠΈΡΠ°ΡΡ ΡΡΠΎ-ΡΠΎ ΠΈ ΡΡΠ°Π²Π½ΠΈΡΡ Ρ ΡΡΠΈΠΌΒ» ΠΌΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅ΠΌ Kapacitor.

Kapacitor β ΡΡΠΎ ΡΠ°ΡΡΡ TICK-ΡΡΠ΅ΠΊΠ°, ΠΊΠΎΡΠΎΡΡΠΉ ΡΠΌΠ΅Π΅Ρ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡ ΠΌΠ΅ΡΡΠΈΠΊΠΈ ΠΈΠ· InfluxDB. ΠΠ½ ΠΌΠΎΠΆΠ΅Ρ ΠΎΠ±ΡΠ΅Π΄ΠΈΠ½ΠΈΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΠΈΠ·ΠΌΠ΅ΡΠ΅Π½ΠΈΠΉ (join), ΠΈΠ· ΠΏΠΎΠ»ΡΡΠ΅Π½Π½ΡΡ
Π΄Π°Π½Π½ΡΡ
Π²ΡΡΠΈΡΠ»ΠΈΡΡ ΡΡΠΎ-ΡΠΎ ΠΏΠΎΠ»Π΅Π·Π½ΠΎΠ΅, Π·Π°ΠΏΠΈΡΠ°ΡΡ ΡΠ΅Π·ΡΠ»ΡΡΠ°Ρ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ Π² InfluxDB ΠΈ ΠΎΡΠΏΡΠ°Π²ΠΈΡΡ Π°Π»Π΅ΡΡ Π² Slack/Telegram/ΠΏΠΎΡΡΡ.
ΠΠ΅ΡΡ ΡΡΠ΅ΠΊ ΠΈΠΌΠ΅Π΅Ρ ΠΎΡΠ»ΠΈΡΠ½ΡΡ ΠΈ ΠΏΠΎΠ΄ΡΠΎΠ±Π½ΡΡ , Π½ΠΎ Π²ΡΠ΅Π³Π΄Π° Π½Π°ΠΉΠ΄ΡΡΡΡ ΠΏΠΎΠ»Π΅Π·Π½ΡΠ΅ Π²Π΅ΡΠΈ, ΠΊΠΎΡΠΎΡΡΠ΅ Π½Π΅ ΡΠΊΠ°Π·Π°Π½Ρ Π² ΠΌΠ°Π½ΡΠ°Π»Π°Ρ . Π ΡΡΠΎΠΉ ΡΡΠ°ΡΡΠ΅ Ρ ΡΠ΅ΡΠΈΠ» ΡΠΎΠ±ΡΠ°ΡΡ ΡΡΠ΄ ΡΠ°ΠΊΠΈΡ ΠΏΠΎΠ»Π΅Π·Π½ΡΡ Π½Π΅ΠΎΡΠ΅Π²ΠΈΠ΄Π½ΡΡ ΡΠΎΠ²Π΅ΡΠΎΠ² (ΠΎΡΠ½ΠΎΠ²Π½ΠΎΠΉ ΡΠΈΠ½ΡΠ°ΠΊΡΠΈΡ TICKscipt ΠΎΠΏΠΈΡΠ°Π½ ) ΠΈ ΠΏΠΎΠΊΠ°Π·Π°ΡΡ, ΠΊΠ°ΠΊ ΠΈΡ ΠΌΠΎΠΆΠ½ΠΎ ΠΏΡΠΈΠΌΠ΅Π½ΡΡΡ, Π½Π° ΠΏΡΠΈΠΌΠ΅ΡΠ΅ ΡΠ΅ΡΠ΅Π½ΠΈΡ ΠΎΠ΄Π½ΠΎΠΉ ΠΈΠ· Π½Π°ΡΠΈΡ Π·Π°Π΄Π°Ρ.
ΠΠ° ΡΡΡΠ³Π²Π°ΠΌΠ΅!
float & int, ΠΎΡΠΈΠ±ΠΊΠΈ Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΠΉ
ΠΡΠΎ Π°Π±ΡΠΎΠ»ΡΡΠ½ΠΎ ΡΡΠ°Π½Π΄Π°ΡΡΠ½Π°Ρ ΠΏΡΠΎΠ±Π»Π΅ΠΌΠ°, ΡΠ΅ΡΠ°Π΅ΡΡΡ ΡΠ΅ΡΠ΅Π· ΠΊΠ°ΡΡ:
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) ΡΠ°ΠΊΠΆΠ΅ Π±ΡΠ΄Π΅Ρ ΠΏΡΡΡΠΎΠΉ. ΠΠ° ΡΡΡ ΡΠ΅ΠΌΡ Π΅ΡΡΡ Π½Π΅ΡΠΊΠΎΠ»ΡΠΊΠΎ ΡΠΈΠΊΠ΅ΡΠΎΠ² Π½Π° Π³ΠΈΡΡ Π°Π±Π΅ (, , ) β ΠΆΠ΄Π΅ΠΌ ΡΠΈΠΊΡΠΎΠ² ΠΈ Π½Π΅ΠΌΠ½ΠΎΠ³ΠΎ ΡΡΡΠ°Π΄Π°Π΅ΠΌ.
ΠΡΠΏΠΎΠ»ΡΠ·ΠΎΠ²Π°Π½ΠΈΠ΅ ΡΡΠ»ΠΎΠ²ΠΈΠΉ Π² Π²ΡΡΠΈΡΠ»Π΅Π½ΠΈΡΡ (if Π² lambda)
|eval(lambda: if("value" > 0, true, false)
ΠΠΎΡΠ»Π΅Π΄Π½ΠΈΠ΅ ΠΏΡΡΡ ΠΌΠΈΠ½ΡΡ ΠΈΠ· ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½Π° Π·Π° ΠΏΠ΅ΡΠΈΠΎΠ΄
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π²Π°ΠΌ Π½ΡΠΆΠ½ΠΎ ΡΡΠ°Π²Π½ΠΈΡΡ Π·Π½Π°ΡΠ΅Π½ΠΈΡ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡ ΠΏΡΡΠΈ ΠΌΠΈΠ½ΡΡ Ρ ΠΏΡΠ΅Π΄ΡΠ΄ΡΡΠ΅ΠΉ Π½Π΅Π΄Π΅Π»Π΅ΠΉ. ΠΠΎΠΆΠ½ΠΎ Π²Π·ΡΡΡ Π΄Π²Π΅ ΠΏΠ°ΡΠΊΠΈ Π΄Π°Π½Π½ΡΡ Π΄Π²ΡΠΌΡ ΠΎΡΠ΄Π΅Π»ΡΠ½ΡΠΌΠΈ batchβΠ°ΠΌΠΈ ΠΈΠ»ΠΈ Π²ΡΡΠ°ΡΠΈΡΡ ΡΠ°ΡΡΡ Π΄Π°Π½Π½ΡΡ ΠΈΠ· Π±ΠΎΠ»ΡΡΠ΅Π³ΠΎ ΠΏΠ΅ΡΠΈΠΎΠ΄Π°:
|where(lambda: duration((unixNano(now()) - unixNano("time"))/1000, 1u) < 5m)
ΠΠ»ΡΠ΅ΡΠ½Π°ΡΠΈΠ²Π°ΡΠ° Π·Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ ΠΏΠ΅Ρ ΠΌΠΈΠ½ΡΡΠΈ ΠΌΠΎΠΆΠ΅ Π΄Π° Π±ΡΠ΄Π΅ ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ΡΠΎ Π½Π° Π½ΠΎΠ΄Π°ΡΠ° BarrierNode, ΠΊΠΎΡΡΠΎ ΠΎΡΡΡΠ²Π° Π΄Π°Π½Π½ΠΈΡΠ΅ ΠΏΠΎ-ΡΠ°Π½ΠΎ ΠΎΡ Π·Π°Π΄Π°Π΄Π΅Π½ΠΎΡΠΎ Π²ΡΠ΅ΠΌΠ΅:
|barrier()
.period(5m)
ΠΡΠΈΠΌΠ΅ΡΠΈ Π·Π° ΠΈΠ·ΠΏΠΎΠ»Π·Π²Π°Π½Π΅ Π½Π° Go-ΡΠ°Π±Π»ΠΎΠ½ΠΈ Π² ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅
Π¨Π°Π±Π»ΠΎΠ½ΠΈΡΠ΅ ΠΎΡΠ³ΠΎΠ²Π°ΡΡΡ Π½Π° ΡΠΎΡΠΌΠ°ΡΠ° ΠΎΡ ΠΏΠ°ΠΊΠ΅ΡΠ° , ΠΏΠΎ-Π΄ΠΎΠ»Ρ ΡΠ° Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΡΠ΅ΡΡΠΎ ΡΡΠ΅ΡΠ°Π½ΠΈ Π·Π°Π΄Π°ΡΠΊΠΈ.
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 Π² ΡΡΠ΅Π΄Π° Π½Π° ΠΏΡΠ΅Π΄ΠΈΡΠ½Π°ΡΠ° Π°Π»Π°ΡΠΌΠ° ΠΎΡ ΡΡΡΠ°ΡΠ° Π³ΡΡΠΏΠ°, Π° Π½Π΅ Π² ΠΎΡΠ΄Π΅Π»Π½ΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅. ΠΠΎ-ΠΊΡΡΠ½ΠΎ β Π΄Π° Π΄ΠΎΠ±Π°Π²ΠΈΠΌ Π² ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ΡΠΎ Π½Π°ΠΉ-ΡΠ΅ΡΡΠ°ΡΠ° Π³ΡΠ΅ΡΠΊΠ° Π·Π° ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ X ΠΌΠΈΠ½ΡΡΠΈ.
ΠΡΠ΄Π΅Π»Π½Π° ΡΠ΅ΠΌΠ° β ΡΠ²ΡΡΠ·Π²Π°Π½Π΅ΡΠΎ Ρ Π΄ΡΡΠ³ΠΈ ΡΡΠ»ΡΠ³ΠΈ ΠΈ ΠΊΠ°ΠΊΠ²ΠΈΡΠΎ ΠΈ Π΄Π° Π±ΠΈΠ»ΠΎ Π΄Π΅ΠΉΡΡΠ²ΠΈΡ, ΠΈΠ½ΠΈΡΠΈΠΈΡΠ°Π½ΠΈ ΠΎΡ Π°Π»Π°ΡΠΌΠ°ΡΠ° (ΡΠ°ΠΌΠΎ Π°ΠΊΠΎ Π²Π°ΡΠ΅ΡΠΎ Π½Π°Π±Π»ΡΠ΄Π΅Π½ΠΈΠ΅ ΡΠ°Π±ΠΎΡΠΈ Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ Π΄ΠΎΠ±ΡΠ΅).
ΠΡΠΈΠΌΠ΅Ρ Π·Π° ΠΎΠΏΠΈΡΠ°Π½ΠΈΠ΅ Π½Π° ΠΎΠ±ΡΠ°Π±ΠΎΡΠ²Π°ΡΠ° ΡΡΠ½ΠΊΡΠΈΡ, ΠΊΡΠ΄Π΅ΡΠΎ 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 :9092 logs lvl=error
ΠΠ°ΡΠΈΠ°Π½Ρ Ρ httpOut
ΠΠΎΠΊΠ°Π·Π²Π° Π΄Π°Π½Π½ΠΈ Π² ΡΠ΅ΠΊΡΡΠΈΡ ΠΏΠ°ΠΉΠΏΠ»Π°ΠΉΠ½:
|httpOut('Π½Π΅ΡΠΎ')
ΠΠ° Π½Π°Π±Π»ΡΠ΄Π°Π²Π°ΠΌΠ΅ (get): :9092\/kapacitor\/v1\/tasks\/task_name\/something
Π‘Ρ Π΅ΠΌΠ° Π½Π° ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅
- ΠΡΡΠΊΠ° Π·Π°Π΄Π°ΡΠ° Π²ΡΡΡΠ° Π΄ΡΡΠ²ΠΎ Π½Π° ΠΈΠ·ΠΏΡΠ»Π½Π΅Π½ΠΈΠ΅ΡΠΎ Ρ ΠΏΠΎΠ»Π΅Π·Π½ΠΈ ΡΠΈΡΡΠΈ Π²ΡΠ² ΡΠΎΡΠΌΠ°Ρ .
- ΠΠ·ΠΈΠΌΠ°ΠΌΠ΅ Π±Π»ΠΎΠΊ .
- ΠΠΌΡΠΊΠ²Π°ΠΌΠ΅ Π² viewer, .
ΠΡΠ΄Π΅ ΠΎΡΠ΅ ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΠΌ timestamp Π² influxdb ΠΏΡΠΈ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ Π·Π°ΠΏΠΈΡΠ²Π°Π½Π΅?
timestamp Π² influxdb ΠΏΡΠΈ ΠΎΠ±ΡΠ°ΡΠ½ΠΎ Π·Π°ΠΏΠΈΡΠ²Π°Π½Π΅
ΠΠ°ΠΏΡΠΈΠΌΠ΅Ρ, Π½Π°ΡΡΡΠΎΠΉΠ²Π°ΠΌΠ΅ Π°Π»Π°ΡΠΌΠ° Π·Π° ΡΡΠΌΠ°ΡΠ° Π½Π° Π·Π°ΡΠ²ΠΊΠΈΡΠ΅ Π½Π° ΡΠ°Ρ (groupBy(1h)) ΠΈ ΠΈΡΠΊΠ°ΠΌΠ΅ Π΄Π° Π·Π°ΠΏΠΈΡΠ΅ΠΌ Π²ΡΠ·Π½ΠΈΠΊΠ½Π°Π»Π°ΡΠ° Π°Π»Π°ΡΠΌΠ° Π² influxdb (Π·Π° Π΄Π° ΠΏΠΎΠΊΠ°ΠΆΠ΅ΠΌ Π½Π°Π»ΠΈΡΠΈΠ΅ΡΠΎ Π½Π° ΠΏΡΠΎΠ±Π»Π΅ΠΌ Π½Π° Π³ΡΠ°ΡΠΈΠΊΠ°ΡΠ° Π² grafana).
influxDBOut() ΡΠ΅ Π·Π°ΠΏΠΈΡΠ΅ Π² timestamp ΡΡΠΎΠΉΠ½ΠΎΡΡΡΠ° time ΠΎΡ Π°Π»Π°ΡΠΌΠ°ΡΠ°, Π² ΡΡΠΎΡΠ²Π΅ΡΡΡΠ²ΠΈΠ΅ Ρ ΡΠΎΠ²Π°, ΡΠΎΡΠΊΠ°ΡΠ° Π½Π° Π³ΡΠ°ΡΠΈΠΊΠ°ΡΠ° ΡΠ΅ Π±ΡΠ΄Π΅ Π·Π°ΠΏΠΈΡΠ°Π½Π° ΠΏΠΎ-ΡΠ°Π½ΠΎ/ΠΏΠΎ-ΠΊΡΡΠ½ΠΎ, ΠΎΡΠΊΠΎΠ»ΠΊΠΎΡΠΎ Π΅ Π΄ΠΎΡΠ»Π° Π°Π»Π°ΡΠΌΠ°ΡΠ°.
ΠΠΎΠ³Π°ΡΠΎ Π΅ Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠ° ΡΠΎΡΠ½ΠΎΡΡ: Π·Π°ΠΎΠ±ΠΈΠΊΠ°Π»ΡΠΌΠ΅ ΡΠΎΠ·ΠΈ ΠΏΡΠΎΠ±Π»Π΅ΠΌ ΡΡΠ΅Π· ΠΈΠ·Π²ΠΈΠΊΠ²Π°Π½Π΅ Π½Π° ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ Ρ Π΅Π½Π΄Π»Π΅Ρ, ΠΊΠΎΠΉΡΠΎ ΡΠ΅ Π·Π°ΠΏΠΈΡΠ΅ Π΄Π°Π½Π½ΠΈΡΠ΅ Π² influxdb Ρ ΡΠ΅ΠΊΡΡΠΈΡ timestamp.
docker, ΠΈΠ·Π³ΡΠ°ΠΆΠ΄Π°Π½Π΅ ΠΈ Π΄Π΅ΠΏΠ»ΠΎΠΉ
ΠΡΠΈ ΡΡΠ°ΡΡΠΈΡΠ°Π½Π΅ kapacitor ΠΌΠΎΠΆΠ΅ Π΄Π° Π·Π°ΡΠ΅ΠΆΠ΄Π° Π·Π°Π΄Π°ΡΠΈ, ΡΠ°Π±Π»ΠΎΠ½ΠΈ ΠΈ Ρ Π΅Π½Π΄Π»Π΅ΡΠΈ ΠΎΡ Π΄ΠΈΡΠ΅ΠΊΡΠΎΡΠΈΡΡΠ°, ΡΠΊΠ°Π·Π°Π½Π° Π² ΠΊΠΎΠ½ΡΠΈΠ³ΡΡΠ°ΡΠΈΡΡΠ°, Π² Π±Π»ΠΎΠΊΠ° [load].
ΠΠ° ΠΊΠΎΡΠ΅ΠΊΡΠ½ΠΎ ΡΡΠ·Π΄Π°Π²Π°Π½Π΅ Π½Π° Π·Π°Π΄Π°ΡΠ° ΡΠ° Π½Π΅ΠΎΠ±Ρ ΠΎΠ΄ΠΈΠΌΠΈ ΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ Π½Π΅ΡΠ°:
- ΠΠΌΠ΅ Π½Π° ΡΠ°ΠΉΠ»Π° β ΡΠ°Π·Π³ΡΡΡΠ° ΡΠ΅ Π² id/ΠΈΠΌΠ΅ Π½Π° ΡΠΊΡΠΈΠΏΡΠ°.
- Π’ΠΈΠΏ β stream/batch
- 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.
ΠΡΠ΅ΡΠΊΠΈΡΠ΅ ΠΈΠ·Π³Π»Π΅ΠΆΠ΄Π°Ρ Π·Π»ΠΎΠ½Π°ΠΌΠ΅ΡΠ΅Π½ΠΎ:

Π ΠΏΠΎ-ΠΌΠ°Π»ΠΊΠΎ Π·Π»ΠΎΠ½Π°ΠΌΠ΅ΡΠ΅Π½ΠΎ, Π°ΠΊΠΎ Π³Π»Π΅Π΄Π°ΠΌΠ΅ Ρ ΡΡΠΏΠ΅ΡΠ½ΠΈΡΠ΅ Π·Π°ΡΠ²ΠΊΠΈ:

ΠΠΎΠ±ΡΠ΅, ΠΌΠΎΠΆΠ΅ΠΌ ΠΏΡΠ΅Π΄Π²Π°ΡΠΈΡΠ΅Π»Π½ΠΎ Π΄Π° ΠΈΠ·ΡΠΈΡΠ»ΠΈΠΌ ΡΡΠ°Π²ΠΊΠ°ΡΠ° Π² ΡΡΠ»ΡΠ³Π°ΡΠ° ΠΏΡΠ΅Π΄ΠΈ Π³ΡΠ°ΡΠ°Π½Π°, ΠΈ Π² Π½ΡΠΊΠΎΠΈ ΡΠ»ΡΡΠ°ΠΈ ΡΠΎΠ²Π° ΡΠ΅ Π΅ Π΄ΠΎΡΡΠ°ΡΡΡΠ½ΠΎ. ΠΠΎ Π½Π΅ Π² Π½Π°ΡΠΈΡ ΡΠ»ΡΡΠ°ΠΉ, ΡΡΠΉ ΠΊΠ°ΡΠΎ Π·Π° Π²ΡΠ΅ΠΊΠΈ ΠΊΠ°Π½Π°Π» ΡΠ΅ ΠΈΠ·ΡΠΈΡΠ»ΡΠ²Π° Β«Π½ΠΎΡΠΌΠ°Π»Π½ΠΎΒ» ΡΡΠΎΡΠ½ΠΎΡΠ΅Π½ΠΈΠ΅, Π° Π°Π»Π°ΡΠΌΠΈΡΠ΅ ΡΠ°Π±ΠΎΡΡΡ Π½Π° ΡΡΠ°ΡΠΈΡΠ½ΠΈ ΡΡΠΎΠΉΠ½ΠΎΡΡΠΈ (ΡΡΡΡΠΈΠΌ Π½Π° ΠΎΠΊΠΎ, ΡΠΌΠ΅Π½ΡΠΌΠ΅, Π°ΠΊΠΎ Π°Π»Π°ΡΠΌΠΈΡΠ° ΡΠ΅ΡΡΠΎ).
ΠΡΠΎ ΠΏΡΠΈΠΌΠ΅ΡΠΈ Π·Π° Β«Π½ΠΎΡΠΌΠ°Π»Π½ΠΎΒ» Π·Π° ΡΠ°Π·Π»ΠΈΡΠ½ΠΈ ΠΊΠ°Π½Π°Π»ΠΈ:


ΠΡΠ΅Π½Π΅Π±ΡΠ΅Π³Π²Π°ΠΌΠ΅ ΠΏΡΠ΅Π΄ΠΈΡΠ½Π°ΡΠ° ΡΠΎΡΠΊΠ° ΠΈ ΠΏΡΠ΅Π΄ΠΏΠΎΠ»Π°Π³Π°ΠΌΠ΅, ΡΠ΅ ΠΏΡΠΈ Π²ΡΠΈΡΠΊΠΈ Π΄ΠΎΡΡΠ°Π²ΡΠΈΡΠΈ Β«Π½ΠΎΡΠΌΠ°Π»Π½Π°ΡΠ°Β» ΡΠΈΡΡΠ°ΡΠΈΡ Π΅ ΠΏΠΎΠ΄ΠΎΠ±Π½Π°. Π‘Π΅Π³Π° Π²ΡΠΈΡΠΊΠΎ Π΅ Π΄ΠΎΠ±ΡΠ΅, ΠΌΠΎΠΆΠ΅ΠΌ Π»ΠΈ Π΄Π° ΡΠ΅ ΡΠΏΡΠ°Π²ΠΈΠΌ Ρ Π°Π»Π°ΡΠΌΠΈΡΠ΅ Π² Π³ΡΠ°ΡΠ°Π½Π°?
ΠΠΎΠΆΠ΅ΠΌ, Π½ΠΎ Π½Π΅ ΠΈΡΠΊΠ°ΠΌΠ΅, Π·Π°ΡΠΎΡΠΎ ΡΡΡΠ±Π²Π° Π΄Π° ΠΈΠ·Π±Π΅ΡΠ΅ΠΌ Π΅Π΄ΠΈΠ½ ΠΎΡ Π²Π°ΡΠΈΠ°Π½ΡΠΈΡΠ΅:
Π°) Π΄Π° Π½Π°ΠΏΡΠ°Π²ΠΈΠΌ ΠΌΠ½ΠΎΠΆΠ΅ΡΡΠ²ΠΎ Π³ΡΠ°ΡΠΈΠΊΠΈ Π·Π° Π²ΡΠ΅ΠΊΠΈ ΠΊΠ°Π½Π°Π» ΠΏΠΎΠΎΡΠ΄Π΅Π»Π½ΠΎ (ΠΈ ΠΌΡΡΠΈΡΠ΅Π»Π½ΠΎ Π΄Π° Π³ΠΈ ΠΏΠΎΠ΄Π΄ΡΡΠΆΠ°ΠΌΠ΅)
Π±) Π΄Π° ΠΎΡΡΠ°Π²ΠΈΠΌ Π΅Π΄Π½Π° Π³ΡΠ°ΡΠΈΠΊΠ° Ρ Π²ΡΠΈΡΠΊΠΈ ΠΊΠ°Π½Π°Π»ΠΈ (ΠΈ Π΄Π° ΡΠ΅ Π·Π°Π³ΡΠ±ΠΈΠΌ Π² ΡΠ²Π΅ΡΠ½ΠΈΡΠ΅ Π»ΠΈΠ½ΠΈΠΈ ΠΈ Π½Π°ΡΡΡΠΎΠ΅Π½ΠΈΡΠ΅ Π°Π»Π°ΡΠΌΠΈ)

ΠΠ°ΠΊΠ²ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡ ΠΌΠ΅?
ΠΡΠ½ΠΎΠ²ΠΎ, Π² Π΄ΠΎΠΊΡΠΌΠ΅Π½ΡΠ°ΡΠΈΡΡΠ° ΠΈΠΌΠ° Π΄ΠΎΠ±ΡΡ Π½Π°ΡΠ°Π»Π΅Π½ ΠΏΡΠΈΠΌΠ΅Ρ (), ΠΌΠΎΠΆΠ΅ΠΌ Π΄Π° Ρ Π²ΡΡΠ»ΠΈΠΌ ΠΏΠΎΠ³Π»Π΅Π΄ ΠΈΠ»ΠΈ Π΄Π° Π³ΠΎ Π²Π·Π΅ΠΌΠ΅ΠΌ Π·Π° ΠΎΡΠ½ΠΎΠ²Π° ΠΏΡΠΈ Π°Π½Π°Π»ΠΎΠ³ΠΈΡΠ½ΠΈ Π·Π°Π΄Π°ΡΠΈ.
ΠΠ°ΠΊΠ²ΠΎ Π½Π°ΠΏΡΠ°Π²ΠΈΡ ΠΌΠ΅ Π² ΠΊΡΠ°ΠΉΠ½Π° ΡΠΌΠ΅ΡΠΊΠ°:
- ΠΎΠ±Π΅Π΄ΠΈΠ½Π΅Π½ΠΈΠ΅ Π½Π° Π΄Π²Π΅ ΡΠ΅ΡΠΈΠΈ Π·Π° Π½ΡΠΊΠΎΠ»ΠΊΠΎ ΡΠ°ΡΠ°, Π³ΡΡΠΏΠΈΡΠ°Π½Π΅ ΠΏΠΎ ΠΊΠ°Π½Π°Π»ΠΈ;
- ΠΏΠΎΠΏΡΠ»Π²Π°ΠΌΠ΅ ΡΠ΅ΡΠΈΠΈΡΠ΅ ΠΏΠΎ Π³ΡΡΠΏΠΈ, Π°ΠΊΠΎ Π½ΡΠΌΠ° Π΄Π°Π½Π½ΠΈ;
- ΡΡΠ°Π²Π½ΡΠ²Π°ΠΌΠ΅ ΠΌΠ΅Π΄ΠΈΠ°Π½Π°ΡΠ° ΠΎΡ ΠΏΠΎΡΠ»Π΅Π΄Π½ΠΈΡΠ΅ 10 ΠΌΠΈΠ½ΡΡΠΈ Ρ ΠΏΡΠ΅Π΄ΠΈΡΠ½ΠΈΡΠ΅ Π΄Π°Π½Π½ΠΈ;
- ΠΊΡΠ΅ΡΠΈΠΌ, Π°ΠΊΠΎ Π½Π΅ΡΠΎ Π΅ ΠΎΡΠΊΡΠΈΡΠΎ;
- ΠΏΠΈΡΠ΅ΠΌ ΠΈΠ·ΡΠΈΡΠ»Π΅Π½ΠΈΡΠ΅ ΡΡΠ°Π²ΠΊΠΈ ΠΈ ΡΡΠ°Π½Π°Π»ΠΈΡΠ΅ Π°Π»Π°ΡΠΌΠΈ Π² influxdb;
- ΠΈΠ·ΠΏΡΠ°ΡΠ°ΠΌΠ΅ ΠΏΠΎΠ»Π΅Π·Π½ΠΎ ΡΡΠΎΠ±ΡΠ΅Π½ΠΈΠ΅ Π² slack.
ΠΠ° ΠΌΠΎΠ΅ ΠΌΠ½Π΅Π½ΠΈΠ΅, ΡΡΠΏΡΡ ΠΌΠ΅ Π΄Π° ΠΏΠΎΡΡΠΈΠ³Π½Π΅ΠΌ ΠΌΠ°ΠΊΡΠΈΠΌΠ°Π»Π½ΠΎ ΠΊΡΠ°ΡΠΈΠ²ΠΎ Π²ΡΠΈΡΠΊΠΎ, ΠΊΠΎΠ΅ΡΠΎ ΠΈΡΠΊΠ°Ρ ΠΌΠ΅ Π΄Π° ΠΏΠΎΠ»ΡΡΠΈΠΌ Π½Π° ΠΈΠ·Ρ ΠΎΠ΄Π° (ΠΈ Π΄ΠΎΡΠΈ ΠΌΠ°Π»ΠΊΠΎ ΠΏΠΎΠ²Π΅ΡΠ΅ Ρ ΠΏΠ΅ΡΡΠΎΠ½Π°Π»ΠΈΠ·ΠΈΡΠ°Π½ΠΈ ΠΎΠ±ΡΠ°Π±ΠΎΡΠ²Π°ΡΠΈ).
ΠΠ° github.com ΠΌΠΎΠΆΠ΅ΡΠ΅ Π΄Π° Π²ΠΈΠ΄ΠΈΡΠ΅ ΠΈ Π½Π° ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΡΠΊΡΠΈΠΏΡ.
ΠΡΠΈΠΌΠ΅Ρ Π½Π° ΠΏΠΎΠ»ΡΡΠ΅Π½ΠΈΡ ΠΊΠΎΠ΄:
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) |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') 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('{{ .Level }}: {{ index .Tags "channel" }} err/req ratio ({{ index .Tags "supplier" }}) {{ if eq .Level "OK" }}It is ok now{{ else }} median Π·Π° ' + string(todayPeriod) + ' Π΅ {{ index .Fields "today.median" | printf "%0.2f" }}%, ΡΠΏΡΡΠΌΠΎ ΠΏΡΠ΅Π΄ΠΈΡΠ½ΠΈΡ ' + string(period) + ' Π΅ {{ 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') 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
