how to plot percentage on grafana? - monitoring

I have success and failure metrics as follows:
A.B.p1.success
A.B.p3.success
A.B.p4.success
...
A.B.p1.failure
A.B.p2.failure
A.B.p4.failure
...
I have in total ~30 persons, and I want to show the each person's success rate as calculated by:
alias(asPercent(A.B.p1.success,sumSeries(A.B.p1.success,A.B.p1.failure)), 'p1')
The problem I have:
1) If I hard-code all the persons in each row, it exceeds the max row Grafana allowed, andd I want to plot them on the same graph
2) If there a way I can do it by a Grafana function?
Thanks in advance!

The way to do this in Graphite is to use a subquery:
add two queries in Grafana, query #A for the total and query #B for the success rate
Hide query #A
Pass query #A as a parameter into the AsPercent function in query #B
Use the sumSeriesWithWildcard function to sum multiple series to get the total in #A:
https://stackoverflow.com/a/12837800/22688
For more, on the AsPercent function read my blog post on this. I describe how to use the AsPercent function at the end:
https://danlimerick.wordpress.com/2017/01/29/graphite-and-grafana-how-to-calculate-percentage-of-totalpercent-distribution/
If the asPercent function does not work (depends on which version and variant of Graphite you are using), you can achieve the same result with mapSeries and reduceSeries (also in the blog post):
aliasByNode(reduceSeries(mapSeries(groupByNodes(snap.gceprod.*.intel.docker.kube-system.*.snap.stats.filesystem.*.{usage,capacity}, 'maxSeries', 2, 11), 0), 'asPercent', 1, 'usage', 'capacity'), 0)
I answered a similar question here if you need another example: https://stackoverflow.com/a/42714756/22688

Related

InfluxDB: How to create a continuous query to calculate delta values?

I'd like to calculate the delta values for a series of measurements stored in an InfluxDB. The values are readings from an electricity meter taken every 5 minutes. The values increase over time. Here is subset of the data to give you an idea (commands shown below are executed in the InfluxDB CLI):
> SELECT "Haushaltstromzaehler - cnt" FROM "myhome_measurements" WHERE time >= '2018-02-02T10:00:00Z' AND time < '2018-02-02T11:00:00Z'
name: myhome_measurements
time Haushaltstromzaehler - cnt
---- --------------------------
2018-02-02T10:00:12.610811904Z 11725.638
2018-02-02T10:05:11.242021888Z 11725.673
2018-02-02T10:10:10.689827072Z 11725.707
2018-02-02T10:15:12.143326976Z 11725.736
2018-02-02T10:20:10.753357056Z 11725.768
2018-02-02T10:25:11.18448512Z 11725.803
2018-02-02T10:30:12.922032896Z 11725.837
2018-02-02T10:35:10.618788096Z 11725.867
2018-02-02T10:40:11.820355072Z 11725.9
2018-02-02T10:45:11.634203904Z 11725.928
2018-02-02T10:50:11.10436096Z 11725.95
2018-02-02T10:55:10.753853952Z 11725.973
Calculating the differences in the InfluxDB CLI is pretty straightforward with the difference() function. This gives me the electricity consumed within the 5 minutes intervals:
> SELECT difference("Haushaltstromzaehler - cnt") FROM "myhome_measurements" WHERE time >= '2018-02-02T10:00:00Z' AND time < '2018-02-02T11:00:00Z'
name: myhome_measurements
time difference
---- ----------
2018-02-02T10:05:11.242021888Z 0.03499999999985448
2018-02-02T10:10:10.689827072Z 0.033999999999650754
2018-02-02T10:15:12.143326976Z 0.02900000000045111
2018-02-02T10:20:10.753357056Z 0.0319999999992433
2018-02-02T10:25:11.18448512Z 0.03499999999985448
2018-02-02T10:30:12.922032896Z 0.033999999999650754
2018-02-02T10:35:10.618788096Z 0.030000000000654836
2018-02-02T10:40:11.820355072Z 0.03299999999944703
2018-02-02T10:45:11.634203904Z 0.028000000000247383
2018-02-02T10:50:11.10436096Z 0.02200000000084401
2018-02-02T10:55:10.753853952Z 0.02299999999922875
Where I struggle is getting this to work in a continuous query. Here is the command I used to setup the continuous query:
CREATE CONTINUOUS QUERY cq_Haushaltstromzaehler_cnt ON myhomedb
BEGIN
SELECT difference(sum("Haushaltstromzaehler - cnt")) AS "delta" INTO "Haushaltstromzaehler_delta" FROM "myhome_measurements" GROUP BY time(1h)
END
Looking in the InfluxDB log file I see that no data is written in the new 'delta' measurement from the continuous query execution:
...finished continuous query cq_Haushaltstromzaehler_cnt, 0 points(s) written...
After much troubleshooting and experimenting I now understand why no data is generated. Setting up a continuous query requires to use the GROUP BY time() statement. This in turn requires to use an aggregate function within the differences() function. The problem now is that the aggregate function returns only one value for the time period specified by GROUP BY time(). Obviously, the differences() function cannot calculate a difference from just one value. Essentially, continuous query executes a command like this:
> SELECT difference(sum("Haushaltstromzaehler - cnt")) FROM "myhome_measurements" WHERE time >= '2018-02-02T10:00:00Z' AND time < '2018-02-02T11:00:00Z' GROUP BY time(1h)
>
I'm now somewhat clueless as to how to make this work and appreciate any advice you might have.
Does it help using the last aggregate function? Not tested this as a cq yet.
Select difference(last(T1_Consumed)) AS T1_Delta, difference(last(T2_Consumed)) AS T2_Delta
from P1Data
where time >= 1551648871000000000 group by time(1h)
DIFFERENCE() would calculate delta from the "aggregated" value taken from previous group, not within current group.
So fill free to use selector function there - since your counters seemed to be cumulative, LAST() should be working well.

