Comparing version 1.0.49 to 1.0.50
@@ -10,8 +10,8 @@ "use strict"; | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const alerts = yield (0, db_1.getAlerts)(); | ||
setPreviousSnapshotContextForAlerts(alerts, context); | ||
const distinctChannels = getChannelsAffected(context.alertableSnapshots(config)); | ||
const newAlerts = detectNewAlerts(alerts, distinctChannels); | ||
const existingAlerts = detectExistingAlerts(alerts, distinctChannels); | ||
const resolvedAlerts = detectResolvedAlerts(alerts, distinctChannels); | ||
const alertsFromLastRound = yield (0, db_1.getAlerts)(); | ||
setPreviousSnapshotContextForAlerts(alertsFromLastRound, context); | ||
const distinctChannels = getChannelsAffected(context.digestableSnapshots); | ||
const newAlerts = detectNewAlerts(alertsFromLastRound, distinctChannels); | ||
const existingAlerts = detectExistingAlerts(alertsFromLastRound, distinctChannels); | ||
const resolvedAlerts = detectResolvedAlerts(alertsFromLastRound, distinctChannels); | ||
yield triggerAlerts(config, context, newAlerts, existingAlerts, resolvedAlerts); | ||
@@ -33,2 +33,5 @@ yield (0, db_1.persistAlerts)([ | ||
const snapshots = context.getAlertableSnapshotsForChannel(config, channel); | ||
if (snapshots.length === 0) { | ||
return; | ||
} | ||
alert.start_date = earliestDateFor(snapshots); | ||
@@ -57,2 +60,8 @@ yield channel.sendNewAlert(snapshots, alert); | ||
const snapshots = context.getAlertableSnapshotsForChannel(config, channel); | ||
if (snapshots.length === 0) { | ||
// only way we can get here is if the channels alerts are muted | ||
alert.setMuted(); | ||
yield sendMutedAlert(config, alert); | ||
return; | ||
} | ||
if (channel.canSendAlert(alert)) { | ||
@@ -74,3 +83,6 @@ yield channel.sendOngoingAlert(snapshots, alert); | ||
alert.resolve(); | ||
if (alert.affected.size === 0) { | ||
if (alert.size === 0) { | ||
if (alert.isMuted) { | ||
yield sendMutedAlert(config, alert); | ||
} | ||
return; | ||
@@ -86,2 +98,11 @@ } | ||
} | ||
function sendMutedAlert(config, alert) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const channel = config.getChannelConfig(alert.channel); | ||
if (!channel) { | ||
return; | ||
} | ||
yield channel.sendMutedAlert(alert); | ||
}); | ||
} | ||
function triggerAlerts(config, context, newAlerts, existingAlerts, resolvedAlerts) { | ||
@@ -88,0 +109,0 @@ return tslib_1.__awaiter(this, void 0, void 0, function* () { |
@@ -24,2 +24,3 @@ import { Result } from "../models/result"; | ||
get snapshots(): Snapshot[]; | ||
get digestableSnapshots(): Snapshot[]; | ||
getAlertableSnapshotsForChannel(config: DigestConfiguration, channel: ChannelConfig): Snapshot[]; | ||
@@ -26,0 +27,0 @@ getLastSnapshotFor(uniqueId: string): Snapshot; |
@@ -96,5 +96,7 @@ "use strict"; | ||
} | ||
get digestableSnapshots() { | ||
return this._snapshots.filter(x => x.isDigestable); | ||
} | ||
getAlertableSnapshotsForChannel(config, channel) { | ||
return this.alertableSnapshots(config) | ||
.filter(x => x.isDigestable) | ||
.filter(x => { var _a, _b; return (_b = (_a = x.alert) === null || _a === void 0 ? void 0 : _a.channels) === null || _b === void 0 ? void 0 : _b.some(c => channel.isMatchFor(c)); }); | ||
@@ -166,4 +168,3 @@ } | ||
alertableSnapshots(config) { | ||
return this.snapshots | ||
.filter(x => x.isDigestable) | ||
return this.digestableSnapshots | ||
.filter(x => !config.muteWindows.some(m => m.isMuted(x.uniqueId))); | ||
@@ -170,0 +171,0 @@ } |
@@ -18,2 +18,3 @@ import { Snapshot } from "./snapshot"; | ||
private _previousSnapshots; | ||
private _wasMuted; | ||
constructor(data: any); | ||
@@ -26,2 +27,4 @@ static New(channel: string): AlertState; | ||
get isResolved(): boolean; | ||
get isMuted(): boolean; | ||
get size(): number; | ||
get affectedKeys(): string[]; | ||
@@ -36,2 +39,3 @@ resolve(): void; | ||
setPreviousSnapshots(previous: Snapshot[]): void; | ||
setMuted(): void; | ||
} |
@@ -47,3 +47,3 @@ "use strict"; | ||
get endTime() { | ||
return this.isResolved ? (0, utility_1.toLocalTimeString)(new Date()) : null; | ||
return this.isResolved || this.isMuted ? (0, utility_1.toLocalTimeString)(new Date()) : null; | ||
} | ||
@@ -60,2 +60,8 @@ get durationMinutes() { | ||
} | ||
get isMuted() { | ||
return this._wasMuted; | ||
} | ||
get size() { | ||
return this.affected.size; | ||
} | ||
get affectedKeys() { | ||
@@ -90,2 +96,5 @@ return Array.from(this.affected.keys()); | ||
muted.forEach(x => this.affected.delete(x)); | ||
const hadAlerts = keys.length > 0; | ||
const noAlertsNow = this.affected.size === 0; | ||
this._wasMuted = hadAlerts && noAlertsNow; | ||
} | ||
@@ -96,4 +105,7 @@ setPreviousSnapshots(previous) { | ||
} | ||
setMuted() { | ||
this._wasMuted = true; | ||
} | ||
} | ||
exports.AlertState = AlertState; | ||
//# sourceMappingURL=alerts.js.map |
@@ -25,2 +25,3 @@ import { Snapshot } from "../snapshot"; | ||
abstract sendResolvedAlert(alert: AlertState): Promise<void>; | ||
abstract sendMutedAlert(alert: AlertState): Promise<void>; | ||
abstract pingAboutOngoingAlert(snapshots: Snapshot[], alert: AlertState): Promise<void>; | ||
@@ -27,0 +28,0 @@ canSendAlert(alert: AlertState): boolean; |
@@ -9,3 +9,4 @@ import { Snapshot } from "../snapshot"; | ||
sendResolvedAlert(alert: AlertState): Promise<void>; | ||
sendMutedAlert(alert: AlertState): Promise<void>; | ||
pingAboutOngoingAlert(_snapshots: Snapshot[], _alert: AlertState): Promise<void>; | ||
} |
@@ -27,2 +27,7 @@ "use strict"; | ||
} | ||
sendMutedAlert(alert) { | ||
const message = `${this.prefix} 🔕 Alerts muted at ${alert.endTime}. ${this.postfix}`.trim(); | ||
console.log(message); | ||
return Promise.resolve(); | ||
} | ||
pingAboutOngoingAlert(_snapshots, _alert) { | ||
@@ -29,0 +34,0 @@ return tslib_1.__awaiter(this, void 0, void 0, function* () { |
@@ -17,3 +17,4 @@ import { Snapshot } from "../snapshot"; | ||
sendResolvedAlert(alert: AlertState): Promise<void>; | ||
sendMutedAlert(alert: AlertState): Promise<void>; | ||
postToSlack(message: string, state?: any, reply?: boolean): Promise<any>; | ||
} |
@@ -18,3 +18,3 @@ "use strict"; | ||
const msg = this._generateFull(snapshots, alert); | ||
if (msg.length < 3800) { | ||
if (msg.length <= 3000) { | ||
return msg; | ||
@@ -68,2 +68,5 @@ } | ||
} | ||
else if (alert.isMuted) { | ||
parts.push(`${this.prefix} 🔕 Outage Muted!`); | ||
} | ||
else { | ||
@@ -90,3 +93,3 @@ parts.push(`${this.prefix} 🔥 Ongoing Outage!`); | ||
if (resolved.length > 0) { | ||
parts.push(`*☑️ ${resolved.length} resolved ${(0, utility_1.pluraliseWithS)("check", resolved.length)}:*`); | ||
parts.push(`*☑️ ${resolved.length} resolved/muted ${(0, utility_1.pluraliseWithS)("check", resolved.length)}:*`); | ||
resolved.forEach(x => { | ||
@@ -134,2 +137,10 @@ const lastResult = x.lastSnapshot ? `(last result before resolution: _${x.lastSnapshot.result}_)` : ""; | ||
} | ||
sendMutedAlert(alert) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
yield Promise.all([ | ||
this.postToSlack(this.generateMessage([], alert), alert.state), | ||
this.postToSlack(`🔕 <!channel> Affected alerts were muted at ${alert.endTime}.\n_See above for more details about affected services._`, alert.state, true) | ||
]); | ||
}); | ||
} | ||
postToSlack(message, state, reply = false) { | ||
@@ -136,0 +147,0 @@ var _a, _b; |
@@ -14,4 +14,5 @@ import { Snapshot } from "../snapshot"; | ||
sendResolvedAlert(alert: AlertState): Promise<void>; | ||
sendMutedAlert(alert: AlertState): Promise<void>; | ||
pingAboutOngoingAlert(_snapshots: Snapshot[], _alert: AlertState): Promise<void>; | ||
private sendSMSToAllContacts; | ||
} |
@@ -33,2 +33,8 @@ "use strict"; | ||
} | ||
sendMutedAlert(alert) { | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const message = `${this.prefix} Current Alert MUTED at ${alert.endTime}.\n\n${this.postfix}`.trim(); | ||
yield this.sendSMSToAllContacts(message); | ||
}); | ||
} | ||
pingAboutOngoingAlert(_snapshots, _alert) { | ||
@@ -35,0 +41,0 @@ return tslib_1.__awaiter(this, void 0, void 0, function* () { |
@@ -73,8 +73,9 @@ "use strict"; | ||
return tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
const persistable = alerts.filter(x => x.size > 0 && !x.isMuted); | ||
yield _connection.transaction((trx) => tslib_1.__awaiter(this, void 0, void 0, function* () { | ||
yield trx("alerts").truncate(); | ||
if (alerts.length === 0) { | ||
if (persistable.length === 0) { | ||
return; | ||
} | ||
yield trx("alerts").insert(alerts.map(x => { | ||
yield trx("alerts").insert(persistable.map(x => { | ||
var _a, _b, _c, _d; | ||
@@ -81,0 +82,0 @@ return { |
{ | ||
"name": "barky", | ||
"version": "1.0.49", | ||
"version": "1.0.50", | ||
"description": "A simple cloud services watchdog with digest notification support & no external dependencies", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/Rohland/barky#readme", |
{ | ||
"name": "barky", | ||
"version": "1.0.49", | ||
"version": "1.0.50", | ||
"description": "A simple cloud services watchdog with digest notification support & no external dependencies", | ||
@@ -5,0 +5,0 @@ "homepage": "https://github.com/Rohland/barky#readme", |
@@ -435,3 +435,3 @@ # Barky - Cloud Watchdog | ||
The value is composed as follows: `type|label|identifier`. For example: `web|web-performance|www.codeo.co.za`. The regular expression for match | ||
will thus be compared against this string value (case insensitive). | ||
will thus be compared against this string value (case-insensitive). | ||
@@ -438,0 +438,0 @@ ### SMS |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
329239
4439