Search code examples
influxdbflux

InfluxDB critical alert when values ​are not equal


I have alerting when I need a value greater than 5. It works and everything is fine with that.

import "influxdata/influxdb/monitor"
import "influxdata/influxdb/v1"

data = from(bucket: "my_bucket")
    |> range(start: -15s)
    |> filter(fn: (r) => r["_measurement"] == "my_mes")
    |> filter(fn: (r) => r["service"] == "test_service")
    |> filter(fn: (r) => r["action"] == "differ")
    |> filter(fn: (r) => r["env"] == "production")
    |> filter(fn: (r) => r["response_code"] == "400")
    |> filter(fn: (r) => r["_field"] == "value")
    |> aggregateWindow(every: 15s, fn: sum, createEmpty: false)

option task = {name: "differ_task", every: 15s, offset: 0s}

check = {_check_id: "12345", _check_name: "check_differ", _type: "threshold", tags: {differ_tag: "1"}}
crit = (r) => r["value"] > 5.0
messageFn = (r) => "Check: ${ r._check_name } is: ${ r._level }"

data |> v1["fieldsAsCols"]() |> monitor["check"](data: check, messageFn: messageFn, crit: crit)

However, I need to change the alerting so that it occurs when there is a difference (no matter which way) between the values.

Let's say the result of the sum of

r["response_code"] == "0"

and

r["response_code"] == "200"

in 15 seconds - not equal.

I tried to write a custom query, using the visual tools I did not find how to do it. However, this query does not work as I need. Is it possible to do this at all? Perhaps with the help of variables and their subsequent comparison?

import "influxdata/influxdb/monitor"
import "influxdata/influxdb/v1"

data = from(bucket: "my_bucket")
    |> range(start: -15s)
    |> filter(fn: (r) => r["_measurement"] == "my_mes")
    |> filter(fn: (r) => r["service"] == "test_service")
    |> filter(fn: (r) => r["action"] == "differ")
    |> filter(fn: (r) => r["env"] == "production")
    |> filter(fn: (r) => r["response_code"] == "0")
    |> filter(fn: (r) => r["_field"] == "value")
    |> aggregateWindow(every: 15s, fn: sum, createEmpty: false)

data2 = from(bucket: "my_bucket")
    |> range(start: -15s)
    |> filter(fn: (r2) => r2["_measurement"] == "my_mes")
    |> filter(fn: (r2) => r2["service"] == "test_service")
    |> filter(fn: (r2) => r2["action"] == "differ")
    |> filter(fn: (r2) => r2["env"] == "production")
    |> filter(fn: (r2) => r2["response_code"] == "200")
    |> filter(fn: (r2) => r2["_field"] == "value")
    |> aggregateWindow(every: 15s, fn: sum, createEmpty: false)

option task = {name: "differ_task", every: 15s, offset: 0s}

check = {_check_id: "12345", _check_name: "check_differ", _type: "threshold", tags: {differ_tag: "1"}}
crit = (r) => r["value"] != r2["value"]
messageFn = (r) => "Check: ${r._check_name} is: ${r._level}"

data |> v1["fieldsAsCols"]() |> monitor["check"](data: check, messageFn: messageFn, crit: crit)

Solution

  • import "experimental"
    import "math"
    
    start = from(bucket: "my_bucket")
        |> range(start: -15s)
        |> filter(fn: (r) => r["_measurement"] == "my_mes")
        |> filter(fn: (r) => r["_field"] == "value")
        |> filter(fn: (r) => r["action"] == "differ")
        |> filter(fn: (r) => r["response_code"] == "0")
        |> filter(fn: (r) => r["env"] == "production")
        |> filter(fn: (r) => r["service"] == "test_service")
        |> experimental.count()
        |> yield(name: "start")
    
    success = from(bucket: "my_bucket")
        |> range(start: -15s)
        |> filter(fn: (r) => r["_measurement"] == "my_mes")
        |> filter(fn: (r) => r["_field"] == "value")
        |> filter(fn: (r) => r["action"] == "recalculate")
        |> filter(fn: (r) => r["response_code"] == "200")
        |> filter(fn: (r) => r["env"] == "production")
        |> filter(fn: (r) => r["service"] == "test_service")
        |> experimental.count()
        |> yield(name: "success")
    
    resStart = start
        |> findColumn(
            fn: (key) => key._field == "value",
            column: "_value",
        )
    resSuccess = success
        |> findColumn(
            fn: (key) => key._field == "value",
            column: "_value",
        )
    //difference >= 4.0 do some alert
    if math.abs(x: float(v: resStart[0]) - float(v: resSuccess[0])) >= 4.0 then
        #DO SOME ALERT
    else
        0