How to do average of gauge metric in Prometheus - group-by

I have gauge metric (sample below). And I want to find the average of metric of last 10 hours for each hour. Not combine of 10 hours. I can easily do in SQl by hour in group by clause. But do not have good idea in prometheus query
{group="PrometheusDemo",resource="FinanceServicesGo",service="analyticsA",warning="1000"} 6
{group="PrometheusDemo",resource="FinanceServicesGo",service="analyticsB",warning="3000"} 9
{group="PrometheusDemo",resource="FinanceServicesGo",service="analyticsC",warning="2000"} 8
...
....
...
I tried below query -
avg({__name__="metricA"}) by (group, service)
Edited question
Problem statement
I have a metric A, with time and value (see image below). In hourly avg column, I took the average of each hours. and then in avg over avg column I took the avg of previous averaged column. I got value 9.12 but If I take the combine average of last 2 hour I will get 8.1. I want avg over avg value (9.12) using prometheus query. How I can do this by using prometheus query?

I think the following query will do the job:
avg by (group, service) (avg_over_time({__name__="metricA"}[1h]))

You're looking for subqueries:
https://prometheus.io/blog/2019/01/28/subquery-support/
https://prometheus.io/docs/prometheus/latest/querying/examples/#subquery
avg_over_time(avg by (group, service) (avg_over_time({__name__="metricA"}[1h]))[10h:1h])
The outermost query avg_over_time(query[10h:1h]) will evaluate a time period for 10h back, execute the query at 1h interval and then average those 10 results for each time series.
The inner query avg by (group, service) (avg_over_time({__name__="metricA"}[1h])) will run 10 times. avg_over_time({__name__="metricA"}[1h]) query will average each initial time series over 1h then get averaged by group and service by avg by (group, service) ().

Related

Graph Of utilization

My problem is as follows: I would like to create a graph of the percentage use of boxes over 24 hours. However, the box.utilization() function is cumulative, so I tried to solve the problem by creating a dataset that collects the values every hour and an event that resets the utilization so that the next hour is not affected by the previous hour's utilization.
(I attach a picture of the graph I created).
Is there a more efficient way?
I have faced the same issue before. Here is how I handled it:
Instead of cumulative utilization, I calculate the maximum hourly utilization. That is, I record the number of seized resource for every minute and get an array of 60 elements. Then divide the maximum number in that array by the total number of resources available. An example:
I have 100 machines
During an hour, maximum of 60 of them were busy
60/100= 60% maximum utilization during that hour
Then I plot these for each hour.

How to do a distinct count of a metric using graphite datasource in grafana?

