From telegraf snmp to influxdb for a percentil95th graph line

Resume: How can I draw a continuous line when I have a table with one value for X time range?

I’m getting data from SNMP counters with input plugin with Telegraf.
Then I send to a bucket on InfluxDBv2.

All fine, I achieve a rate graph for the consumed bandwidth per minute. With a dynamic range, (30m 1h, 20h, 5d)

I’m trying to obtain quantile 0.95 from that graph. This must be a continuous line. So I will have two lines in the same graph.

The percentile line will be the percentile from that window.

Currently, I can see the perc95 value when I select view raw data, but unable to show this continuous line to the graph:

query 1:

import ""
experimental/aggregate"

    from(bucket: "g")
      |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
      |> filter(fn: (r) => r["_measurement"] == "_sapBaseStatsIngressPchipOfferedHiPrioOctets")
      |> filter(fn: (r) => r["description"] == "xxx: xxx")
      |> aggregateWindow(every: 1m, fn: last, createEmpty: false)
      |> aggregate.rate(every: 1m, unit: 1s)
      |> yield(name: "last")

Apparently fine, the problem starts here:

query2:

import "experimental/aggregate"
from(bucket: "g")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "_sapBaseStatsIngressPchipOfferedHiPrioOctets")
  |> filter(fn: (r) => r["description"] == "xxx: xxx")
  |> aggregateWindow(every: 1m, fn: last, createEmpty: false)
  |> aggregate.rate(every: 1m, unit: 1s)
  |> quantile(q:0.95,)

A sample of csv output:

 false   false   true   true   false   
 #datatype   string   long dateTime:RFC3339   dateTime:RFC3339   double
 #default    _result
                   result   table   _start   _stop   _value
                                 0       2021-04-15T09:40:36.360235132Z  2021-04-15T10:40:36.360235132Z  
 532820.0516666668

Do you have any advice?

Hello @gil-obradors,
I did the following:

data = from(bucket: "telegraf")
  |> range(start: v.timeRangeStart, stop: v.timeRangeStop)
  |> filter(fn: (r) => r["_measurement"] == "cpu")
  |> filter(fn: (r) => r["_field"] == "usage_system")
  |> filter(fn: (r) => r["cpu"] == "cpu-total")
  |> limit(n: 10)

data
  |> yield(name: "data")

r0 = data
  |> quantile(column: "_value", q: 0.95, method: "estimate_tdigest", compression: 1000.0)
  |> findRecord(fn: (key) => key.cpu == "cpu-total", idx: 0)
data
  |> map(fn: (r) => ({ r with _value: r0._value }))
  |> yield(name: "quant_line") 

Does that work for your purposes?

1 Like

Nice example,

could you pls say is my example correct: I want graph with only data that in (or below of line) quantile (drop the data above the line)?
And if I collect “cpu-total” not from 1 host, but from many (near 200) how to show this percentile line & percentile data for each host?

r0 = data
|> quantile(column: “_value”, q: 0.9, method: “estimate_tdigest”, compression: 1000.0)
|> findRecord(fn: (key) => key.cpu == “cpu-total”, idx: 0)

data
|> filter(fn: (r) => r[“_value”] < r0._value )
|> yield(name: “below_quant_line”)

data
|> map(fn: (r) => ({ r with _value: r0._value }))
|> yield(name: “quant_line”)