Browse Source

Merge pull request 'CLI-arguments && docs && Prometheus auth' (#8) from cli-arguments into master

Reviewed-on: #8
pull/12/head
rozetko 2 years ago
parent
commit
f6679a98be
  1. 9
      .npmignore
  2. 32
      README.md
  3. 6
      package.json
  4. 13
      spec/prometheus.jest.ts
  5. 6
      src/connectors/index.ts
  6. 3
      src/connectors/prometheus.ts
  7. 3
      src/services/query_service/direct.ts
  8. 35
      src/tsdb-kit/index.ts
  9. 6
      webpack.config.js
  10. 5
      yarn.lock

9
.npmignore

@ -2,7 +2,8 @@ src
spec spec
.travis.yml .travis.yml
jest.config.js jest.config.js
tsconfig.lib.json lib.tsconfig.json
tsconfig.bin.json bin.tsconfig.json
tsconfig.jest.json webpack.config.js
yarn.lock
.vscode

32
README.md

@ -1,21 +1,43 @@
# tsdb-kit # tsdb-kit
[![Build Status](https://travis-ci.org/CorpGlory/tsdb-kit.svg?branch=master)](https://travis-ci.org/CorpGlory/tsdb-kit) TSDB-kit is a node.js library and CLI-tool for querying timeseries-datasources.
Node.js library and utilities for running Grafana datasources on backend. ## Features
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 a unified interface to all datasources. Library gives single output format: fields order, time units, etc - can query datasources directly or using Grafana as proxy
- can be used as a lib from your node.js-code or as a CLI-tool
- user gets a unified interface to all datasources. Library gives single output format: fields order, time units, etc.
## Supported datasources ## Supported datasources
### Direct
* Prometheus
### Grafana
* Influxdb * Influxdb
* Graphite * Graphite
* Prometheus * Prometheus
* PostgreSQL / TimescaleDB / MySQL * PostgreSQL / TimescaleDB / MySQL
* ElasticSearch * ElasticSearch
Please write us at ping@corpglory.com if you want your datasource to be supported: Please write us at ping@corpglory.com if you want your datasource to be supported
## Usage
### Lib (TODO)
### CLI
For now, CLI supports only direct Prometheus queries
For example:
`npx @corpglory/tsdb-kit -U http://localhost:9090 -q '100-(avg by (instance) (irate(node_cpu_seconds_total{mode="idle"}[5m])) * 100)' -u my_user -p my_password`
## Development (TODO)
## 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)

6
package.json

@ -1,12 +1,13 @@
{ {
"name": "@corpglory/tsdb-kit", "name": "@corpglory/tsdb-kit",
"version": "1.1.1", "version": "2.0.0",
"description": "", "description": "",
"scripts": { "scripts": {
"build": "yarn build:lib && yarn build:bin", "build": "yarn build:lib && yarn build:bin",
"build:lib": "tsc --p lib.tsconfig.json", "build:lib": "tsc --p lib.tsconfig.json",
"build:bin": "webpack --config webpack.config.js", "build:bin": "webpack --config webpack.config.js",
"dev": "tsc -w", "dev:lib": "tsc --p lib.tsconfig.json -w",
"dev:bin": "webpack --watch --config webpack.config.js",
"test": "jest" "test": "jest"
}, },
"repository": { "repository": {
@ -32,6 +33,7 @@
"devDependencies": { "devDependencies": {
"@types/jest": "^26.0.15", "@types/jest": "^26.0.15",
"@types/lodash": "^4.14.165", "@types/lodash": "^4.14.165",
"argparse": "^2.0.1",
"jest": "^26.6.3", "jest": "^26.6.3",
"ts-jest": "^26.4.4", "ts-jest": "^26.4.4",
"ts-loader": "^9.3.1", "ts-loader": "^9.3.1",

13
spec/prometheus.jest.ts

@ -7,7 +7,11 @@ import 'jest';
describe('Test Prometheus time range processing', function() { describe('Test Prometheus time range processing', function() {
let datasource = { let datasource = {
type: DatasourceType.PROMETHEUS, type: DatasourceType.PROMETHEUS,
url: 'api/datasources/proxy/4/api/v1/query_range?query=node_disk_io_time_ms&start=1543411320&end=1543432950&step=30' url: 'api/datasources/proxy/4/api/v1/query_range?query=node_disk_io_time_ms&start=1543411320&end=1543432950&step=30',
auth: {
username: 'my_user',
password: 'my_password',
}
} }
let targets = []; let targets = [];
let prometheus = new PrometheusConnector(datasource, targets); let prometheus = new PrometheusConnector(datasource, targets);
@ -19,4 +23,11 @@ describe('Test Prometheus time range processing', function() {
expect(query.url.indexOf(`start=${Math.floor(from / 1000)}`) !== -1).toBeTruthy(); expect(query.url.indexOf(`start=${Math.floor(from / 1000)}`) !== -1).toBeTruthy();
expect(query.url.indexOf(`end=${Math.floor(to / 1000)}`) !== -1).toBeTruthy(); expect(query.url.indexOf(`end=${Math.floor(to / 1000)}`) !== -1).toBeTruthy();
}); });
it('check that username/password present in query', function() {
let query = prometheus.getQuery(0, 0, 1000, 0);
expect(query.auth?.username).toBe('my_user');
expect(query.auth?.password).toBe('my_password');
})
}); });

6
src/connectors/index.ts

@ -12,6 +12,7 @@ export enum DatasourceType {
MYSQL = 'mysql', MYSQL = 'mysql',
} }
// TODO: Datasource: type -> class
export declare type Datasource = { export declare type Datasource = {
url: string; url: string;
type: DatasourceType; type: DatasourceType;
@ -22,6 +23,7 @@ export declare type Datasource = {
}; };
data?: any; data?: any;
datasourceId?: string; datasourceId?: string;
auth?: any;
}; };
export type DatasourceQuery = { export type DatasourceQuery = {
@ -29,6 +31,10 @@ export type DatasourceQuery = {
method: string; method: string;
schema: any; schema: any;
headers?: any; headers?: any;
auth?: {
username: string;
password: string;
};
} }
export type DataTable = { export type DataTable = {

3
src/connectors/prometheus.ts

@ -21,7 +21,8 @@ export class PrometheusConnector extends DatasourceConnector {
method: 'GET', method: 'GET',
schema: { schema: {
params: this.datasource.params params: this.datasource.params
} },
auth: this.datasource.auth,
} }
} }

3
src/services/query_service/direct.ts

@ -14,8 +14,7 @@ export class DirectQueryService extends QueryService {
async query(query: DatasourceQuery): Promise<AxiosResponse<any>> { async query(query: DatasourceQuery): Promise<AxiosResponse<any>> {
// TODO: support auth // TODO: support auth
let axiosQuery = { let axiosQuery = {
url: query.url, ...query,
method: query.method,
}; };
_.defaults(axiosQuery, query.schema); _.defaults(axiosQuery, query.schema);

35
src/tsdb-kit/index.ts

@ -2,20 +2,41 @@ import { queryByConfig, QueryConfig } from '..';
import { DatasourceType, QueryType } from '../connectors'; import { DatasourceType, QueryType } from '../connectors';
const { version } = require('../../package.json')
import { ArgumentParser } from 'argparse';
import * as _ from 'lodash'; import * as _ from 'lodash';
const parser = new ArgumentParser();
// TODO: these `const`s should be CLI arguments parser.add_argument('-v', '--version', { action: 'version', version });
const PROMETHEUS_URL = 'http://localhost:9090'; parser.add_argument('-U', '--url', { help: 'Datasource URL', required: true });
const QUERY = '100-(avg by (instance) (irate(node_cpu_seconds_total{job="nvicta-ai-node-exporter",mode="idle"}[5m])) * 100)'; parser.add_argument('-q', '--query', { help: 'Query Template', required: true });
const FROM = 1660670020000; // ms parser.add_argument('-f', '--from', { help: 'From timestamp (ms), e.g. 1660670020000. If not specified, `now-5m` is used' });
const TO = 1660670026000; // ms parser.add_argument('-t', '--to', { help: 'To timestamp (ms), e.g. 1660670026000. If not specified, `now` is used' });
parser.add_argument('-u', '--username', { help: 'Basic Auth Username' });
parser.add_argument('-p', '--password', { help: 'Basic Auth Password' });
const args = parser.parse_args();
const timeNowInMs = new Date().getTime();
const PROMETHEUS_URL = args.url;
const QUERY = args.query;
const FROM = args.from || timeNowInMs - 5 * 60 * 1000;
const TO = args.to || timeNowInMs;
const USERNAME = args.username;
const PASSWORD = args.password;
let auth;
if(USERNAME && PASSWORD) {
auth = { username: USERNAME, password: PASSWORD };
}
const datasource = { const datasource = {
type: DatasourceType.PROMETHEUS, type: DatasourceType.PROMETHEUS,
// TODO: remove PROMETHEUS_URL from here // TODO: remove PROMETHEUS_URL from here
url: `${PROMETHEUS_URL}/api/v1/query_range?query=${QUERY}&start=1543411320&end=1543432950&step=30` url: `${PROMETHEUS_URL}/api/v1/query_range?query=${QUERY}&start=1543411320&end=1543432950&step=30`,
} auth,
};
const targets = []; const targets = [];
const queryConfig = new QueryConfig(QueryType.DIRECT, datasource, targets); const queryConfig = new QueryConfig(QueryType.DIRECT, datasource, targets);
queryByConfig(queryConfig, PROMETHEUS_URL, FROM, TO) queryByConfig(queryConfig, PROMETHEUS_URL, FROM, TO)

6
webpack.config.js

@ -1,3 +1,4 @@
const webpack = require('webpack');
const path = require('path'); const path = require('path');
@ -12,13 +13,16 @@ module.exports = {
path: path.resolve(__dirname, './bin'), path: path.resolve(__dirname, './bin'),
filename: 'tsdb-kit.js' filename: 'tsdb-kit.js'
}, },
plugins: [
new webpack.BannerPlugin({ banner: "#!/usr/bin/env node", raw: true }),
],
resolve: { resolve: {
extensions: ['.ts', '.js'], extensions: ['.ts', '.js'],
}, },
module: { module: {
rules: [ rules: [
{ {
test: /.ts?$/, test: /.ts$/,
loader: 'ts-loader', loader: 'ts-loader',
options: { options: {
configFile: 'bin.tsconfig.json' configFile: 'bin.tsconfig.json'

5
yarn.lock

@ -905,6 +905,11 @@ argparse@^1.0.7:
dependencies: dependencies:
sprintf-js "~1.0.2" sprintf-js "~1.0.2"
argparse@^2.0.1:
version "2.0.1"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-2.0.1.tgz#246f50f3ca78a3240f6c997e8a9bd1eac49e4b38"
integrity sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==
arr-diff@^4.0.0: arr-diff@^4.0.0:
version "4.0.0" version "4.0.0"
resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520"

Loading…
Cancel
Save