Хотите использовать несколько окон в одном потоке с kapacitor
Цель: я хотел бы получить уведомление через 5 минут после состояния предупреждения, а затем каждые 30 минут после этого.
Я поиграл с .count() и функцией времени, но это ни к чему не привело, мне не хотелось вычислять этот беспорядок, и я не мог придумать, как сделать его удобным и надежным.
Решение, с которым я сейчас работаю, состоит в том, чтобы иметь два потока с отдельными окнами.
var initialData = stream
|from()
.database(db)
.measurement(metricType)
.retentionPolicy(rPolicy)
.groupBy(group)
.where(lambda: "cpu" == 'cpu-total')
.where(lambda: "host" =~ hostFilter)
|mean(metric)
.as('initialStat')
|window()
.period(10m)
.every(5m)
.align()
var continuousData = stream
|from()
.database(db)
.measurement(metricType)
.retentionPolicy(rPolicy)
.groupBy(group)
.where(lambda: metricType == 'cpu-total')
.where(lambda: "host" =~ hostFilter)
|mean(metric)
.as('continuousStat')
|window()
.period(10m)
.every(30)
.align()
Помимо того, что это кажется странным, мне нужно было бы рассчитать значения для каждого, и мне также нужно отдельно |alert()
узлы. Первый узел будет уведомлять только об изменении состояния, но второй узел не может иметь этого, поэтому я получаю напоминание о предупреждении каждые N минут. У меня также проблема в том, что первый |alert()
узел отправит OK
уведомление, а второй также отправит дупе OK
N минут спустя.
Я чувствую, что должен быть лучший способ сделать это. Я думаю, что я могу использовать if
заявление во втором |alert()
узел, чтобы не отправлять уведомление о OK
как первый |window
справлюсь с этим. На данный момент я еще не понял, как это сделать, но я уверен, что это возможно. Я также не хочу бороться с тикстингом, я знаю, что он не предназначен для использования в качестве полноценного языка в выпуске 741
Полный текст ниже
// CONFIGURATION PARAMETERS
// Alerting
var emailAddress = '$EMAIL'
var pagerdutyKey = '$PD'
var slackChannel = '$SLACK'
// Static Thresholds in percent cpu steal used
var warn = 85
var crit = 95
// Dynamic thresholds in number of std deviations
var warnSig = 2.5
var critSig = 3.5
// Print INFO level (every result will be an alert)
// AlertNode.StateChangesOnly will also need to be disabled
// NOTE:
// INFO level alerts will be disregarded by the pagerduty handler, this is not configurable.
var debug = FALSE
// Datastream
// Define the data that will be acted upon
var db = 'telegraf'
var group = 'host'
var metricType = 'cpu'
var metric = 'time_steal'
var rPolicy = 'default'
// Regex used to filter on a subset of hosts
var hostFilter = /.+/
// Window
var dataPeriod = 10m
var initialFrequency = 5m
var continuousFrequency = 30m
// DATAFRAME
var initialData = stream
|from()
.database(db)
.measurement(metricType)
.retentionPolicy(rPolicy)
.groupBy(group)
.where(lambda: metricType == 'cpu-total')
.where(lambda: "host" =~ hostFilter)
|mean(metric)
.as('initialStat')
|window()
.period(dataPeriod)
.every(initialFrequency)
.align()
var continuousData = stream
|from()
.database(db)
.measurement(metricType)
.retentionPolicy(rPolicy)
.groupBy(group)
.where(lambda: metricType == 'cpu-total')
.where(lambda: "host" =~ hostFilter)
|mean(metric)
.as('continuousStat')
|window()
.period(dataPeriod)
.every(continuousFrequency)
.align()
// Calculations
var initialCalculation = initialData
|eval(lambda: sigma("initialStat"))
.as('intialSigma')
.keep()
var continuousCalculation = continuousData
|eval(lambda: sigma("continuousStat"))
.as('continuousSigma')
.keep()
// ALERT CONDITIONS
var initialCondition = initialCalculation
|alert()
.id('{{ index .Tags "host" }}')
.message('{{ .ID }} is {{ .Level }}: CPU STEAL USAGE {{ index .Fields "initialStat" }}% SHORT')
.details('this is an alert')
.stateChangesOnly()
.info(lambda: debug)
.warn(lambda: "stat" < warn OR
"sigma" > warnSig)
.crit(lambda: "stat" < crit OR
"sigma" > critSig)
var continuousCondition = continuousCalculation
|alert()
.id('{{ index .Tags "host" }}')
.message('{{ .ID }} is {{ .Level }}: CPU STEAL USAGE {{ index .Fields "continuousStat" }}% LONG')
.details('this is an alert')
.info(lambda: debug)
.warn(lambda: "stat" < warn OR
"sigma" > warnSig)
.crit(lambda: "stat" < crit OR
"sigma" > critSig)
// ACTIONS
continuousCondition
// .log('/tmp/alerts/cpu_steal_usage_alerts')
// .slack()
// .channel(slackChannel)
.email(emailAddress)
.pagerDuty()
.serviceKey(pagerdutyKey)
initialCondition
// .log('/tmp/alerts/cpu_steal_usage_alerts')
// .slack()
// .channel(slackChannel)
.email(emailAddress)
.pagerDuty()
.serviceKey(pagerdutyKey)
1 ответ
Так что, очевидно, я могу сделать несколько окон в одном узле потока.
stream
|from()
.database(db)
.measurement(metricType)
.retentionPolicy(rPolicy)
.groupBy(group)
.where(lambda: metricType == metricFilter)
.where(lambda: "host" =~ hostFilter)
|window()
.period(dataPeriod)
.every(initialFrequency)
.align()
|mean(metric)
.as('initialStat')
|window()
.period(dataPeriod)
.every(continuousFrequency)
.align()
|mean(metric)
.as('continuousStat')
Все еще работает через OK
вопрос хотя.