Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 2 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
# UPDATE

We are working to refresh this codebase. Please see the [milestones](https://github.com/grafana-druid-plugin/druidplugin/milestones) for current estimated dates and related issues / projects for planned work.

## Grafana Version Compatibility:
**Druid plugin version 0.0.3 and below are supported for Grafana: 3.x.x**

Expand All @@ -15,18 +11,6 @@ We are working to refresh this codebase. Please see the [milestones](https://git

## Status

This plugin is built on the top of an existing Druid plugin (https://github.com/grafana/grafana-plugins) which used to work on older Grafana versions. With the UI changes done on Grafana-3.0 the existing plugin stopped working. Lot of changes have been made to have it work on Grafana 3.0. It supports timeseries, group by, topN and Select queries.

Lot of features might still not be implemented. Your contributions are welcome.

## Plugin development history

This plugin was originally developed by Quantiply Corporation (Supported for Grafana versions < 2.5): https://github.com/grafana/grafana-plugins/tree/master/datasources/druid

This plugin was further enhanced by Carl Bergquist (https://github.com/grafana/grafana/pull/3328) (to support it on Grafana version 2.5 & 2.6).

I cloned the source from the Pull Request by Carl Bergquist and changed the plugin to have it work on Grafana-3.0.

All the credits for the original code and enahcement to 2.5 goes to Quantiply and Carl Bergquist.
This plugin is built on the top of an existing Druid plugin (https://github.com/grafana-druid-plugin/druidplugin). The original plugin get inputs from simple textboxes and drop downs. This comes at cost of generality. This plugin gets query as raw json query.

Opensourcing all the changes done to the plugin to support Grafana-3.0.
It supports timeseries, group by, topN and Select queries.
1 change: 0 additions & 1 deletion dist/config_ctrl.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/// <reference path="../node_modules/grafana-sdk-mocks/app/headers/common.d.ts" />
export declare class DruidConfigCtrl {
static templateUrl: string;
current: any;
Expand Down
18 changes: 9 additions & 9 deletions dist/datasource.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/// <reference path="../node_modules/grafana-sdk-mocks/app/headers/common.d.ts" />
import * as Druid from 'druid.d';
export default class DruidDatasource {
id: number;
Expand All @@ -12,24 +11,25 @@ export default class DruidDatasource {
periodGranularity: any;
GRANULARITIES: any[][];
filterTemplateExpanders: {
"selector": string[];
"regex": string[];
"javascript": string[];
"search": any[];
selector: string[];
regex: string[];
javascript: string[];
search: any[];
};
constructor(instanceSettings: any, $q: any, backendSrv: any, templateSrv: any);
query(options: any): any;
doQuery(from: any, to: any, granularity: any, target: any): any;
replaceVariables(obj: any): any;
splitCardinalityFields(aggregator: any): any;
selectQuery(datasource: string, intervals: Array<string>, granularity: Druid.Granularity, dimensions: Array<string | Object>, metric: Array<string | Object>, filters: Array<Druid.DruidFilter>, selectThreshold: Object): any;
timeSeriesQuery(datasource: string, intervals: Array<string>, granularity: Druid.Granularity, filters: Array<Druid.DruidFilter>, aggregators: Object, postAggregators: Object): any;
timeSeriesQuery(datasource: string, intervals: Array<string>, granularity: Druid.Granularity, filters: Object, aggregators: Object, postAggregators: Object): any;
topNQuery(datasource: string, intervals: Array<string>, granularity: Druid.Granularity, filters: Array<Druid.DruidFilter>, aggregators: Object, postAggregators: Object, threshold: number, metric: string | Object, dimension: string | Object): any;
groupByQuery(datasource: string, intervals: Array<string>, granularity: Druid.Granularity, filters: Array<Druid.DruidFilter>, aggregators: Object, postAggregators: Object, groupBy: Array<string>, limitSpec: Druid.LimitSpec): any;
druidQuery(query: Druid.AbstractDruidQuery): any;
getLimitSpec(limitNum: any, orderBy: any): {
"type": string;
"limit": any;
"columns": any;
type: string;
limit: any;
columns: any;
};
testDatasource(): any;
getDataSources(): any;
Expand Down
55 changes: 49 additions & 6 deletions dist/datasource.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion dist/datasource.js.map

Large diffs are not rendered by default.

70 changes: 53 additions & 17 deletions dist/datasource.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,8 @@ export default class DruidDatasource {
query(options) {
const from = this.dateToMoment(options.range.from, false);
const to = this.dateToMoment(options.range.to, true);

let promises = options.targets.map(target => {
if (target.hide === true || _.isEmpty(target.druidDS) || (_.isEmpty(target.aggregators) && target.queryType !== "select")) {
if (target.hide === true || _.isEmpty(target.druidDS)) {
const d = this.q.defer();
d.resolve([]);
return d.promise;
Expand All @@ -82,10 +81,13 @@ export default class DruidDatasource {
}

doQuery(from, to, granularity, target) {
let partialDruidObjectVariabled = JSON.parse(target.druidPartialQuery);
let partialDruidObject = this.replaceVariables(partialDruidObjectVariabled);

let datasource = target.druidDS;
let filters = target.filters;
let aggregators = target.aggregators.map(this.splitCardinalityFields);
let postAggregators = target.postAggregators;
let filters = partialDruidObject.filter;//target.filters;
let aggregators = partialDruidObject.aggregations;//target.aggregators.map(this.splitCardinalityFields);
let postAggregators = partialDruidObject.postAggregations;//target.postAggregators;
let groupBy = _.map(target.groupBy, (e) => { return this.templateSrv.replace(e) });
let limitSpec = null;
let metricNames = this.getMetricNames(aggregators, postAggregators);
Expand Down Expand Up @@ -122,6 +124,23 @@ export default class DruidDatasource {
});
}
else {
let samadQuery: Druid.DruidTimeSeriesQuery = {
queryType: "timeseries",
dataSource: datasource,
granularity: granularity,
intervals: intervals
};
let partialDruidObject = JSON.parse(target.druidPartialQuery)
if (partialDruidObject.filter) {
samadQuery.filter = partialDruidObject.filter
}
if (partialDruidObject.aggregations) {
samadQuery.aggregations = partialDruidObject.aggregations
}
if (partialDruidObject.postAggregations) {
samadQuery.postAggregations = partialDruidObject.postAggregations
}

promise = this.timeSeriesQuery(datasource, intervals, granularity, filters, aggregators, postAggregators)
.then(response => {
return this.convertTimeSeriesData(response.data, metricNames);
Expand Down Expand Up @@ -153,17 +172,35 @@ export default class DruidDatasource {
return metrics;
});
};

replaceVariables(obj):any {
let result = {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
if (typeof (obj[key]) == "object") {
if(Array.isArray(obj[key])){
result[key] = obj[key].map(item=>this.replaceVariables(item))
}else{
result[key] = this.replaceVariables(obj[key]);
}
} else if (typeof (obj[key]) == "string") {
result[key] = this.templateSrv.replace(obj[key]);
}else{
result[key] = obj[key];
}
}
}
return result;
};
splitCardinalityFields(aggregator) {
if (aggregator.type === 'cardinality' && typeof aggregator.fieldNames === 'string') {
aggregator.fieldNames = aggregator.fieldNames.split(',')
}
return aggregator;
}
};

selectQuery(datasource: string, intervals: Array<string>, granularity: Druid.Granularity,
dimensions: Array<string | Object>, metric: Array<string | Object>, filters: Array<Druid.DruidFilter>,
selectThreshold: Object) {
dimensions: Array<string | Object>, metric: Array<string | Object>, filters: Array<Druid.DruidFilter>,
selectThreshold: Object) {
let query: Druid.DruidSelectQuery = {
"queryType": "select",
"dataSource": datasource,
Expand All @@ -182,7 +219,7 @@ export default class DruidDatasource {
};

timeSeriesQuery(datasource: string, intervals: Array<string>, granularity: Druid.Granularity,
filters: Array<Druid.DruidFilter>, aggregators: Object, postAggregators: Object) {
filters: Object, aggregators: Object, postAggregators: Object) {
let query: Druid.DruidTimeSeriesQuery = {
queryType: "timeseries",
dataSource: datasource,
Expand All @@ -192,16 +229,15 @@ export default class DruidDatasource {
intervals: intervals
};

if (filters && filters.length > 0) {
query.filter = this.buildFilterTree(filters);
if (filters && Object.keys(filters).length > 0) {
query.filter = filters;
}

return this.druidQuery(query);
};

topNQuery(datasource: string, intervals: Array<string>, granularity: Druid.Granularity,
filters: Array<Druid.DruidFilter>, aggregators: Object, postAggregators: Object,
threshold: number, metric: string | Object, dimension: string | Object) {
filters: Array<Druid.DruidFilter>, aggregators: Object, postAggregators: Object,
threshold: number, metric: string | Object, dimension: string | Object) {
const query: Druid.DruidTopNQuery = {
queryType: "topN",
dataSource: datasource,
Expand All @@ -222,8 +258,8 @@ export default class DruidDatasource {
};

groupByQuery(datasource: string, intervals: Array<string>, granularity: Druid.Granularity,
filters: Array<Druid.DruidFilter>, aggregators: Object, postAggregators: Object, groupBy: Array<string>,
limitSpec: Druid.LimitSpec) {
filters: Array<Druid.DruidFilter>, aggregators: Object, postAggregators: Object, groupBy: Array<string>,
limitSpec: Druid.LimitSpec) {
const query: Druid.DruidGroupByQuery = {
queryType: "groupBy",
dataSource: datasource,
Expand Down
2 changes: 1 addition & 1 deletion dist/druid.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export interface AbstractDruidQuery {
intervals: Array<string>;
granularity: Granularity;
queryType: string;
filter?: DruidFilter;
filter?: Object;
aggregations?: Object;
postAggregations?: Object;
context?: Object;
Expand Down
Loading