grafana/public/app/features/plugins/datasource_srv.ts
David Kaltschmidt 411719bc70 Explore: POC for datasource query importers
Explore is about keeping context between datasources if possible. When
changing from metrics to logging, some of the filtering can be kept to
narrow down logging streams relevant to the metrics.

- adds `importQueries` function in language providers
- query import dependent on origin datasource
- implemented  prometheus-to-logging import: keeping label selectors
  that are common to both datasources
- added types
2018-11-16 13:52:58 +00:00

185 lines
4.6 KiB
TypeScript

// Libraries
import _ from 'lodash';
import coreModule from 'app/core/core_module';
// Utils
import config from 'app/core/config';
import { importPluginModule } from './plugin_loader';
// Types
import { DataSourceApi } from 'app/types/series';
import { DataSource } from 'app/types';
export class DatasourceSrv {
datasources: { [name: string]: DataSource };
/** @ngInject */
constructor(private $q, private $injector, private $rootScope, private templateSrv) {
this.init();
}
init() {
this.datasources = {};
}
get(name?: string): Promise<DataSourceApi> {
if (!name) {
return this.get(config.defaultDatasource);
}
name = this.templateSrv.replace(name);
if (name === 'default') {
return this.get(config.defaultDatasource);
}
if (this.datasources[name]) {
return this.$q.when(this.datasources[name]);
}
return this.loadDatasource(name);
}
loadDatasource(name: string): Promise<DataSourceApi> {
const dsConfig = config.datasources[name];
if (!dsConfig) {
return this.$q.reject({ message: 'Datasource named ' + name + ' was not found' });
}
const deferred = this.$q.defer();
const pluginDef = dsConfig.meta;
importPluginModule(pluginDef.module)
.then(plugin => {
// check if its in cache now
if (this.datasources[name]) {
deferred.resolve(this.datasources[name]);
return;
}
// plugin module needs to export a constructor function named Datasource
if (!plugin.Datasource) {
throw new Error('Plugin module is missing Datasource constructor');
}
const instance: DataSource = this.$injector.instantiate(plugin.Datasource, { instanceSettings: dsConfig });
instance.meta = pluginDef;
instance.name = name;
instance.pluginExports = plugin;
this.datasources[name] = instance;
deferred.resolve(instance);
})
.catch(err => {
this.$rootScope.appEvent('alert-error', [dsConfig.name + ' plugin failed', err.toString()]);
});
return deferred.promise;
}
getAll() {
return config.datasources;
}
getAnnotationSources() {
const sources = [];
this.addDataSourceVariables(sources);
_.each(config.datasources, value => {
if (value.meta && value.meta.annotations) {
sources.push(value);
}
});
return sources;
}
getExploreSources() {
const { datasources } = config;
const es = Object.keys(datasources)
.map(name => datasources[name])
.filter(ds => ds.meta && ds.meta.explore);
return _.sortBy(es, ['name']);
}
getMetricSources(options) {
const metricSources = [];
_.each(config.datasources, (value, key) => {
if (value.meta && value.meta.metrics) {
let metricSource = { value: key, name: key, meta: value.meta, sort: key };
//Make sure grafana and mixed are sorted at the bottom
if (value.meta.id === 'grafana') {
metricSource.sort = String.fromCharCode(253);
} else if (value.meta.id === 'mixed') {
metricSource.sort = String.fromCharCode(254);
}
metricSources.push(metricSource);
if (key === config.defaultDatasource) {
metricSource = { value: null, name: 'default', meta: value.meta, sort: key };
metricSources.push(metricSource);
}
}
});
if (!options || !options.skipVariables) {
this.addDataSourceVariables(metricSources);
}
metricSources.sort((a, b) => {
if (a.sort.toLowerCase() > b.sort.toLowerCase()) {
return 1;
}
if (a.sort.toLowerCase() < b.sort.toLowerCase()) {
return -1;
}
return 0;
});
return metricSources;
}
addDataSourceVariables(list) {
// look for data source variables
for (let i = 0; i < this.templateSrv.variables.length; i++) {
const variable = this.templateSrv.variables[i];
if (variable.type !== 'datasource') {
continue;
}
let first = variable.current.value;
if (first === 'default') {
first = config.defaultDatasource;
}
const ds = config.datasources[first];
if (ds) {
const key = `$${variable.name}`;
list.push({
name: key,
value: key,
meta: ds.meta,
sort: key,
});
}
}
}
}
let singleton: DatasourceSrv;
export function setDatasourceSrv(srv: DatasourceSrv) {
singleton = srv;
}
export function getDatasourceSrv(): DatasourceSrv {
return singleton;
}
coreModule.service('datasourceSrv', DatasourceSrv);
export default DatasourceSrv;