ืกืืืจ ืืื ืื ืฉืืืื ืืฃ ืืื ืื ืฉืืื ืืืืข ืืฉ ืฆืืจื ืืืกืืฃ ืืืื ืฉืืจืืช. ืืฉืื ืืืืืื ื ืืื ืืื ืืืืืืจ ืืชืจืื ืืืืืื ืฉื ืืกืคื, ืฉืชืืืืข ืขื ืื ืืจืืื ืื ืชืื ืื ืืขืจืืฆืื ืื ืืืื ืืื (ืืืื, ืกืืืง, ืืืืจื). ืืฉืืจืืช ืืืื ืช ืืืืื ืืืงืืื
Capacitor ืืื ืืืง ืืืกื ืืช TICK ืฉืืืืื ืืขืื ืืืืื ื-InfluxDB. ืืื ืืืื ืืืืจ ืืกืคืจ ืืืืืืช ืืื (Join), ืืืฉื ืืฉืื ืฉืืืืฉื ืืื ืชืื ืื ืฉืืชืงืืื, ืืืชืื ืืช ืืชืืฆืื ืืืืจื ื-InfluxDB, ืืฉืืื ืืชืจืื ื-Slack/Telegram/mail.
ืื ืืขืจืืื ืืื ืืื ืืืคืืจืืช
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()
.tag('status', 'empty')
.field('value', 0)
ืืื ืืฆืืจืคืืช (ืคื ืืื ืืื ืืืฆืื ื)
ืืืจืืจืช ืืืื, ืืฆืืจืคืืช ืชืืืง ื ืงืืืืช ืฉืืื ืืื ื ืชืื ืื (ืคื ืืืืื).
ืขื fill('null'), ืชืชืืฆืข ืืฆืืจืคืืช ืืืฆืื ืืช, ืืืืืจ ืืื ืชืฆืืจืื ืืืฆืข ืืจืืจืช ืืืื() ืืืืื ืืช ืืขืจืืื ืืจืืงืื:
var data = res1
|join(res2)
.as('res1', 'res2)
.fill('null')
|default()
.field('res1.value', 0.0)
.field('res2.value', 100.0)
ืขืืืื ืืฉ ืืื ื ืืืื ืก. ืืืืืื ืฉืืืขืื, ืื ืืืช ืืืกืืจืืช (res1 ืื res2) ืจืืงื, ืื ืืกืืจื (ืื ืชืื ืื) ืฉืชืชืงืื ืชืืื ืจืืงื. ืืฉื ื ืืกืคืจ ืืจืืืกืื ืื ืืฉื ืื ื-Github (
ืฉืืืืฉ ืืชื ืืื ืืืืฉืืืื (ืื ืืืืืื)
|eval(lambda: if("value" > 0, true, false)
ืืืฉ ืืงืืช ืืืจืื ืืช ืืืฆืื ืืจ ืืชืงืืคื
ืืืืืื, ืขืืื ืืืฉืืืช ืืช ืืขืจืืื ืฉื ืืืฉ ืืืงืืช ืืืืจืื ืืช ืขื ืืฉืืืข ืืงืืื. ืืชื ืืืื ืืงืืช ืฉืชื ืืฆืืืช ืฉื ื ืชืื ืื ืืฉืชื ืืฆืืืช ื ืคืจืืืช ืื ืืืืฅ ืืืง ืืื ืชืื ืื ืืชืงืืคื ืืืืื ืืืชืจ:
|where(lambda: duration((unixNano(now()) - unixNano("time"))/1000, 1u) < 5m)
ืืืืคื ืืืืฉ ืืืงืืช ืืืืจืื ืืช ืชืืื ืืืฉืชืืฉ ื-BarrierNode, ืฉืื ืชืง ื ืชืื ืื ืืคื ื ืืืื ืฉืฆืืื:
|barrier()
.period(5m)
ืืืืืืืช ืืฉืืืืฉ ืืชืื ืืืช Go ืืืืืขื
ืชืื ืืืช ืืชืืืืืช ืืคืืจืื ืืืืืืื
ืืืจืช
ืื ืื ื ืขืืฉืื ืกืืจ ืืืืจืื ืืื ืืคืขืืืื ืื ืฉืื ืขื ืืงืกื ืฉืื:
|alert()
...
.message(
'{{ if eq .Level "OK" }}It is ok now{{ else }}Chief, everything is broken{{end}}'
)
ืฉืชื ืกืคืจืืช ืืืจื ืื ืงืืื ืืขืฉืจืื ืืช ืืืืืขื
ืฉืืคืืจ ืงืจืืืืช ืืืืืขื:
|alert()
...
.message(
'now value is {{ index .Fields "value" | printf "%0.2f" }}'
)
ืืจืืืช ืืฉืชื ืื ืืืืืขื
ืื ื ืืฆืืืื ืืืืข ื ืืกืฃ ืืืืืขื ืืื ืืขื ืืช ืขื ืืฉืืื "ืืื ืื ืฆืืขืง"?
var warnAlert = 10
|alert()
...
.message(
'Today value less then '+string(warnAlert)+'%'
)
ืืืื ืืชืจืื ืืืืืื
ืื ืืืจ ืืืจืื ืืืฉืจ ืืฉ ืืืชืจ ืืงืืืฆื ืืืช ืื ืชืื ืื, ืืืจืช ืจืง ืืชืจืื ืืืช ืชืืืืฆืจ:
|alert()
...
.id('{{ index .Tags "myname" }}/{{ index .Tags "myfield" }}')
ืืืคื ืืืชืื ืืืฉืืช
ืืจืฉืืื ืืืืืื ืฉื ืืืืคืืื ืืืืืช exec, ืืืืคืฉืจืช ืื ืืืฆืข ืืช ืืกืงืจืืคื ืฉืื ืขื ืืคืจืืืจืื ืฉืขืืจื (stdin) - ืืฆืืจืชืืืช ืืชื ืื!
ืืื ืืื ืืืื ืฉืื ื ืืื ืกืงืจืืคื ืงืื ืฉื Python ืืฉืืืืช ืืืืขืืช ืืจืขื.
ืืืชืืื ืจืฆืื ื ืืฉืืื ืืืืืขื ืชืืื ืช ืืจืืคื ื ืืืื ืช ืืืจืฉืื. ืืืืจ ืืื, ืืชืื 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("something")
ืฆืคื (cli): kapacitor -url
ืืคืฉืจืืช ืขื httpOut
ืืฆืื ื ืชืื ืื ืืฆืื ืืจ ืื ืืืื:
|httpOut('something')
ืฆืคื (ืงืืื):
ืชืื ืืช ืืืฆืืข
- ืื ืืฉืืื ืืืืืจื ืขืฅ ืืืฆืืข ืขื ืืกืคืจืื ืฉืืืืฉืืื ืืคืืจืื
graphviz . - ืงื ืืืืง
ื ืงืืื . - ืืืืง ืืืชื ืืฆืืคื,
ืชืื ื .
ืืืคื ืขืื ืืคืฉืจ ืืืฉืื ืืืจืคื?
ืืืชืืช ืืื ื-influxdb ืขื ืืชืืื ืืืืจืช
ืืืืืื, ืืืืจื ื ืืชืจืื ืืกืืื ืืืงืฉืืช ืืฉืขื (groupBy(1h)) ืืจืืฆืื ืืชืขื ืืช ืืืชืจืื ืฉืืชืจืืฉื ื-influxdb (ืืื ืืืจืืืช ืืคื ืืช ืขืืืืช ืืืขืื ืขื ืืืจืฃ ืืืจืืคื ื).
influxDBOut() ืืืชืื ืืช ืขืจื ืืืื ืืืืชืจืื ืืืืชืืช ืืืื; ืืืชืื, ืื ืงืืื ืืชืจืฉืื ืชืืืชื ืืืงืื/ืืืืืจ ืืืืชืจืื ืฉืืืืขื.
ืืืฉืจ ื ืืจืฉ ืืืืง: ืื ื ืขืืงืคืื ืืช ืืืขืื ืขื ืืื ืงืจืืื ืืืืคื ืืืชืื ืืืฉืืช, ืฉืืืชืื ื ืชืื ืื ื-influxdb ืขื ืืืชืืช ืืืื ืื ืืืืืช.
docker, ืื ืืื ืืคืจืืกื
ืืขืช ืืืคืขืื, Capacitor ืืืื ืืืขืื ืืฉืืืืช, ืชืื ืืืช ืืืืคืืื ืืืกืคืจืืื ืฉืฆืืื ื ืืชืฆืืจื ืืืืืง [load].
ืืื ืืืฆืืจ ืืฉืืื ื ืืื ื, ืืชื ืฆืจืื ืืช ืืืืจืื ืืืืื:
- ืฉื ืืงืืืฅ - ืืืจืื ืืืืื/ืฉื ืกืงืจืืคื
- ืกืื โ ืืจื/ืืฆืืื
- dbrp - ืืืืช ืืคืชื ืืฆืืื ืืืืื ืืกื ื ืชืื ืื + ืืืื ืืืช ืืกืงืจืืคื ืคืืขื (dbrp "ืกืคืง." "autogen")
ืื ืืฉืืืช ืืฆืืื ืืืฉืื ืืื ื ืืืืื ืฉืืจื ืขื dbrp, ืืฉืืจืืช ืืืื ืืกืจื ืืืชืืื ืืืืชืื ืขืืื ืืืืฉืจ ืืืืื.
ืืืจืื ืืืจืฃ, ืืืืคื, ืืฉืืจื ืืื ืื ืืืืจื ืืืชืงืืื; ืืื ืื ืืชืงืืืช ืืจื ืืืืฉืง ืืืืืืืช ืฉืืืื.
ืคืจืืฆื ืืขืช ืื ืืืช ืงืื ืืืื ืจ: Dockerfile ืืืฆื ืขื -1 ืื ืืฉ ืฉืืจืืช ืขื //.+dbrp, ืื ืฉืืืคืฉืจ ืื ืืืืื ืืื ืืช ืืกืืื ืืืฉื ืืขืช ืืจืืืช ื-build.
ืืืฆืืจืฃ ืืื ืืจืืื
ืืฉืืื ืืืืืื: ืขืืื ืืงืืช ืืช ืืืืืืื ื-95 ืืืื ืืืคืขืื ืฉื ืืฉืืจืืช ืืืฉื ืฉืืืข, ืืืฉืืืช ืื ืืงื ืืชืื 10 ืืืืจืื ืืช ืืขืจื ืื.
ืืชื ืื ืืืื ืืขืฉืืช ืืฆืืจืคืืช ืฉื ืืื ืืจืืื, ืืืจืื/ืืืืฆืข/ืืฆืืื ืืขื ืงืืืฆืช ื ืงืืืืช ืืืคื ืืช ืืฆืืืช ืืืจื, ืืฉืืืื "ืื ื ืืชื ืืืืกืืฃ ืงืฆืืืช ืื ืชืืืืื ืืืื: ืืฆืืื -> ืืจื" ืชืืืืจ.
ืื ืืชืืฆืื ืฉื ืืฆืืื, ืืืฉืชื ื ืืืืืื ืืืืื, ืืื ื ืืืืืคืช.
ืืฉื ื ืืคืฉืจืืช ืืฉืืืจ ืืช ืืืกืคืจืื ืืืจืืฉืื ืืืืฆืืื ืืจืืฉืื ื ืืงืืืฅ ืืจื udf ืืืืขืื ืืช ืืงืืืฅ ืืื ืืืืฆืขืืช sideload.
ืื ืคืชืจื ื ืขื ืื?
ืืฉ ืื ื ื-100 ืกืคืงื ืืืื ืืช, ืืื ืืื ืืื ืืืืืื ืืืืืช ืืื ืงืฉืจืื, ื ืงืจื ืืื ืขืจืืฅ. ืืฉื ื ื-300 ืขืจืืฆืื ืืื, ืื ืืื ืืืขืจืืฆืื ืขืืื ืืืคืื. ืืืื ืื ืืืืืื ืฉื ืจืฉืื, ื ืขืงืื ืืืจ ืฉืืขืืจ ืืฉืืืืืช (ืืงืฉืืช ืืฉืืืืืช).
ืืื ืื ืืจืืคื ื?
ืืืชืจืืืช ืฉืืืื ืืืืืืจืืช ื-Grafana ืืฉ ืืกืคืจ ืืกืจืื ืืช. ืืืงื ืงืจืืืืื, ืืืงื ืืคืฉืจ ืืขืฆืื ืขืื ืืื, ืชืืื ืืืฆื.
ืืจืคืื ื ืื ืืืืข ืืืฉื ืืื ืืืืืืช + ืืชืจืื, ืืื ืฆืจืื ืชืขืจืืฃ (ืืงืฉืืช-ืืขืืืืช)/ืืงืฉืืช.
ืืฉืืืืืช ื ืจืืืช ืืืขืืืืช:
ืืคืืืช ืจืข ืืฉืืกืชืืืื ืขืืืื ืืืงืฉืืช ืืืฆืืืืช:
ืืืงืื, ืื ืื ื ืืืืืื ืืืฉื ืืจืืฉ ืืช ืืชืขืจืืฃ ืืฉืืจืืช ืืคื ื ืืจืืคื ื, ืืืืงืจืื ืืกืืืืื ืื ืืขืืื. ืืื ืื ืืฆืื ื, ืื... ืขืืืจ ืื ืขืจืืฅ ืืืืก ืฉืื ื ืืฉื "ื ืืจืืื", ืืืืชืจืืืช ืคืืขืืืช ืืคื ืขืจืืื ืกืืืืื (ืื ืื ื ืืืคืฉืื ืืืชื ืืขืื ืืื, ืืฉื ืื ืืืชื ืื ืืฉ ืืชืจืืืช ืชืืืคืืช).
ืืื ืื ืืืืืืืช ืฉื "ืจืืื" ืขืืืจ ืขืจืืฆืื ืฉืื ืื:
ืื ื ืืชืขืืืื ืืื ืงืืื ืืงืืืืช ืืื ืืืื ืฉืืชืืื ื ื"ืจืืืื" ืืืื ืขืืืจ ืื ืืกืคืงืื. ืขืืฉืื ืืื ืืกืืจ, ืืื ืื ื ืืืืืื ืืืกืชืืจ ืขื ืืชืจืืืช ืืืจืืคื ื?
ืื ืื ื ืืืืืื, ืืื ืื ืื ื ืืืฉ ืื ืจืืฆืื, ืื ืื ืื ื ืฆืจืืืื ืืืืืจ ืืืช ืืืืคืฉืจืืืืช:
ื) ืืืฆืืจ ืืจืื ืืจืคืื ืขืืืจ ืื ืขืจืืฅ ืื ืคืจื (ืืืืืืช ืืืชื ืืืื)
ื) ืืฉืืจ ืชืจืฉืื ืืื ืขื ืื ืืขืจืืฆืื (ืืชืื ืืืืืื ืืงืืืื ืืฆืืขืื ืืื ืืืืชืจืืืช ืืืืชืืืืช ืืืฉืืช)
ืืื ืขืฉืืช ืืช ืื?
ืฉืื, ืืฉ ืืืืื ืืชืืื ืืืื ืืชืืขืื (
ืื ืขืฉืื ื ืืกืืฃ:
- ืืืฆืืจืฃ ืืฉืชื ืกืืจืืช ืชืื ืืกืคืจ ืฉืขืืช, ืืงืืฅ ืืคื ืขืจืืฆืื;
- ืืื ืืช ืืกืืจื ืืคื ืงืืืฆื ืื ืื ืืื ื ืชืื ืื;
- ืืฉืื ืืช ืืืฆืืื ืฉื 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)
// 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)
ืืื ืืืกืงื ื?
Capacitor ืืขืืื ืืืืฆืืข ืืชืจืืืช-ื ืืืืจ ืขื ืืืืจื ืฉื ืงืืืฆืืช, ืืืฆืืข ืืืฉืืืื ื ืืกืคืื ืขื ืกืื ืืืืื ืฉืืืจ ื ืจืฉืื, ืืืฆืืข ืคืขืืืืช ืืืชืืืืช ืืืฉืืช ืืืจืฆืช ืกืงืจืืคืืื (udf).
ืืืกืื ืืื ืืกื ืืื ื ืืืื ืืืืืื - ื ืกื ืืืช ืื ืืจืคื ื ืื ืืืื ืืืจืื ืืื ื ืืกืคืงืื ืืช ืจืฆืื ืืชืื ืืืืืื.
ืืงืืจ: www.habr.com