In my rule what I try to do is to calculate the overall count of points (agents_count
) in a window (where each point stands for an alive server along with its metadata), and then to re-use the same window data to filter some data points having only some certain tags values (idle_agents
), and calculate the percentage of the remaining points against the overall count. Finally, this % is evaluated in a threshold of an alert()
node. The simplified script is:
var data = stream
|from()
.measurement(measurement)
var agents = data
|window()
.period(window_period)
.every(window_every)
.align()
var agents_count = agents
|count('status_code')
var idle_agents = agents
|where(lambda: "status" == 'Idle')
var idle_agents_count = idle_agents
|count('status_code')
idle_agents_count
|join(agents_count)
.as('idle', 'all')
|eval(lambda: float("idle.count") * 100.0 / float("all.count"))
.as('idle.%')
.keep()
|alert()
.crit(lambda: "idle.%" <= float(crit_percent) OR "idle.count" <= crit_count)
What I want to include into my alert details is the data of the data stream before it’s got processed with count()
- variable idle_agents
in the case above. So that I not only get the bare % of the remaining points, but also the details of those remaining points (pretty printed somehow). This is how the data looks there:
{
"series": [
{
"name": "measurement",
"columns": [
"time",
"build_server",
"host",
"identity",
"name",
"organization",
"project",
"status",
"status_code"
],
"values": [
[
"2018-08-24T16:19:51Z",
"build02.host.corp",
"24511ae0f374",
"my-identity1",
"build02-agent-10",
"quality_assurance_and_support",
"build",
"Idle",
1
],
[
"2018-08-24T16:19:51Z",
"build02.host.corp",
"24511ae0f374",
"my-identity2",
"build02-agent-6",
"quality_assurance_and_support",
"build",
"Building",
2
],
...
The point is that once I process the points with count()
what I have remained in the node is only the following:
{
"series": [
{
"name": "measurement",
"columns": [
"time",
"count"
],
"values": [
[
"2018-08-24T16:07:30Z",
15
]
]
}
]
}
So I can’t access the original data when I then work it out with join()
and alert()
.
I tried some stupid thing as adding that variable reference containing all the data - .details(idle_agents)
, but of course ran into error:
invalid TICKscript: line 86 char 10: error calling func "details" on obj *pipeline.AlertNodeData: reflect.Set: value of type *pipeline.WindowNode is not assignable to type string
There are some other rules with which I ran into the same necessity too. What would be the suggestion to achieve that? So that alerts would be much more meaningful.