Commit dc2738af by bergquist

docs(example): move datasource example to seperate repo

parent 08a45e9a
## Example plugin implementations
[datasource-plugin-genericdatsource](https://github.com/grafana/datasource-plugin-genericdatasource/tree/3.0)
\ No newline at end of file
{
"disallowImplicitTypeConversion": ["string"],
"disallowKeywords": ["with"],
"disallowMultipleLineBreaks": true,
"disallowMixedSpacesAndTabs": true,
"disallowTrailingWhitespace": true,
"requireSpacesInFunctionExpression": {
"beforeOpeningCurlyBrace": true
},
"disallowSpacesInsideArrayBrackets": true,
"disallowSpacesInsideParentheses": true,
"validateIndentation": 2
}
\ No newline at end of file
{
"browser": true,
"esnext": true,
"bitwise":false,
"curly": true,
"eqnull": true,
"devel": true,
"eqeqeq": true,
"forin": false,
"immed": true,
"supernew": true,
"expr": true,
"indent": 2,
"latedef": true,
"newcap": true,
"noarg": true,
"noempty": true,
"undef": true,
"boss": true,
"trailing": true,
"laxbreak": true,
"laxcomma": true,
"sub": true,
"unused": true,
"maxdepth": 6,
"maxlen": 140,
"globals": {
"System": true,
"define": true,
"require": true,
"Chromath": false,
"setImmediate": true
}
}
module.exports = function(grunt) {
require('load-grunt-tasks')(grunt);
grunt.loadNpmTasks('grunt-execute');
grunt.loadNpmTasks('grunt-contrib-clean');
grunt.initConfig({
clean: ["dist"],
copy: {
src_to_dist: {
cwd: 'src',
expand: true,
src: ['**/*', '!**/*.js', '!**/*.scss'],
dest: 'dist'
},
pluginDef: {
expand: true,
src: 'plugin.json',
dest: 'dist',
}
},
watch: {
rebuild_all: {
files: ['src/**/*', 'plugin.json'],
tasks: ['default'],
options: {spawn: false}
},
},
babel: {
options: {
sourceMap: true,
presets: ["es2015"],
plugins: ['transform-es2015-modules-systemjs', "transform-es2015-for-of"],
},
dist: {
files: [{
cwd: 'src',
expand: true,
src: ['**/*.js'],
dest: 'dist',
ext:'.js'
}]
},
},
});
grunt.registerTask('default', ['clean', 'copy:src_to_dist', 'copy:pluginDef', 'babel']);
};
#Generic backend datasource#
More documentation about datasource plugins can be found in the [Docs](https://github.com/grafana/grafana/blob/master/docs/sources/plugins/datasources.md)
Your backend need implement 4 urls
* "/" Should return 200 ok. Used for "Test connection" on the datasource config page.
* "/search" Used by the find metric options on the query tab in panels
* "/query" Should return metrics based on input
* "/annotations" should return annotations
## Example backend implementation ##
https://gist.github.com/bergquist/bc4aa5baface3cffa109
\ No newline at end of file
{
"name": "kentik-app",
"private": true,
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "git+https://github.com/raintank/kentik-app-poc.git"
},
"author": "",
"license": "ISC",
"bugs": {
"url": "https://github.com/raintank/kentik-app-poc/issues"
},
"devDependencies": {
"grunt": "~0.4.5",
"babel": "~6.5.1",
"grunt-babel": "~6.0.0",
"grunt-contrib-copy": "~0.8.2",
"grunt-contrib-watch": "^0.6.1",
"grunt-contrib-uglify": "~0.11.0",
"grunt-systemjs-builder": "^0.2.5",
"load-grunt-tasks": "~3.2.0",
"grunt-execute": "~0.2.2",
"grunt-contrib-clean": "~0.6.0"
},
"dependencies": {
"babel-plugin-transform-es2015-modules-systemjs": "^6.5.0",
"babel-preset-es2015": "^6.5.0",
"lodash": "~4.0.0"
},
"homepage": "https://github.com/raintank/kentik-app-poc#readme"
}
{
"name": "GenericDatasource",
"id": "datasource-plugin-genericdatasource",
"type": "datasource",
"staticRoot": ".",
"metrics": true,
"annotations": true,
"info": {
"description": "generic datsource plugin",
"author": {
"name": "Raintank Inc.",
"url": "http://raintank.io"
},
"version": "0.9.0",
"updated": "2016-02-10"
},
"dependencies": {
"grafanaVersion": "2.6.x",
"plugins": [ ]
}
}
.generic-datasource-query-row .query-keyword {
width: 75px;
}
\ No newline at end of file
export class GenericDatasource {
constructor(instanceSettings, $q, backendSrv) {
this.type = instanceSettings.type;
this.url = instanceSettings.url;
this.name = instanceSettings.name;
this.q = $q;
this.backendSrv = backendSrv;
}
// Called once per panel (graph)
query(options) {
var query = this.buildQueryParameters(options);
if (query.targets.length <= 0) {
return this.q.when([]);
}
return this.backendSrv.datasourceRequest({
url: this.url + '/query',
data: query,
method: 'POST',
headers: { 'Content-Type': 'application/json' }
});
}
// Required
// Used for testing datasource in datasource configuration pange
testDatasource() {
return this.backendSrv.datasourceRequest({
url: this.url + '/',
method: 'GET'
}).then(response => {
if (response.status === 200) {
return { status: "success", message: "Data source is working", title: "Success" };
}
});
}
annotationQuery(options) {
return this.backendSrv.datasourceRequest({
url: this.url + '/annotations',
method: 'POST',
data: options
}).then(result => {
return result.data;
});
}
// Optional
// Required for templating
metricFindQuery(options) {
return this.backendSrv.datasourceRequest({
url: this.url + '/search',
data: options,
method: 'POST',
headers: { 'Content-Type': 'application/json' }
}).then(this.mapToTextValue);
}
mapToTextValue(result) {
return _.map(result.data, (d, i) => {
return { text: d, value: i};
});
}
buildQueryParameters(options) {
//remove placeholder targets
options.targets = _.filter(options.targets, target => {
return target.target !== 'select metric';
});
return options;
}
}
import {GenericDatasource} from './datasource';
import {GenericDatasourceQueryCtrl} from './query_ctrl';
class GenericConfigCtrl {}
GenericConfigCtrl.templateUrl = 'partials/config.html';
class GenericQueryOptionsCtrl {}
GenericQueryOptionsCtrl.templateUrl = 'partials/query.options.html';
class GenericAnnotationsQueryCtrl {}
GenericAnnotationsQueryCtrl.templateUrl = 'partials/annotations.editor.html'
export {
GenericDatasource as Datasource,
GenericDatasourceQueryCtrl as QueryCtrl,
GenericConfigCtrl as ConfigCtrl,
GenericQueryOptionsCtrl as QueryOptionsCtrl,
GenericAnnotationsQueryCtrl as AnnotationsQueryCtrl
};
<h5 class="section-heading">Query</h5>
<div class="gf-form-group">
<div class="gf-form">
<input type="text" class="gf-form-input" ng-model='ctrl.annotation.query' placeholder=""></input>
</div>
</div>
<datasource-http-settings current="ctrl.current">
</datasource-http-settings>
<query-editor-row ctrl="ctrl" class="generic-datasource-query-row">
<ul class="tight-form-list">
<li class="tight-form-item query-keyword">Query</li>
<li>
<metric-segment-model property="ctrl.target.target" get-options="ctrl.getOptions()" on-change="ctrl.onChangeInternal()" css-class="tight-form-item-xxlarge"></metric-segment-model>
</li>
</ul>
</query-editor-row>
<section class="grafana-metric-options" >
<div class="gf-form">
</div>
</section>
import {QueryCtrl} from 'app/plugins/sdk';
import './css/query-editor.css!'
export class GenericDatasourceQueryCtrl extends QueryCtrl {
constructor($scope, $injector, uiSegmentSrv) {
super($scope, $injector);
this.scope = $scope;
this.uiSegmentSrv = uiSegmentSrv;
this.target.target = this.target.target || 'select metric';
}
getOptions() {
return this.datasource.metricFindQuery(this.target)
.then(this.uiSegmentSrv.transformToSegments(false));
// Options have to be transformed by uiSegmentSrv to be usable by metric-segment-model directive
}
onChangeInternal() {
this.panelCtrl.refresh(); // Asks the panel to refresh data.
}
}
GenericDatasourceQueryCtrl.templateUrl = 'partials/query.editor.html';
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment