6 changed files with 95 additions and 93 deletions
@ -1,6 +1,5 @@ |
|||||||
node_modules/ |
node_modules/ |
||||||
dist/ |
dist/ |
||||||
exported/*.csv |
exported/ |
||||||
exported/*.json |
|
||||||
api-keys.json |
api-keys.json |
||||||
package-lock.json |
package-lock.json |
||||||
|
@ -0,0 +1,70 @@ |
|||||||
|
import { GrafanaMetric } from './grafana_metric_model'; |
||||||
|
import { getApiKey } from '../config'; |
||||||
|
import { URL } from 'url'; |
||||||
|
import axios from 'axios'; |
||||||
|
|
||||||
|
|
||||||
|
const CHUNK_SIZE = 50000; |
||||||
|
|
||||||
|
|
||||||
|
/** |
||||||
|
* @param metric to query to Grafana |
||||||
|
* @returns [time, value][] array |
||||||
|
*/ |
||||||
|
export async function queryByMetric( |
||||||
|
metric: GrafanaMetric, panelUrl: string, from: number, to: number |
||||||
|
) { |
||||||
|
|
||||||
|
let datasource = metric.datasource; |
||||||
|
|
||||||
|
let origin = new URL(panelUrl).origin; |
||||||
|
let url = `${origin}/${datasource.url}`; |
||||||
|
|
||||||
|
let params = datasource.params |
||||||
|
let data = { |
||||||
|
values: [], |
||||||
|
columns: [] |
||||||
|
}; |
||||||
|
|
||||||
|
let chunkParams = Object.assign({}, params); |
||||||
|
while(true) { |
||||||
|
chunkParams.q = metric.metricQuery.getQuery(from, to, CHUNK_SIZE, data.values.length); |
||||||
|
var chunk = await queryGrafana(url, chunkParams); |
||||||
|
let values = chunk.values; |
||||||
|
data.values = data.values.concat(values); |
||||||
|
data.columns = chunk.columns; |
||||||
|
|
||||||
|
if(values.length < CHUNK_SIZE) { |
||||||
|
// because if we get less that we could, then there is nothing more
|
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
return data; |
||||||
|
} |
||||||
|
|
||||||
|
async function queryGrafana(url: string, params: any) { |
||||||
|
let origin = new URL(url).origin; |
||||||
|
let headers = { Authorization: `Bearer ${getApiKey(origin)}` }; |
||||||
|
|
||||||
|
try { |
||||||
|
var res = await axios.get(url, { params, headers }); |
||||||
|
} catch (e) { |
||||||
|
if(e.response.status === 401) { |
||||||
|
throw new Error('Unauthorized. Check the $HASTIC_API_KEY.'); |
||||||
|
} |
||||||
|
throw new Error(e.message); |
||||||
|
} |
||||||
|
|
||||||
|
if (res.data.results === undefined) { |
||||||
|
throw new Error('results field is undefined in response.'); |
||||||
|
} |
||||||
|
|
||||||
|
// TODO: support more than 1 metric (each res.data.results item is a metric)
|
||||||
|
let results = res.data.results[0]; |
||||||
|
if (results.series === undefined) { |
||||||
|
return []; |
||||||
|
} |
||||||
|
|
||||||
|
return results.series[0]; |
||||||
|
} |
@ -1,66 +0,0 @@ |
|||||||
import { getApiKey } from './config'; |
|
||||||
|
|
||||||
import axios from 'axios'; |
|
||||||
|
|
||||||
|
|
||||||
export class GrafanaAPI { |
|
||||||
private apiKey; |
|
||||||
constructor(private grafanaUrl) { |
|
||||||
getApiKey(grafanaUrl) |
|
||||||
.then(key => { |
|
||||||
this.apiKey = key; |
|
||||||
console.log(this.apiKey); |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
private get _headers() { |
|
||||||
return { |
|
||||||
'Authorization': `Bearer ${this.apiKey}`, |
|
||||||
'Accept': 'application/json', |
|
||||||
'Content-Type': 'application/json' |
|
||||||
}; |
|
||||||
} |
|
||||||
|
|
||||||
private async _getDatasourceByName(name) { |
|
||||||
return fetch(`${this.grafanaUrl}/api/datasources/name/${name}`, { |
|
||||||
method: 'GET', |
|
||||||
headers: this._headers |
|
||||||
}) |
|
||||||
.then(data => data.json()); |
|
||||||
} |
|
||||||
|
|
||||||
public async queryDatasource(datasourceName, measurement, query) { |
|
||||||
let datasource = await this._getDatasourceByName(datasourceName); |
|
||||||
|
|
||||||
return this._queryGrafana(`${this.grafanaUrl}/api/datasources/proxy/${datasource.id}/query`, { |
|
||||||
q: encodeURIComponent(query), |
|
||||||
db: datasource.database, |
|
||||||
epoch: 'ms' |
|
||||||
}); |
|
||||||
} |
|
||||||
|
|
||||||
private async _queryGrafana(url: string, params: any) { |
|
||||||
try { |
|
||||||
var res = await axios.get(url, { params, headers: this._headers }); |
|
||||||
} catch (e) { |
|
||||||
if(e.response.status === 401) { |
|
||||||
throw new Error('Unauthorized. Check the $HASTIC_API_KEY.'); |
|
||||||
} |
|
||||||
throw new Error(e.message); |
|
||||||
} |
|
||||||
|
|
||||||
if (res.data.results === undefined) { |
|
||||||
throw new Error('results field is undefined in response.'); |
|
||||||
} |
|
||||||
|
|
||||||
// TODO: support more than 1 metric (each res.data.results item is a metric)
|
|
||||||
let results = res.data.results[0]; |
|
||||||
if (results.series === undefined) { |
|
||||||
return []; |
|
||||||
} |
|
||||||
|
|
||||||
return results.series[0].values as [number, number][]; |
|
||||||
} |
|
||||||
|
|
||||||
} |
|
||||||
|
|
Loading…
Reference in new issue