Browse Source

Notifications timezone #649 (#781)

* test offset for units

* add timeZone

* remove old code

* remove consolelogs

* fix

* fix2

* add error

* add redexp

* for patterns

* for anomaly

* dry

* types

* fix

* fix

* funcs to utils

* timezone -> time
pull/1/head
Alexandr Velikiy 5 years ago committed by Alexey Velikiy
parent
commit
9bcb639676
  1. 14
      server/src/config.ts
  2. 2
      server/src/controllers/analytics_controller.ts
  3. 16
      server/src/services/alert_service.ts
  4. 2
      server/src/services/notification_service.ts
  5. 26
      server/src/utils/time.ts

14
server/src/config.ts

@ -1,10 +1,11 @@
import { getJsonDataSync } from './services/json_service';
import { normalizeUrl } from './utils/url';
import { parseTimeZone } from './utils/time';
import * as path from 'path';
import * as fs from 'fs';
import * as os from 'os';
import * as moment from 'moment';
let configFile = path.join(__dirname, '../../config.json');
let configExists = fs.existsSync(configFile);
@ -50,6 +51,7 @@ export const HASTIC_WEBHOOK_URL = getConfigField('HASTIC_WEBHOOK_URL', null);
export const HASTIC_WEBHOOK_TYPE = getConfigField('HASTIC_WEBHOOK_TYPE', 'application/json');
export const HASTIC_WEBHOOK_SECRET = getConfigField('HASTIC_WEBHOOK_SECRET', null);
export const HASTIC_WEBHOOK_IMAGE_ENABLED = getConfigField('HASTIC_WEBHOOK_IMAGE', false);
export const TIMEZONE_UTC_OFFSET = getTimeZoneOffset();
export const ANLYTICS_PING_INTERVAL = 500; // ms
export const PACKAGE_VERSION = getPackageVersion();
@ -145,3 +147,13 @@ function getDbConfig(connectionStr: string): DBConfig {
};
return config;
}
function getTimeZoneOffset(): number {
let configTimeZone = getConfigField('TIMEZONE_UTC_OFFSET', null);
if(configTimeZone !== null) {
return parseTimeZone(configTimeZone);
} else {
const serverUtcOffset = moment().utcOffset();
return serverUtcOffset;
}
}

2
server/src/controllers/analytics_controller.ts

@ -89,7 +89,7 @@ async function onPushDetect(detectionResult: DetectionResult): Promise<void> {
const segments = await onDetect(detectionResult);
if(!_.isEmpty(segments) && analyticUnit.alert) {
try {
const segment = await Segment.findOne(_.last(segments))
const segment = await Segment.findOne(_.last(segments));
alertService.receiveAlert(analyticUnit, segment);
} catch(err) {
console.error(`error while sending webhook: ${err.message}`);

16
server/src/services/alert_service.ts

@ -2,6 +2,7 @@ import { sendNotification, MetaInfo, AnalyticMeta, WebhookType, Notification } f
import * as AnalyticUnit from '../models/analytic_units';
import { Segment } from '../models/segment_model';
import { availableReporter } from '../utils/reporter';
import { toTimeZone } from '../utils/time';
import { ORG_ID, HASTIC_API_KEY, HASTIC_WEBHOOK_IMAGE_ENABLED } from '../config';
import axios from 'axios';
@ -77,12 +78,14 @@ export class Alert {
}
protected makeMessage(meta: AnalyticMeta): string {
const localTimeFrom = toTimeZone(meta.from);
const localTimeTo = toTimeZone(meta.to);
return [
`[${meta.analyticUnitType.toUpperCase()} ALERTING] ${meta.analyticUnitName}`,
`URL: ${meta.grafanaUrl}`,
``,
`From: ${new Date(meta.from)}`,
`To: ${new Date(meta.to)}`,
`From: ${localTimeFrom}`,
`To: ${localTimeTo}`,
`ID: ${meta.analyticUnitId}`,
`Message: ${meta.message}`
].join('\n');
@ -103,12 +106,14 @@ class PatternAlert extends Alert {
}
protected makeMessage(meta: AnalyticMeta): string {
const localTimeFrom = toTimeZone(meta.from);
const localTimeTo = toTimeZone(meta.to);
return [
`[PATTERN DETECTED] ${meta.analyticUnitName}`,
`URL: ${meta.grafanaUrl}`,
``,
`From: ${new Date(meta.from)}`,
`To: ${new Date(meta.to)}`,
`From: ${localTimeFrom}`,
`To: ${localTimeTo}`,
`ID: ${meta.analyticUnitId}`
].join('\n');
}
@ -141,11 +146,12 @@ class ThresholdAlert extends Alert {
}
protected makeMessage(meta: AnalyticMeta): string {
const localTimeFrom = toTimeZone(meta.from);
let message = [
`[THRESHOLD ALERTING] ${meta.analyticUnitName}`,
`URL: ${meta.grafanaUrl}`,
``,
`Starts at: ${new Date(meta.from)}`,
`Starts at: ${localTimeFrom}`,
`ID: ${meta.analyticUnitId}`
].join('\n');

2
server/src/services/notification_service.ts

@ -1,5 +1,5 @@
import * as AnalyticUnit from '../models/analytic_units';
import { HASTIC_WEBHOOK_URL, HASTIC_WEBHOOK_TYPE, HASTIC_WEBHOOK_SECRET, HASTIC_INSTANCE_NAME } from '../config';
import { HASTIC_WEBHOOK_URL, HASTIC_WEBHOOK_TYPE, HASTIC_INSTANCE_NAME } from '../config';
import axios from 'axios';
import * as querystring from 'querystring';

26
server/src/utils/time.ts

@ -0,0 +1,26 @@
import { TIMEZONE_UTC_OFFSET } from '../config';
import * as _ from 'lodash';
import * as moment from 'moment';
const MINUTES_IN_HOUR = 60;
export function parseTimeZone(timeZone: string): number {
const re = /\b-?\d{1,2}?:\d{2}\b/;
const correctFormat = re.test(timeZone);
if(!correctFormat) {
throw new Error(`Wrong timeZone format in config - "TIMEZONE_UTC_OFFSET": ${timeZone}`);
}
const time = _.split(timeZone, ':');
let minutesOffset = Math.abs(Number(time[0])) * MINUTES_IN_HOUR + Number(time[1]);
if(timeZone.indexOf('-') !== -1) {
minutesOffset = -1 * minutesOffset;
}
return minutesOffset;
}
export function toTimeZone(time: moment.MomentInput): string {
const utcTime = moment(time).utc();
const timeWithOffset = utcTime.utcOffset(TIMEZONE_UTC_OFFSET);
return timeWithOffset.format('ddd MMM DD YYYY HH:mm:ss');
}
Loading…
Cancel
Save