/
health-cron.js
72 lines (68 loc) · 3.15 KB
/
health-cron.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
import { Meteor } from 'meteor/meteor';
import { SyncedCron } from 'meteor/littledata:synced-cron';
import _ from 'lodash';
import { Healths } from '../../api/health/HealthsCollection';
import { Notifications } from '../../api/notifications/NotificationsCollection';
import { UserProfiles } from '../../api/users/UserProfilesCollection';
/**
* serviceTracker sets a service name to true if the given service is down
* therefore, multiple notifications docs won't be created if a service remains down
* service name is set back to false if the given service is back up
*/
const serviceTracker = { mauka: false, makai: false, mongo: false, health: false };
/**
* Creates a Notification document for everyone subscribed to the 'system service down' notification
* when a service goes down
* In order to not spam the user, the name of the service that is down
* is set to true, and notifications for that service cannot be created again until
* the service is back up
*/
function serviceHealthStatus(healths, service, usersInterested) {
const serviceName = service.toLowerCase();
const healthDoc = _.find(healths, health => health.service === service);
if (healthDoc && (healthDoc.status === 'DOWN') && (serviceTracker[serviceName] === false)) {
_.forEach(usersInterested, user => {
const username = user.username;
const type = 'system service down';
const dataSummary = { service: serviceName, summary: `${service} service went down` };
Notifications.define({ username, type, data: dataSummary });
serviceTracker[serviceName] = true;
});
}
if (healthDoc && healthDoc.status !== ('DOWN' || undefined) && serviceTracker[serviceName] === true) {
serviceTracker[serviceName] = false;
}
}
function healthCron() {
// Set up cron job unless in testing mode or it's explicitly disabled in settings file.
const testMode = Meteor.isTest || Meteor.isAppTest;
const disabled = Meteor.settings.healthCron && !Meteor.settings.healthCron.enabled;
if (disabled) {
console.log('Health cron job disabled in view.config.json.');
}
if (!testMode && !disabled) {
// Default the update interval to 10 seconds if not supplied in configuration file.
const updateIntervalSeconds = Meteor.settings.systemStats ? Meteor.settings.systemStats.updateIntervalSeconds : 10;
const services = ['MAUKA', 'MAKAI', 'MONGO', 'HEALTH'];
SyncedCron.add({
name: 'Check Health collection for services that are down',
schedule(parser) {
return parser.text(`every ${updateIntervalSeconds} seconds`); // Seconds must be between 0-59.
},
job() {
const usersInterested = UserProfiles.find({ 'notification_preferences.notification_types':
'system service down' }).fetch();
const healths = Healths.find(
{ timestamp: { $gt: new Date(Date.now() - (1000 * 62)) } },
{ sort: { timestamp: -1 } },
).fetch();
_.map(services, service => serviceHealthStatus(healths, service, usersInterested));
},
});
console.log(`Starting cron job to update health status every ${updateIntervalSeconds} seconds.`);
SyncedCron.start();
}
}
Meteor.startup(() => {
healthCron();
});