diff --git a/server/package.json b/server/package.json index 9e2a396..d7dba2e 100644 --- a/server/package.json +++ b/server/package.json @@ -38,7 +38,7 @@ "es6-promise": "^4.2.4", "event-stream": "3.3.4", "file-loader": "^1.1.11", - "grafana-datasource-kit": "0.1.10", + "grafana-datasource-kit": "0.1.11", "jest": "^23.1.1", "koa": "^2.0.46", "koa-bodyparser": "^4.2.0", diff --git a/server/src/controllers/analytics_controller.ts b/server/src/controllers/analytics_controller.ts index e3c1b26..7bb1254 100644 --- a/server/src/controllers/analytics_controller.ts +++ b/server/src/controllers/analytics_controller.ts @@ -9,7 +9,7 @@ import { AlertService } from '../services/alert_service'; import { HASTIC_API_KEY, GRAFANA_URL } from '../config'; import { DataPuller } from '../services/data_puller'; -import { queryByMetric } from 'grafana-datasource-kit'; +import { queryByMetric, ConnectionRefused } from 'grafana-datasource-kit'; import * as _ from 'lodash'; @@ -126,14 +126,24 @@ async function query(analyticUnit: AnalyticUnit.AnalyticUnit, detector: Analytic panelUrl = analyticUnit.panelUrl; } - const queryResult = await queryByMetric( - analyticUnit.metric, - panelUrl, - range.from, - range.to, - HASTIC_API_KEY - ); - const data = queryResult.values; + let data; + + try { + const queryResult = await queryByMetric( + analyticUnit.metric, + panelUrl, + range.from, + range.to, + HASTIC_API_KEY + ); + data = queryResult.values; + } catch(e) { + if(e instanceof ConnectionRefused) { + throw new Error(`Can't connect Grafana: ${e.message}, check GRAFANA_URL`); + } + throw e; + } + if(data.length === 0) { throw new Error('Empty data to detect on'); } diff --git a/server/src/services/data_puller.ts b/server/src/services/data_puller.ts index adb3ae9..89c210f 100644 --- a/server/src/services/data_puller.ts +++ b/server/src/services/data_puller.ts @@ -4,7 +4,7 @@ import * as AnalyticUnitCache from '../models/analytic_unit_cache_model'; import { AnalyticsService } from './analytics_service'; import { HASTIC_API_KEY, GRAFANA_URL } from '../config'; -import { queryByMetric } from 'grafana-datasource-kit'; +import { queryByMetric, ConnectionRefused } from 'grafana-datasource-kit'; import * as _ from 'lodash'; @@ -15,6 +15,35 @@ const PULL_PERIOD_MS = 5000; export class DataPuller { + private _availableReporter = (positiveMsg: string|null, negativeMsg: string|null) => { + let reported = false; + return available => { + if(available && reported) { + reported = false; + if(positiveMsg) { + console.log(positiveMsg); + } + } + + if(!available && !reported) { + reported = true; + if(negativeMsg) { + console.error(negativeMsg); + } + } + } + }; + + private _analyticReadyReporter = this._availableReporter( + 'data puller: analytic ready, start pushing', + 'data puller: analytic service not ready, return empty result' + ); + + private _grafanaConnectionRefusedReporter = this._availableReporter( + 'data puller: connected to Grafana', + `data puller: can't connect to Grafana. Check GRAFANA_URL` + ); + private _unitTimes: { [analyticUnitId: string]: number } = {}; constructor(private analyticsService: AnalyticsService) {}; @@ -126,8 +155,8 @@ export class DataPuller { AsyncIterableIterator { const getData = async () => { + this._analyticReadyReporter(this.analyticsService.ready); if(!this.analyticsService.ready) { - console.log(`data generator: analytic service not ready, return empty result while wait service`); return { columns: [], values: [] @@ -137,9 +166,21 @@ export class DataPuller { try { const time = this._unitTimes[analyticUnit.id] const now = Date.now(); - return await this.pullData(analyticUnit, time, now); + const res = await this.pullData(analyticUnit, time, now); + this._grafanaConnectionRefusedReporter(true); + return res; } catch(err) { - throw new Error(`error while pulling data: ${err.message}`); + + if(err instanceof ConnectionRefused) { + this._grafanaConnectionRefusedReporter(false); + } else { + console.error(`error while pulling data: ${err.message}`); + } + + return { + columns: [], + values: [] + }; } }