I have a metric that shows the state of a server. The values are integers and if the value is 0 (zero) then the server is stable, else it is unstable. And the graph we have is at a minute level. So, I want to show an aggregated value to know how many hours the server is unstable in the selected time range.
Lets say, if I select "Last 7 days" as the time duration...we have get X hours of instability of server.
And one more thing, I have a line graph (time series graph) that shows the state of server...but, the thing is when I select "Last 24 hours or 48 hours" I am getting the graph at a minute level...when I increase the duration to a quarter I am getting the graph for every 5 min or something like that....I understand it's aggregating the values....but does any body know how the grafana is doing the aggregation ??
I have tried "scaleToSeconds" function and "ConsolidateBy" functions and many more to first get the count of non zero value minutes, but no success.
Any help would be greatly appreciated.
Thanks in advance.
There are a few different ways to tackle this, there are 2 places that aggregation happens in this situation:
When you query for a time range longer than your raw retention interval and whisper returns aggregated data. The aggregation method used here is defined in your carbon aggregation configuration.
When Grafana sends a query to Graphite it passes maxDataPoints=<width of graph in pixels>, and Graphite will perform aggregation to return at most that many points (because you don't have enough pixels to render more points than that). The method used for this consolidation is controlled by the consolidateBy function.
It is possible for both of these to be used in the same query if you eg have a panel that queries 3 days worth of data and you store 2 days at 1-minute and 7 days at 5-minute intervals in whisper then you'd have 72 * 60 / 5 = 864 points from the 5-minute archive in whisper, but if your graph is only 500px wide then at runtime that would be consolidated down to 10-minute intervals and return 432 points.
So, if you want to always have access to the count then you can change your carbon configuration to use sum aggregation for those series (and remove the existing whisper files so new ones are created with the new aggregation config), and pass consolidateBy('sum') in your queries, and you'll always get the sum back for each interval.
That said, you can also address this at query time by multiplying the average back out to get a total (assuming that your whisper aggregation config is using average). The simplest way to do that will be to summarize the data with average into buckets that match the longest aggregation interval you'll be querying, then scale those values by that interval to calculate the total number of minutes. Finally, you'll want to use consolidateBy('sum') so that any runtime consolidation will work properly.
consolidateBy(scale(summarize(my.series, '10min', 'avg'), 60), 'sum')
With all of that said, you may want to consider reporting uptime in terms of percentages rather than raw minutes, in which case you can use the raw averages directly.
When you say the value is zero (0), the server is healthy - what other values are reported while the server is unhealthy/unstable? If you're only reporting zero (healthy) or one (unhealthy), for example, then you could use the sumSeries function to get a count across multiple servers.
Some more information is needed here about the types of values the server is reporting in order to give you a better answer.
Grafana does aggregate - or consolidate - data typically by using the average aggregation function. You can override this using the 'sum' aggregation in the consolidateBy function.
To get a running calculation over time, you would most likely have to use the summarize function (also with the sum aggregation) and define the time period, e.g. 1 hour, 1 day, 1 week, and so on. You could take this a step further by combining this with a time template variable so that as the period grows/shrinks, the summarize period will increase/decrease accordingly.

Grafana / influxDB: How many minutes was metric value=1 during selected period?

Grafana / influxDB: So I have a boolean (0 or 1). I want to know how many minutes the value was 1 during a period I wish to select (several days). Can it be done? Thanks.
It will be tricky to calculate it in the InfluxDB however, Grafana has a 3rd party Discrete panel, where you can calculate it on the app/panel level. Panel calculation will be running in the browser, so it can be slow if you have many datapoints in the selected time period.

How to calculate the average value in a Prometheus query from Grafana

I was trying to create a Prometheus graph on Grafana, but i can't find the function which calculate the average value.
For example , to create a graph for read_latency, the result contain many tags. If there are 3 machine, there will be 3 tag seperately, for machine1, machine2, machine3. Here is a graph(click to show)
Prometheus
I want to combine these three together, so there will be only one tag : machines, and the value is the average of those three.
It seems that Prometheus query function doesn't have something like average(), so I am not sure how to do this.
I used to work on InfluxDB, and the graph can show like (click to show):
influxDB
I think you are searching for the avg() operation. see documentation
Use built-in $__interval variable, where node, name are custom labels (depending on you metrics):
sum(avg_over_time(some_metric[$__interval])) by (node, name)
or fixed value like 1m,1h etc:
sum(avg_over_time(some_metric[1m])) by (node, name)
You can filter using Grafana variables:
sum(avg_over_time(some_metric{cluster=~"$cluster"}[1m])) by (node, name)
Short answer: use avg() function to return the average value across multiple time series. For example, avg(metric) returns the average value for time series with metric name.
Long answer: Prometheus provides two functions for calculating the average:
avg_over_time calculates the average over raw sample stored in the database on the lookbehind window specified in square brackets. The average is calculated independently per each matching time series. For example, avg_over_time(metric[1h]) calculates average values for raw samples over the last hour per each time series with metric name.
avg calculates the average over multiple time series. The average is calculated independently per each point on the graph.
If you need to calculate the average over raw samples across all the time series, which match the given selector, per each time bucket, e.g.:
SELECT
time_bucket('5 minutes', timestamp) AS t,
avg(value)
FROM table
GROUP BY t
Then the following PromQL query must be used:
sum(sum_over_time(metric[$__interval])) / sum(count_over_time(metric[$__interval]))
Do not use avg(avg_over_time(metric[$__interval])), since it returns average of averages, which isn't equal to real average. See this explanation for details.

Tableau running average

I have a column of numeric data and another column by date. I'm trying to calculate a running average by week. I'm using a table calculation, Running Total on Average. This is not producing the running average I am expecting.
Example:
For 3rd week Running average, the running average is calculating the first week average + second week average + third week average, and then taking the average of those 3 numbers. What I want it to do is take all prior 3 week data and THEN take one single average as a whole. Hope that makes sense.
This seems to have done it. Calculated field:
RUNNING_SUM(SUM([NPS]))/RUNNING_SUM(COUNT([NPS]))