ื˜ืจื™ืงื™ื ืœืขื™ื‘ื•ื“ ืžื“ื“ื™ื ื‘ืงืคืืกื™ื˜ื•ืจ

ืกื‘ื™ืจ ืœื”ื ื™ื— ืฉื”ื™ื•ื ืืฃ ืื—ื“ ืœื ืฉื•ืืœ ืžื“ื•ืข ื™ืฉ ืฆื•ืจืš ืœืืกื•ืฃ ืžื“ื“ื™ ืฉื™ืจื•ืช. ื”ืฉืœื‘ ื”ื”ื’ื™ื•ื ื™ ื”ื‘ื ื”ื•ื ืœื”ื’ื“ื™ืจ ื”ืชืจืื” ืœืžื“ื“ื™ื ืฉื ืืกืคื•, ืฉืชื•ื“ื™ืข ืขืœ ื›ืœ ื—ืจื™ื’ื” ื‘ื ืชื•ื ื™ื ื‘ืขืจื•ืฆื™ื ื”ื ื•ื—ื™ื ืœื›ื (ืžื™ื™ืœ, ืกืœืืง, ื˜ืœื’ืจื). ื‘ืฉื™ืจื•ืช ื”ื–ืžื ืช ื”ืžืœื•ืŸ ื”ืžืงื•ื•ืŸ Ostrovok.ru ื›ืœ ื”ืžื“ื“ื™ื ืฉืœ ื”ืฉื™ืจื•ืชื™ื ืฉืœื ื• ืžื•ื–ื’ื™ื ืœืชื•ืš InfluxDB ื•ืžื•ืฆื’ื™ื ื‘-Grafana, ื•ื’ื ื”ืชืจืื” ื‘ืกื™ืกื™ืช ืžื•ื’ื“ืจืช ืฉื. ืขื‘ื•ืจ ืžืฉื™ืžื•ืช ื›ืžื• "ืืชื” ืฆืจื™ืš ืœื—ืฉื‘ ืžืฉื”ื• ื•ืœื”ืฉื•ื•ืช ืื™ืชื•", ืื ื• ืžืฉืชืžืฉื™ื ื‘ืงื™ืคืืกื™ื˜ื•ืจ.

ื˜ืจื™ืงื™ื ืœืขื™ื‘ื•ื“ ืžื“ื“ื™ื ื‘ืงืคืืกื™ื˜ื•ืจ
Capacitor ื”ื•ื ื—ืœืง ืžื—ืกื ื™ืช TICK ืฉื™ื›ื•ืœื” ืœืขื‘ื“ ืžื“ื“ื™ื ืž-InfluxDB. ื”ื•ื ื™ื›ื•ืœ ืœื—ื‘ืจ ืžืกืคืจ ืžื“ื™ื“ื•ืช ื™ื—ื“ (Join), ืœื—ืฉื‘ ืžืฉื”ื• ืฉื™ืžื•ืฉื™ ืžื”ื ืชื•ื ื™ื ืฉื”ืชืงื‘ืœื•, ืœื›ืชื•ื‘ ืืช ื”ืชื•ืฆืื” ื‘ื—ื–ืจื” ืœ-InfluxDB, ืœืฉืœื•ื— ื”ืชืจืื” ืœ-Slack/Telegram/mail.

