Browse Source

convert timestamps to dates

pull/6/head
rozetko 1 year ago
parent
commit
66b8471848
  1. 1
      package.json
  2. 8
      src/models/target.ts
  3. 3
      src/routes/tasks.ts
  4. 49
      src/services/exporter.ts
  5. 3
      src/types.ts
  6. 6
      src/utils.ts
  7. 9
      yarn.lock

1
package.json

@ -17,6 +17,7 @@
"fast-csv": "^2.5.0",
"lodash": "^4.17.21",
"moment": "^2.29.4",
"moment-timezone": "^0.5.40",
"nodemon": "^2.0.20",
"ts-loader": "^9.4.2",
"typescript": "^4.9.4",

8
src/models/target.ts

@ -1,8 +0,0 @@
import { DataSourceSettings, PanelModel } from '../types';
export class Target {
constructor(
public panel: PanelModel,
public datasource: DataSourceSettings,
) {}
}

3
src/routes/tasks.ts

@ -14,6 +14,7 @@ type TRequest = {
body: {
task: ExportTask,
url: string,
timeZoneName: string,
},
};
@ -67,7 +68,7 @@ async function addTask(req: TRequest, res) {
}
const exporter = exporterFactory.getExporter();
exporter.export(task, datasourceUrl);
exporter.export(task, datasourceUrl, body.timeZoneName);
res.status(200).send(`Export process started`);
}

49
src/services/exporter.ts

@ -1,7 +1,6 @@
import { Target } from '../models/target';
import { URL } from 'url';
import { apiKeys } from '../config';
import { promisify } from '../utils';
import { promisify, toIsoString } from '../utils';
import { DashboardQuery, ExportProgress, ExportStatus, ExportTask } from '../types';
import { QueryConfig, queryByConfig } from '@corpglory/tsdb-kit';
@ -27,7 +26,7 @@ const DEFAULT_PROGRESS = {
export class Exporter {
private _task: ExportTask;
public async export(task: ExportTask, datasourceUrl: string) {
public async export(task: ExportTask, datasourceUrl: string, timeZoneName: string) {
try {
this._task = _.cloneDeep(task);
this._task.id = uuidv4();
@ -36,22 +35,17 @@ export class Exporter {
this._validateQueries(task.queries);
this._validateDatasourceUrl(datasourceUrl);
const targets = task.queries.map((query: DashboardQuery) => new Target(
query.panel,
query.datasource,
));
await this._updateProgress();
const queryConfigs = targets.map(
target =>
const queryConfigs = task.queries.map(
query =>
new QueryConfig(
QueryType.GRAFANA,
{
...target.datasource,
url: datasourceUrl
...query.datasource,
url: datasourceUrl,
},
target.panel.targets
[query.target]
)
);
@ -76,12 +70,31 @@ export class Exporter {
const datasourceMetrics = await queryByConfig(queryConfig, datasourceUrl, from, to, apiKey);
columns = datasourceMetrics.columns;
values = datasourceMetrics.values;
if(_.isEmpty(columns)) {
columns = datasourceMetrics.columns;
} else {
columns = _.concat(columns, datasourceMetrics.columns.slice(1));
}
if(_.isEmpty(values)) {
values = datasourceMetrics.values;
} else {
if(values.length !== datasourceMetrics.values.length) {
throw new Error(`All queries should return rows of the same lengths`);
}
for(const rowIdx in values) {
if(datasourceMetrics.values[rowIdx][0] !== values[rowIdx][0]) {
throw new Error('Queries should return the same timestamps');
}
values[rowIdx] = _.concat(values[rowIdx], datasourceMetrics.values[rowIdx].slice(1));
}
}
}
values = values.map((row: number[]) => [toIsoString(row[0], timeZoneName), ...row.slice(1)]);
if(columns.length > 0) {
this._writeCsv(stream, { columns, values, });
this._writeCsv(stream, { columns, values });
}
await this._updateProgress({ status: ExportStatus.EXPORTING, progress: (day + 1) / days });
@ -137,8 +150,8 @@ export class Exporter {
if(_.isEmpty(query.datasource)) {
throw new Error('all queries should have a `datasource` field');
}
if(_.isEmpty(query.panel.targets)) {
throw new Error('all queries should have a `panel` field with non-empty `targets` field');
if(_.isEmpty(query.target)) {
throw new Error('all queries should have a `target` field');
}
}
}

3
src/types.ts

@ -105,8 +105,9 @@ export type ExportTask = {
id?: string;
};
export type DashboardQuery = DataQuery & {
export type DashboardQuery = {
selected: boolean;
target: DataQuery;
panel: PanelModel;
datasource: DataSourceSettings;
};

6
src/utils.ts

@ -1,3 +1,5 @@
import * as moment from 'moment-timezone';
export async function promisify(method: (...params: any[]) => Promise<any> | void, ...params: any[]) {
return new Promise((resolve, reject) => {
method(...params, (err, result) => {
@ -9,3 +11,7 @@ export async function promisify(method: (...params: any[]) => Promise<any> | voi
})
});
}
export function toIsoString(msTimestamp: number, timeZone: string): string {
return moment.tz(msTimestamp, timeZone).format('YYYY-MM-DD HH:mm:ssZ').replace(/:00$/, '');
}

9
yarn.lock

@ -1046,7 +1046,14 @@ minimatch@^3.1.2:
dependencies:
brace-expansion "^1.1.7"
moment@^2.22.2, moment@^2.29.4:
moment-timezone@^0.5.40:
version "0.5.40"
resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.40.tgz#c148f5149fd91dd3e29bf481abc8830ecba16b89"
integrity sha512-tWfmNkRYmBkPJz5mr9GVDn9vRlVZOTe6yqY92rFxiOdWXbjaR0+9LwQnZGGuNR63X456NqmEkbskte8tWL5ePg==
dependencies:
moment ">= 2.9.0"
"moment@>= 2.9.0", moment@^2.22.2, moment@^2.29.4:
version "2.29.4"
resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.4.tgz#3dbe052889fe7c1b2ed966fcb3a77328964ef108"
integrity sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==

Loading…
Cancel
Save