SSRS: Adding a filter that returns information from entire group

I am trying to create a report in SSRS. Below is a small example of what my dataset looks like.
Example Data Set
So, there are three different stores (A,B,C) and each has a landlord (a,b,c). Landlords can pay via three different methods (1,2,3) and the amounts paid per method are shown.
Right now, I have two filters set up. The first is by Store and the second is by Landlord.
What I am having trouble with is:
How can I set up a filter by the Amount that will return information from an entire Store/Landlord?
So for example, if I wanted to filter Amount by 150, I would like to return all the "payment" information for the store(s) that have a payment of 150. Such as the following:
Desired Result
Is it possible to add a filter to return information from the entire group? (Store and Landlord are the group in this case)
I am new to SSRS so any help/insight would be greatly appreciated!
You can use LookUpSet to locate the matching groups, JOIN to put the results in a string and the INSTR function to filter your results.
=IIF(ISNOTHING(Parameters!AMOUNT.Value) OR INSTR(
Join(LOOKUPSET(Fields!Amount.Value, Fields!Amount.Value, Fields!Store.Value, "DataSet1"), ", ") ,
Fields!Store.Value
) > 0, 1, 0)
This translates to:
If the Store value is found (INSTR > 0) in the list (JOIN) of Stores where the Amount is the current Amount (Lookupset).
In your filter, put the above expression in the Expression, change the type to INTEGER and the Value to 1.
[

grails 2.4.4, how to do pagination with very large record set, so dont know the total

All the examples I can find do something like this:
<g:paginate controller="Book" action="list" total="${bookInstanceTotal}" />
and the total attribute is "required" according to the documentation.
This works fine for very simple examples with small record sets (e.g. a few hundred)
If there are say 100k rows returned because the user put in wide search criteria, then I certainly don't want to read them all to find the total to allow pagination, and don't want to transfer all 100k rows from the db to the grails server, and don't want to repeat this each time thy hit the next page. I want to use the mysql limit/offset or similar to only bring back the small number of required rows.
Is this possible, or do I really have to work out the total (by reading all the records, or doing a separate count, then read the records?
I will always prefer to use criteria for pagination.
The example of using criteria :
def c = Account.createCriteria()
def results = c.list (max: 10, offset: 10) {
like("holderFirstName", "Fred%")
and {
between("balance", 500, 1000)
eq("branch", "London")
}
order("holderLastName", "desc")
}
This example is taken from grails documentation and you can read more about criteria in this documentation.
Using this criteria, you will get at max 10 results. But the important part is you can get total count according to the same criteria by using
results.totalCount
You don't read all records from db and load in grails to get the total. You just load 10 or whatever number of records you display in each page and you execute a count query to get the totalCount.
It works like this.
Lets say, you display 10 records on each page and you have 100K records in db.
Lets say UI passes max and offset params.
params.max = params.max ? (params.int(max) < 100 : params.max : 100) : 10
params.offset = params.offset ?: 0
def list = Domain.list(params)
When max option is specified, Domain.list() method returns PagedResultList which has getTotalCount() method which fires a count query and returns totalCount.
And you render the view like this
render(view:"list", model:[list:list, totalCount:list.totalCount)
So here you are not loading all the records from database, you are loading just 10 records and execute a count query to get totalCount

How to use perform division between two sums

I try to do something the following division using sum over two columns like this.
Report.sum('(clicks_count / nullif(sum(views_count),0))')
But I get the error PG::GroupingError: ERROR: aggregate function calls cannot be nested.
I'm a bit stuck in how to perform this query in ActiveRecord, any idea?
Try Report.sum(clicks_count) / Report.sum(view_count).
If you'd like to use only one query, then you can use pluck:
Report.pluck('sum(clicks_count) / nullif(sum(views_count),0))').first
You can also group by another attribute (for example date):
Report.group(:date).pluck('sum(clicks_count) / nullif(sum(views_count),0))')
This will give you the clicks_count sum divided by views_count sum for each date.

Doing calculation in ruby on rails Model.sum()

I have a model called Data and some columns called timestamp, value1 and value2. I would like to use it with highstock chart.
Before the chart is printed I would like some calculations on it:
Summarize the result of value1 devided by value2 (value1/value2) by each day or month or year and put it in an array like [[timestamp_day, value1/value2], [...], ...].
I'm able to do the "timestamp-grouping". But I'm hanging on summarize the value1/value2.
Is there a way to do it like .sum(value1/value2)? Or is there any way to define a virtual column that does the calculation?
Thanks & best regards, Andreas
If you're trying to grab the calculated values right from the database you can pass an expression into the active record sum function.
Data.group(:timestamp).sum("value1 / value2")
#array = #collection.collect { |c| [v.timestamp, (v.value1+v.value2 /3)] }
#collection is the collection/array of all your data
#array will be of this format after collect is executed: [[timestamp_day, value1/value2], [...], ...]
The one thing that isn't clear is what the denominator is. I use "3" here but could be anything you want. You could even call up another method to get it if it's a complex operation.

Resources