ื›ืœ ื”ืขืจื™ืžื” ืžื’ื ื™ื‘ื” ื•ืžืคื•ืจื˜ืช ืชื™ืขื•ื“, ืื‘ืœ ืชืžื™ื“ ื™ื”ื™ื• ื“ื‘ืจื™ื ืฉื™ืžื•ืฉื™ื™ื ืฉืœื ืžืฆื•ื™ื ื™ื ื‘ืžืคื•ืจืฉ ื‘ืžื“ืจื™ื›ื™ื. ื‘ืžืืžืจ ื–ื”, ื”ื—ืœื˜ืชื™ ืœืืกื•ืฃ ืžืกืคืจ ืขืฆื•ืช ืฉื™ืžื•ืฉื™ื•ืช, ืœื ืžื•ื‘ื ื•ืช ืžืืœื™ื”ืŸ (ื”ืชื—ื‘ื™ืจ ื”ื‘ืกื™ืกื™ ืฉืœ 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()
        .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 (1633, 1871, 6967) โ€“ ืื ื—ื ื• ืžื—ื›ื™ื ืœืชื™ืงื•ื ื™ื ื•ืกื•ื‘ืœื™ื ืงืฆืช.

ืฉื™ืžื•ืฉ ื‘ืชื ืื™ื ื‘ื—ื™ืฉื•ื‘ื™ื (ืื ื‘ืœืžื‘ื“ื”)

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

ื—ืžืฉ ื“ืงื•ืช ืื—ืจื•ื ื•ืช ืžื”ืฆื™ื ื•ืจ ืœืชืงื•ืคื”

ืœื“ื•ื’ืžื”, ืขืœื™ืš ืœื”ืฉื•ื•ืช ืืช ื”ืขืจื›ื™ื ืฉืœ ื—ืžืฉ ื”ื“ืงื•ืช ื”ืื—ืจื•ื ื•ืช ืขื ื”ืฉื‘ื•ืข ื”ืงื•ื“ื. ืืชื” ื™ื›ื•ืœ ืœืงื—ืช ืฉืชื™ ืืฆื•ื•ืช ืฉืœ ื ืชื•ื ื™ื ื‘ืฉืชื™ ืืฆื•ื•ืช ื ืคืจื“ื•ืช ืื• ืœื—ืœืฅ ื—ืœืง ืžื”ื ืชื•ื ื™ื ืžืชืงื•ืคื” ื’ื“ื•ืœื” ื™ื•ืชืจ:

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

ื—ืœื•ืคื” ืœื—ืžืฉ ื”ื“ืงื•ืช ื”ืื—ืจื•ื ื•ืช ืชื”ื™ื” ืœื”ืฉืชืžืฉ ื‘-BarrierNode, ืฉืžื ืชืง ื ืชื•ื ื™ื ืœืคื ื™ ื”ื–ืžืŸ ืฉืฆื•ื™ืŸ:

|barrier()
        .period(5m)

ื“ื•ื’ืžืื•ืช ืœืฉื™ืžื•ืฉ ื‘ืชื‘ื ื™ื•ืช Go ื‘ื”ื•ื“ืขื”

ืชื‘ื ื™ื•ืช ืžืชืื™ืžื•ืช ืœืคื•ืจืžื˜ ืžื”ื—ื‘ื™ืœื” text.templateืœื”ืœืŸ ื›ืžื” ื—ื™ื“ื•ืช ืฉื ืชืงืœื•ืช ื‘ื”ืŸ ืœืขืชื™ื ืงืจื•ื‘ื•ืช.

ืื—ืจืช

ืื ื—ื ื• ืขื•ืฉื™ื ืกื“ืจ ื‘ื“ื‘ืจื™ื ื•ืœื ืžืคืขื™ืœื™ื ืื ืฉื™ื ืขื ื˜ืงืกื˜ ืฉื•ื‘:

|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 ืžืืจื— ืื• ip:9092 ื™ื•ืžื ื™ื lvl=ืฉื’ื™ืื”

ืืคืฉืจื•ืช ืขื httpOut

ืžืฆื™ื’ ื ืชื•ื ื™ื ื‘ืฆื™ื ื•ืจ ื”ื ื•ื›ื—ื™:

|httpOut('something')

ืฆืคื• (ืงื‘ืœื•): ืžืืจื— ืื• ip:9092/kapacitor/v1/tasks/task_name/something

ืชื›ื ื™ืช ื‘ื™ืฆื•ืข

  • ื›ืœ ืžืฉื™ืžื” ืžื—ื–ื™ืจื” ืขืฅ ื‘ื™ืฆื•ืข ืขื ืžืกืคืจื™ื ืฉื™ืžื•ืฉื™ื™ื ื‘ืคื•ืจืžื˜ graphviz.
  • ืงื— ื‘ืœื•ืง ื ืงื•ื“ื”.
  • ื”ื“ื‘ืง ืื•ืชื• ื‘ืฆื•ืคื”, ืชื”ื ื”.

ืื™ืคื” ืขื•ื“ ืืคืฉืจ ืœื”ืฉื™ื’ ืžื’ืจืคื”?

ื—ื•ืชืžืช ื–ืžืŸ ื‘-influxdb ืขืœ ื›ืชื™ื‘ื” ื—ื•ื–ืจืช

ืœื“ื•ื’ืžื”, ื”ื’ื“ืจื ื• ื”ืชืจืื” ืœืกื›ื•ื ื”ื‘ืงืฉื•ืช ืœืฉืขื” (groupBy(1h)) ื•ืจื•ืฆื™ื ืœืชืขื“ ืืช ื”ื”ืชืจืื” ืฉื”ืชืจื—ืฉื” ื‘-influxdb (ื›ื“ื™ ืœื”ืจืื•ืช ื™ืคื” ืืช ืขื•ื‘ื“ืช ื”ื‘ืขื™ื” ืขืœ ื”ื’ืจืฃ ื‘ื’ืจืืคื ื”).

influxDBOut() ื™ื›ืชื•ื‘ ืืช ืขืจืš ื”ื–ืžืŸ ืžื”ื”ืชืจืื” ืœื—ื•ืชืžืช ื”ื–ืžืŸ; ื‘ื”ืชืื, ื”ื ืงื•ื“ื” ื‘ืชืจืฉื™ื ืชื™ื›ืชื‘ ืžื•ืงื“ื/ืžืื•ื—ืจ ืžื”ื”ืชืจืื” ืฉื”ื’ื™ืขื”.

ื›ืืฉืจ ื ื“ืจืฉ ื“ื™ื•ืง: ืื ื• ืขื•ืงืคื™ื ืืช ื”ื‘ืขื™ื” ืขืœ ื™ื“ื™ ืงืจื™ืื” ืœืžื˜ืคืœ ืžื•ืชืื ืื™ืฉื™ืช, ืฉื™ื›ืชื•ื‘ ื ืชื•ื ื™ื ืœ-influxdb ืขื ื—ื•ืชืžืช ื”ื–ืžืŸ ื”ื ื•ื›ื—ื™ืช.

docker, ื‘ื ื™ื™ื” ื•ืคืจื™ืกื”

ื‘ืขืช ื”ื”ืคืขืœื”, Capacitor ื™ื›ื•ืœ ืœื˜ืขื•ืŸ ืžืฉื™ืžื•ืช, ืชื‘ื ื™ื•ืช ื•ืžื˜ืคืœื™ื ืžื”ืกืคืจื™ื™ื” ืฉืฆื•ื™ื ื” ื‘ืชืฆื•ืจื” ื‘ื‘ืœื•ืง [load].

ื›ื“ื™ ืœื™ืฆื•ืจ ืžืฉื™ืžื” ื ื›ื•ื ื”, ืืชื” ืฆืจื™ืš ืืช ื”ื“ื‘ืจื™ื ื”ื‘ืื™ื:

  1. ืฉื ื”ืงื•ื‘ืฅ - ืžื•ืจื—ื‘ ืœืžื–ื”ื”/ืฉื ืกืงืจื™ืคื˜
  2. ืกื•ื’ โ€“ ื–ืจื/ืืฆื•ื•ื”
  3. dbrp - ืžื™ืœืช ืžืคืชื— ืœืฆื™ื•ืŸ ื‘ืื™ื–ื” ืžืกื“ ื ืชื•ื ื™ื + ืžื“ื™ื ื™ื•ืช ื”ืกืงืจื™ืคื˜ ืคื•ืขืœ (dbrp "ืกืคืง." "autogen")

ืื ืžืฉื™ืžืช ืืฆื•ื•ื” ื›ืœืฉื”ื™ ืื™ื ื” ืžื›ื™ืœื” ืฉื•ืจื” ืขื dbrp, ื”ืฉื™ืจื•ืช ื›ื•ืœื• ื™ืกืจื‘ ืœื”ืชื—ื™ืœ ื•ื™ื›ืชื•ื‘ ืขืœื™ื” ื‘ื™ื•ืฉืจ ื‘ื™ื•ืžืŸ.

ื‘ื›ืจื•ื ื•ื’ืจืฃ, ืœื”ื™ืคืš, ื”ืฉื•ืจื” ื”ื–ื• ืœื ืืžื•ืจื” ืœื”ืชืงื™ื™ื; ื”ื™ื ืœื ืžืชืงื‘ืœืช ื“ืจืš ื”ืžืžืฉืง ื•ืžื—ื•ืœืœืช ืฉื’ื™ืื”.

ืคืจื™ืฆื” ื‘ืขืช ื‘ื ื™ื™ืช ืงื•ื ื˜ื™ื™ื ืจ: Dockerfile ื™ื•ืฆื ืขื -1 ืื ื™ืฉ ืฉื•ืจื•ืช ืขื //.+dbrp, ืžื” ืฉื™ืืคืฉืจ ืœืš ืœื”ื‘ื™ืŸ ืžื™ื“ ืืช ื”ืกื™ื‘ื” ืœื›ืฉืœ ื‘ืขืช ื”ืจื›ื‘ืช ื”-build.

ืœื”ืฆื˜ืจืฃ ืื—ื“ ืœืจื‘ื™ื

ืžืฉื™ืžื” ืœื“ื•ื’ืžื”: ืขืœื™ืš ืœืงื—ืช ืืช ื”ืื—ื•ื–ื•ืŸ ื”-95 ืžื–ืžืŸ ื”ื”ืคืขืœื” ืฉืœ ื”ืฉื™ืจื•ืช ืœืžืฉืš ืฉื‘ื•ืข, ืœื”ืฉื•ื•ืช ื›ืœ ื“ืงื” ืžืชื•ืš 10 ื”ืื—ืจื•ื ื•ืช ืœืขืจืš ื–ื”.

ืืชื” ืœื ื™ื›ื•ืœ ืœืขืฉื•ืช ื”ืฆื˜ืจืคื•ืช ืฉืœ ืื—ื“ ืœืจื‘ื™ื, ืื—ืจื•ืŸ/ืžืžื•ืฆืข/ื—ืฆื™ื•ืŸ ืžืขืœ ืงื‘ื•ืฆืช ื ืงื•ื“ื•ืช ื”ื•ืคืš ืืช ื”ืฆื•ืžืช ืœื–ืจื, ื”ืฉื’ื™ืื” "ืœื ื ื™ืชืŸ ืœื”ื•ืกื™ืฃ ืงืฆื•ื•ืช ืœื ืชื•ืืžื™ื ื‘ื™ืœื“: ืืฆื•ื•ื” -> ื–ืจื" ืชื•ื—ื–ืจ.

ื’ื ื”ืชื•ืฆืื” ืฉืœ ืืฆื•ื•ื”, ื›ืžืฉืชื ื” ื‘ื‘ื™ื˜ื•ื™ ืœืžื‘ื“ื”, ืื™ื ื” ืžื•ื—ืœืคืช.

ื™ืฉื ื” ืืคืฉืจื•ืช ืœืฉืžื•ืจ ืืช ื”ืžืกืคืจื™ื ื”ื“ืจื•ืฉื™ื ืžื”ืืฆื•ื•ื” ื”ืจืืฉื•ื ื” ืœืงื•ื‘ืฅ ื“ืจืš udf ื•ืœื˜ืขื•ืŸ ืืช ื”ืงื•ื‘ืฅ ื”ื–ื” ื‘ืืžืฆืขื•ืช sideload.

ืžื” ืคืชืจื ื• ืขื ื–ื”?

ื™ืฉ ืœื ื• ื›-100 ืกืคืงื™ ืžืœื•ื ื•ืช, ืœื›ืœ ืื—ื“ ืžื”ื ื™ื›ื•ืœื™ื ืœื”ื™ื•ืช ื›ืžื” ืงืฉืจื™ื, ื ืงืจื ืœื–ื” ืขืจื•ืฅ. ื™ืฉื ื ื›-300 ืขืจื•ืฆื™ื ืืœื”, ื›ืœ ืื—ื“ ืžื”ืขืจื•ืฆื™ื ืขืœื•ืœ ืœื™ืคื•ืœ. ืžื‘ื™ืŸ ื›ืœ ื”ืžื“ื“ื™ื ืฉื ืจืฉืžื•, ื ืขืงื•ื‘ ืื—ืจ ืฉื™ืขื•ืจ ื”ืฉื’ื™ืื•ืช (ื‘ืงืฉื•ืช ื•ืฉื’ื™ืื•ืช).

ืœืžื” ืœื ื’ืจืืคื ื”?

ืœื”ืชืจืื•ืช ืฉื’ื™ืื” ื”ืžื•ื’ื“ืจื•ืช ื‘-Grafana ื™ืฉ ืžืกืคืจ ื—ืกืจื•ื ื•ืช. ื—ืœืงื ืงืจื™ื˜ื™ื™ื, ื—ืœืงื ืืคืฉืจ ืœืขืฆื•ื ืขื™ื ื™ื™ื, ืชืœื•ื™ ื‘ืžืฆื‘.

ื’ืจืคืื ื” ืœื ื™ื•ื“ืข ืœื—ืฉื‘ ื‘ื™ืŸ ืžื“ื™ื“ื•ืช + ื”ืชืจืื”, ืื‘ืœ ืฆืจื™ืš ืชืขืจื™ืฃ (ื‘ืงืฉื•ืช-ื˜ืขื•ื™ื•ืช)/ื‘ืงืฉื•ืช.

ื”ืฉื’ื™ืื•ืช ื ืจืื•ืช ืžื’ืขื™ืœื•ืช:

ื˜ืจื™ืงื™ื ืœืขื™ื‘ื•ื“ ืžื“ื“ื™ื ื‘ืงืคืืกื™ื˜ื•ืจ

ื•ืคื—ื•ืช ืจืข ื›ืฉืžืกืชื›ืœื™ื ืขืœื™ื”ื ื‘ื‘ืงืฉื•ืช ืžื•ืฆืœื—ื•ืช:

ื˜ืจื™ืงื™ื ืœืขื™ื‘ื•ื“ ืžื“ื“ื™ื ื‘ืงืคืืกื™ื˜ื•ืจ

ืื•ืงื™ื™, ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœื—ืฉื‘ ืžืจืืฉ ืืช ื”ืชืขืจื™ืฃ ื‘ืฉื™ืจื•ืช ืœืคื ื™ ื’ืจืืคื ื”, ื•ื‘ืžืงืจื™ื ืžืกื•ื™ืžื™ื ื–ื” ื™ืขื‘ื•ื“. ืื‘ืœ ืœื ืืฆืœื ื•, ื›ื™... ืขื‘ื•ืจ ื›ืœ ืขืจื•ืฅ ื”ื™ื—ืก ืฉืœื• ื ื—ืฉื‘ "ื ื•ืจืžืœื™", ื•ื”ื”ืชืจืื•ืช ืคื•ืขืœื•ืช ืœืคื™ ืขืจื›ื™ื ืกื˜ื˜ื™ื™ื (ืื ื—ื ื• ืžื—ืคืฉื™ื ืื•ืชืŸ ื‘ืขื™ื ื™ื™ื, ืžืฉื ื™ื ืื•ืชืŸ ืื ื™ืฉ ื”ืชืจืื•ืช ืชื›ื•ืคื•ืช).

ืืœื• ื”ืŸ ื“ื•ื’ืžืื•ืช ืฉืœ "ืจื’ื™ืœ" ืขื‘ื•ืจ ืขืจื•ืฆื™ื ืฉื•ื ื™ื:

ื˜ืจื™ืงื™ื ืœืขื™ื‘ื•ื“ ืžื“ื“ื™ื ื‘ืงืคืืกื™ื˜ื•ืจ

ื˜ืจื™ืงื™ื ืœืขื™ื‘ื•ื“ ืžื“ื“ื™ื ื‘ืงืคืืกื™ื˜ื•ืจ

ืื ื• ืžืชืขืœืžื™ื ืžื”ื ืงื•ื“ื” ื”ืงื•ื“ืžืช ื•ืžื ื™ื—ื™ื ืฉื”ืชืžื•ื ื” ื”"ืจื’ื™ืœื”" ื“ื•ืžื” ืขื‘ื•ืจ ื›ืœ ื”ืกืคืงื™ื. ืขื›ืฉื™ื• ื”ื›ืœ ื‘ืกื“ืจ, ื•ืื ื—ื ื• ื™ื›ื•ืœื™ื ืœื”ืกืชื“ืจ ืขื ื”ืชืจืื•ืช ื‘ื’ืจืืคื ื”?
ืื ื—ื ื• ื™ื›ื•ืœื™ื, ืื‘ืœ ืื ื—ื ื• ืžืžืฉ ืœื ืจื•ืฆื™ื, ื›ื™ ืื ื—ื ื• ืฆืจื™ื›ื™ื ืœื‘ื—ื•ืจ ืื—ืช ืžื”ืืคืฉืจื•ื™ื•ืช:
ื) ืœื™ืฆื•ืจ ื”ืจื‘ื” ื’ืจืคื™ื ืขื‘ื•ืจ ื›ืœ ืขืจื•ืฅ ื‘ื ืคืจื“ (ื•ืœืœื•ื•ืช ืื•ืชื ื‘ื›ืื‘)
ื‘) ื”ืฉืืจ ืชืจืฉื™ื ืื—ื“ ืขื ื›ืœ ื”ืขืจื•ืฆื™ื (ื•ืชืœืš ืœืื™ื‘ื•ื“ ื‘ืงื•ื•ื™ื ื”ืฆื‘ืขื•ื ื™ื™ื ื•ื‘ื”ืชืจืื•ืช ื”ืžื•ืชืืžื•ืช ืื™ืฉื™ืช)

