'use strict';
const job = require('../parts/jobs/job.js'),
plugins = require('../../plugins/pluginManager.js'),
tracker = require('../parts/mgmt/tracker.js');
/** Class for the job of pinging servers **/
class PingJob extends job.Job {
/**
* Run the ping job
* @param {Db} db connection
* @param {done} done callback
*/
run(db, done) {
plugins.loadConfigs(db, async function() {
const offlineMode = plugins.getConfig("api").offline_mode;
if (!offlineMode) {
var server = tracker.getBulkServer();
var user = tracker.getBulkUser(server);
if (!user) {
return done();
}
try {
var custom = await tracker.getAllData();
if (Object.keys(custom).length) {
user.user_details({"custom": custom });
}
}
catch (ex) {
console.log("Error collecting server data:", ex);
}
var days = 90;
var current_sync = Date.now();
// Atomically retrieve old last_sync value and set new one
var syncResult = await db.collection("plugins").findOneAndUpdate(
{_id: "version"},
{$set: {last_sync: current_sync}},
{
upsert: true,
returnDocument: 'before',
projection: {last_sync: 1}
}
);
var last_sync = syncResult.value ? syncResult.value.last_sync : null;
if (last_sync) {
days = Math.floor((new Date().getTime() - last_sync) / (1000 * 60 * 60 * 24));
}
if (days > 0) {
//calculate seconds timestamp of days before today
var startTs = Math.round((new Date().getTime() - (30 * 24 * 60 * 60 * 1000)) / 1000);
//sync server events - use aggregation pipeline to group by day and action on MongoDB side
var aggregationPipeline = [
// Match documents with timestamp greater than startTs and valid action
{
$match: {
ts: { $gt: startTs }
}
},
// Add calculated fields for day grouping
{
$addFields: {
// Convert timestamp to date and set to noon (12:00:00)
dayDate: {
$dateFromParts: {
year: { $year: { $toDate: { $multiply: ["$ts", 1000] } } },
month: { $month: { $toDate: { $multiply: ["$ts", 1000] } } },
day: { $dayOfMonth: { $toDate: { $multiply: ["$ts", 1000] } } },
hour: 12,
minute: 0,
second: 0
}
}
}
},
// Convert back to timestamp in seconds
{
$addFields: {
noonTimestamp: {
$divide: [{ $toLong: "$dayDate" }, 1000]
}
}
},
// Group by day and action
{
$group: {
_id: {
day: "$noonTimestamp",
action: "$a"
},
count: { $sum: 1 }
}
},
// Project to final format
{
$project: {
_id: 0,
action: "$_id.action",
timestamp: "$_id.day",
count: 1
}
}
];
var cursor = db.collection("systemlogs").aggregate(aggregationPipeline);
while (cursor && await cursor.hasNext()) {
let eventData = await cursor.next();
user.add_event({key: eventData.action, count: eventData.count, timestamp: eventData.timestamp});
}
server.start(function() {
server.stop();
done();
});
}
else {
done();
}
}
else {
done();
}
});
}
}
module.exports = PingJob;