Skip to content

Commit

Permalink
Merge branch 'feature/series-aggregation'
Browse files Browse the repository at this point in the history
  • Loading branch information
oberschlauberger committed Dec 5, 2018
2 parents 6edbcb9 + f94caf0 commit d23edb1
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 11 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ You can create variables for templating based on APM queries. You can either que
Considering the different temporal aggregation levels of CA APM, it makes sense to use a template variable to control the temporal resolution of time series data dynamically. Simply create a dashboard variable of type _Interval_ and use `15s,30s,1m,2m,6m,12m,24m,48m,1h,168m,12h` for the values.

### Series Aggregation
In raw query mode, you can choose an aggregation mode to aggregate multiple metrics into a single series of values. This way, you can get a single aggregated time series for visualization in Grafana if your query returns multiple metrics. The implemented aggregation modes are _sum_, _mean_, _max_, _min_, and _median_. Be careful when your metrics might contain null values - these are not explicitly handled by the aggregation methods.
In raw query mode, you can choose an aggregation mode to aggregate multiple metrics into a single series of values. This way, you can get a single aggregated time series for visualization in Grafana if your query returns multiple metrics. The implemented aggregation modes are _sum_, _mean_, _max_, _min_, and _median_.

![Series-Aggregation](https://github.com/NovaTecConsulting/ca-apm-grafana-datasource/blob/master/media/multi_series_aggregation.gif)

Expand Down
20 changes: 15 additions & 5 deletions dist/datasource.js
Original file line number Diff line number Diff line change
Expand Up @@ -164,16 +164,26 @@ var ApmDatasource = /** @class */ (function () {
if (!(rawMetricDataPoint.childNodes[3].getAttribute("xsi:nil") === "true")) {
// we have a value, convert to int implicitly
value = +rawMetricDataPoint.childNodes[3].textContent;
// collect values into map, drop NaN values
if (!isNaN(value)) {
metricData[id] = {
metricKey: rawMetricDataPoint.childNodes[0].textContent + legendSeparator + rawMetricDataPoint.childNodes[1].textContent,
metricValue: value
};
}
}
metricData[id] = {
metricKey: rawMetricDataPoint.childNodes[0].textContent + legendSeparator + rawMetricDataPoint.childNodes[1].textContent,
metricValue: value
};
}
;
// for each time slice, collect all referenced data points
slices.forEach(function (slice) {
var dataPoints = slice.references.map(function (reference) { return metricData[reference]; });
var dataPoints = slice.references
.reduce(function (dataPoints, reference) {
var dataPoint = metricData[reference];
if (typeof dataPoint != "undefined") {
dataPoints.push(dataPoint);
}
return dataPoints;
}, []);
// post processing, aggregation
if (/^sum|mean|max|min|median$/.test(aggregationMode)) {
var aggregate = aggregations[aggregationMode](dataPoints.map(function (dataPoint) { return dataPoint.metricValue; }));
Expand Down
20 changes: 15 additions & 5 deletions src/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -188,17 +188,27 @@ export class ApmDatasource {
if (!(rawMetricDataPoint.childNodes[3].getAttribute("xsi:nil") === "true")) {
// we have a value, convert to int implicitly
value = +rawMetricDataPoint.childNodes[3].textContent;
}

metricData[id] = {
metricKey: rawMetricDataPoint.childNodes[0].textContent + legendSeparator + rawMetricDataPoint.childNodes[1].textContent,
metricValue: value
// collect values into map, drop NaN values
if (!isNaN(value)) {
metricData[id] = {
metricKey: rawMetricDataPoint.childNodes[0].textContent + legendSeparator + rawMetricDataPoint.childNodes[1].textContent,
metricValue: value
}
}
}
};

// for each time slice, collect all referenced data points
slices.forEach(function (slice) {
var dataPoints: [MetricPoint] = slice.references.map(reference => metricData[reference]);
var dataPoints: [MetricPoint] = slice.references
.reduce((dataPoints, reference) => {
const dataPoint = metricData[reference];
if (typeof dataPoint != "undefined") {
dataPoints.push(dataPoint);
}
return dataPoints;
}, [])

// post processing, aggregation
if (/^sum|mean|max|min|median$/.test(aggregationMode)) {
Expand Down

0 comments on commit d23edb1

Please sign in to comment.