ื˜ืจื™ืงื™ื ืœืขื™ื‘ื•ื“ ืžื“ื“ื™ื ื‘ืงืคืืกื™ื˜ื•ืจ

ืื™ืš ืขืฉื™ืช ืืช ื–ื”?

ืฉื•ื‘, ื™ืฉ ื“ื•ื’ืžื” ื”ืชื—ืœื” ื˜ื•ื‘ื” ื‘ืชื™ืขื•ื“ (ื—ื™ืฉื•ื‘ ืชืขืจื™ืคื™ื ืขืœ ืคื ื™ ืกื“ืจื•ืช ืžืฆื˜ืจืคื•ืช), ื ื™ืชืŸ ืœื”ืฆื™ืฅ ืื• ืœืงื—ืช ื›ื‘ืกื™ืก ื‘ื‘ืขื™ื•ืช ื“ื•ืžื•ืช.

ืžื” ืขืฉื™ื ื• ื‘ืกื•ืฃ:

  • ืœื”ืฆื˜ืจืฃ ืœืฉืชื™ ืกื“ืจื•ืช ืชื•ืš ืžืกืคืจ ืฉืขื•ืช, ืžืงื‘ืฅ ืœืคื™ ืขืจื•ืฆื™ื;
  • ืžืœื ืืช ื”ืกื“ืจื” ืœืคื™ ืงื‘ื•ืฆื” ืื ืœื ื”ื™ื• ื ืชื•ื ื™ื;
  • ื”ืฉื•ื• ืืช ื”ื—ืฆื™ื•ืŸ ืฉืœ 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) < 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

ื”ื•ืกืคืช ืชื’ื•ื‘ื”