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
.vscode/
lib/
package-lock.json

2
LICENSE

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

10
README.md

@ -1,11 +1,11 @@
# 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.
You can send your datasource metric from Grafana to compile it on Node.js and query your datasource via Grafana API in background.
Node.js library and utilities for running Grafana datasources on backend.
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
@ -15,7 +15,7 @@ User gets unified interface to all datasources. Library gives single output form
* PostgreSQL / TimescaleDB
* 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
* [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",
"version": "1.0.1",
"name": "grafana-datasource-kit",
"version": "0.1.17",
"description": "",
"scripts": {
"build": "tsc",
@ -9,20 +9,19 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/CorpGlory/tsdb-kit.git"
"url": "git+https://github.com/CorpGlory/grafana-datasource-kit.git"
},
"author": "CorpGlory Inc.",
"publishConfig": {
"access": "public"
},
"license": "MIT",
"license": "",
"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": {
"axios": "^0.18.0",
"lodash": "^4.17.19",
"moment": "^2.22.2",
"url": "^0.11.0"
},

1
src/metrics/metric.ts

@ -7,6 +7,7 @@ export declare type Datasource = {
epoch: string;
};
data?: any;
datasourceId?: string;
};
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 { PostgresMetric } from './postgres_metric';
import { ElasticsearchMetric } from './elasticsearch_metric';
import { MysqlMetric } from './mysql_metric';
export function metricFactory(
datasource: Datasource,
@ -17,7 +17,8 @@ export function metricFactory(
'graphite': GraphiteMetric,
'prometheus': PrometheusMetric,
'postgres': PostgresMetric,
'elasticsearch': ElasticsearchMetric
'elasticsearch': ElasticsearchMetric,
'mysql': MysqlMetric,
};
if(classMap[datasource.type] === undefined) {
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 { processSQLLimitOffset } from './utils';
import { SqlMetric } from './sql_metric';
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