Browse Source

Merge pull request #8 from CorpGlory/grafana-data-exporter-sync-01

sync acd2a2e756eba25134a8f7237994239c640555d3
dependabot/npm_and_yarn/handlebars-4.7.6
Coin de Gamma 4 years ago committed by GitHub
parent
commit
a0a94fd4c2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      .gitignore
  2. 2
      LICENSE
  3. 10
      README.md
  4. 5103
      package-lock.json
  5. 13
      package.json
  6. 1
      src/metrics/metric.ts
  7. 5
      src/metrics/metrics_factory.ts
  8. 5
      src/metrics/mysql_metric.ts
  9. 62
      src/metrics/postgres_metric.ts
  10. 68
      src/metrics/sql_metric.ts

1
.gitignore vendored

@ -4,4 +4,3 @@ node_modules/
npm-debug.log npm-debug.log
.vscode/ .vscode/
lib/ lib/
package-lock.json

2
LICENSE

@ -1,6 +1,6 @@
MIT License MIT License
Copyright (c) 2020 CorpGlory Copyright (c) 2018 CorpGlory
Permission is hereby granted, free of charge, to any person obtaining a copy Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal of this software and associated documentation files (the "Software"), to deal

10
README.md

@ -1,11 +1,11 @@
# tsdb-kit # tsdb-kit
[![Build Status](https://travis-ci.org/CorpGlory/tsdb-kit.svg?branch=master)](https://travis-ci.org/CorpGlory/tsdb-kit) [![Build Status](https://travis-ci.org/CorpGlory/tsdb-kit.svg?branch=master)](https://travis-ci.org/CorpGlory/grafana-datasource-kit)
Node.js library for running Grafana datasources on backend plus utils. Node.js library and utilities for running Grafana datasources on backend.
You can send your datasource metric from Grafana to compile it on Node.js and query your datasource via Grafana API in background. You can send your datasource metrics from Grafana to compile it on Node.js and query your datasource via Grafana API in background.
User gets unified interface to all datasources. Library gives single output format: fields order, time units, etc User gets a unified interface to all datasources. Library gives single output format: fields order, time units, etc
## Supported datasources ## Supported datasources
@ -15,7 +15,7 @@ User gets unified interface to all datasources. Library gives single output form
* PostgreSQL / TimescaleDB * PostgreSQL / TimescaleDB
* ElasticSearch * ElasticSearch
Please write us a letter if you want your datasource to be supported: ping@corpglory.com Please write us at ping@corpglory.com if you want your datasource to be supported:
## Projects based on library ## Projects based on library
* [grafana-data-exporter](https://github.com/CorpGlory/grafana-data-exporter) * [grafana-data-exporter](https://github.com/CorpGlory/grafana-data-exporter)

5103
package-lock.json generated

File diff suppressed because it is too large Load Diff

13
package.json

@ -1,6 +1,6 @@
{ {
"name": "@corpglory/tsdb-kit", "name": "grafana-datasource-kit",
"version": "1.0.1", "version": "0.1.17",
"description": "", "description": "",
"scripts": { "scripts": {
"build": "tsc", "build": "tsc",
@ -9,20 +9,19 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "git+https://github.com/CorpGlory/tsdb-kit.git" "url": "git+https://github.com/CorpGlory/grafana-datasource-kit.git"
}, },
"author": "CorpGlory Inc.", "author": "CorpGlory Inc.",
"publishConfig": { "publishConfig": {
"access": "public" "access": "public"
}, },
"license": "MIT", "license": "",
"bugs": { "bugs": {
"url": "https://github.com/CorpGlory/tsdb-kit/issues" "url": "https://github.com/CorpGlory/grafana-datasource-kit/issues"
}, },
"homepage": "https://github.com/CorpGlory/tsdb-kit", "homepage": "https://github.com/CorpGlory/grafana-datasource-kit",
"dependencies": { "dependencies": {
"axios": "^0.18.0", "axios": "^0.18.0",
"lodash": "^4.17.19",
"moment": "^2.22.2", "moment": "^2.22.2",
"url": "^0.11.0" "url": "^0.11.0"
}, },

1
src/metrics/metric.ts

@ -7,6 +7,7 @@ export declare type Datasource = {
epoch: string; epoch: string;
}; };
data?: any; data?: any;
datasourceId?: string;
}; };
export type MetricQuery = { export type MetricQuery = {

5
src/metrics/metrics_factory.ts

@ -4,7 +4,7 @@ import { AbstractMetric, Datasource, MetricId } from './metric';
import { PrometheusMetric } from './prometheus_metric'; import { PrometheusMetric } from './prometheus_metric';
import { PostgresMetric } from './postgres_metric'; import { PostgresMetric } from './postgres_metric';
import { ElasticsearchMetric } from './elasticsearch_metric'; import { ElasticsearchMetric } from './elasticsearch_metric';
import { MysqlMetric } from './mysql_metric';
export function metricFactory( export function metricFactory(
datasource: Datasource, datasource: Datasource,
@ -17,7 +17,8 @@ export function metricFactory(
'graphite': GraphiteMetric, 'graphite': GraphiteMetric,
'prometheus': PrometheusMetric, 'prometheus': PrometheusMetric,
'postgres': PostgresMetric, 'postgres': PostgresMetric,
'elasticsearch': ElasticsearchMetric 'elasticsearch': ElasticsearchMetric,
'mysql': MysqlMetric,
}; };
if(classMap[datasource.type] === undefined) { if(classMap[datasource.type] === undefined) {
console.error(`Datasources of type ${datasource.type} are not supported currently`); console.error(`Datasources of type ${datasource.type} are not supported currently`);

5
src/metrics/mysql_metric.ts

@ -0,0 +1,5 @@
import { SqlMetric } from './sql_metric';
export class MysqlMetric extends SqlMetric {
}

62
src/metrics/postgres_metric.ts

@ -1,63 +1,5 @@
import { AbstractMetric, Datasource, MetricId, MetricQuery, MetricResults } from './metric'; import { SqlMetric } from './sql_metric';
import { processSQLLimitOffset } from './utils';
import * as _ from 'lodash'; export class PostgresMetric extends SqlMetric {
export class PostgresMetric extends AbstractMetric {
private _targetName: string; //save first target name, while multi metric not implemented
constructor(datasource: Datasource, targets: any[], id?: MetricId) {
super(datasource, targets, id);
if(targets.length === 0) {
throw Error('got empty targets list');
}
this._targetName = targets[0].refId;
}
getQuery(from: number, to: number, limit: number, offset: number): MetricQuery {
let queries = this.datasource.data.queries;
_.forEach(queries, q => {
q.rawSql = processSQLLimitOffset(q.rawSql, limit, offset);
});
return {
url: this.datasource.url,
method: 'POST',
schema: {
data: {
from: String(from),
to: String(to),
queries: queries
}
}
};
}
getResults(res): MetricResults {
let emptyResult = {
columns: ['timestamp', 'target'],
values: []
};
if(res.data === undefined || res.data.results.length < 1) {
console.log('datasource return empty response, no data');
return emptyResult;
}
// TODO: support more than 1 metric (each res.data.results item is a metric)
let results = res.data.results[this._targetName];
if (results.series === undefined) {
return emptyResult;
}
let points = results.series[0].points;
points.forEach(p => p.reverse());
return {
columns: ['timestamp', results.series[0].name],
values: points
};
}
} }

68
src/metrics/sql_metric.ts

@ -0,0 +1,68 @@
import { AbstractMetric, Datasource, MetricId, MetricQuery, MetricResults } from './metric';
import { processSQLLimitOffset } from './utils';
import * as _ from 'lodash';
// for 26.09.2020 it works for all SQL datasources
export class SqlMetric extends AbstractMetric {
private _targetName: string; //save first target name, while multi metric not implemented
private url: string = 'api/tsdb/query';
constructor(datasource: Datasource, targets: any[], id?: MetricId) {
super(datasource, targets, id);
if(targets.length === 0) {
throw Error('got empty targets list');
}
this._targetName = targets[0].refId;
}
getQuery(from: number, to: number, limit: number, offset: number): MetricQuery {
let queries = this.targets;
_.forEach(queries, q => {
q.rawSql = processSQLLimitOffset(q.rawSql, limit, offset);
if (!q.datasourceId) {
q.datasourceId = this.datasource.datasourceId;
}
});
return {
url: this.url,
method: 'POST',
schema: {
data: {
from: String(from),
to: String(to),
queries: queries
}
}
};
}
getResults(res): MetricResults {
let emptyResult = {
columns: ['timestamp', 'target'],
values: []
};
if(res.data === undefined || res.data.results.length < 1) {
console.log('datasource return empty response, no data');
return emptyResult;
}
// TODO: support more than 1 metric (each res.data.results item is a metric)
let results = res.data.results[this._targetName];
if (!results.series) {
return emptyResult;
}
let points = results.series[0].points;
points.forEach(p => p.reverse());
return {
columns: ['timestamp', results.series[0].name],
values: points
};
}
}
Loading…
Cancel
Save