From c571c1d59031eaf510e560f3bdc62df2374ba45f Mon Sep 17 00:00:00 2001 From: James Barnett Date: Sun, 21 Oct 2018 19:12:36 +0100 Subject: Add configurable log interval and max log limit --- logger-config.json | 4 ++ public/javascripts/dash.js | 6 +-- routes/ws.js | 2 +- services/data-logger.js | 101 ++++++++++++++++++++++++++++++--------------- 4 files changed, 76 insertions(+), 37 deletions(-) create mode 100644 logger-config.json diff --git a/logger-config.json b/logger-config.json new file mode 100644 index 0000000..639d9a5 --- /dev/null +++ b/logger-config.json @@ -0,0 +1,4 @@ +{ + "logIntervalSeconds": 1, + "maxLogEntries": 1440 +} \ No newline at end of file diff --git a/public/javascripts/dash.js b/public/javascripts/dash.js index 11a8b0a..a2aa73f 100644 --- a/public/javascripts/dash.js +++ b/public/javascripts/dash.js @@ -244,11 +244,11 @@ var dash = { addLogEntry: function (logEntry, updateChart) { - dash.usageLogChart.data.labels.push(moment(logEntry.timestamp, 'x').format("MMM Do hh:mm"),); + dash.usageLogChart.data.labels.push(moment(logEntry.ts, 'x').format("MMM Do HH:mm"),); dash.usageLogChart.data.datasets.forEach(function (dataset) { dataset.data.push({ - x: logEntry.timestamp, - y: logEntry.power + x: logEntry.ts, + y: logEntry.pw }); }); if (updateChart) { diff --git a/routes/ws.js b/routes/ws.js index 86eec0d..1599721 100644 --- a/routes/ws.js +++ b/routes/ws.js @@ -21,7 +21,7 @@ router.ws('/', function(ws, req) { ws.send(dataBroadcaster.generatePayload('dailyUsage', deviceId, cachedData.dailyUsage)); ws.send(dataBroadcaster.generatePayload('monthlyUsage', deviceId, cachedData.monthlyUsage)); ws.send(dataBroadcaster.generatePayload('powerState', deviceId, cachedData.powerState)); - dataLogger.getAllEntries(deviceId, (loggedData) => { + dataLogger.getLogEntriesForDevice(deviceId, (loggedData) => { ws.send(dataBroadcaster.generatePayload('loggedData', deviceId, loggedData)); }); diff --git a/services/data-logger.js b/services/data-logger.js index 0948221..9c23de1 100644 --- a/services/data-logger.js +++ b/services/data-logger.js @@ -1,9 +1,58 @@ const fs = require('fs'); const dataBroadcaster = require('./data-broadcaster'); +let logIntervalMs; +let maxLogEntries; + +loadLogConfig(); + +function loadLogConfig() { + try { + let config = JSON.parse(fs.readFileSync('logger-config.json', 'utf8')); + logIntervalMs = (config.logIntervalSeconds * 1000); + maxLogEntries = config.maxLogEntries; + + } + catch (err) { + console.warn('Error reading logger config. Reverting to defaults.', err); + logIntervalMs = 60000 // 1 min + maxLogEntries = 1440 // 24 hrs at 1/min + } +} + function startLogging(device) { - setInterval(() => { log(device); }, 60000); - console.log('Logging started for ' + device.alias + ' [' + device.deviceId + ']'); + setInterval(() => { log(device); }, logIntervalMs); + console.log('Logging started for ' + device.alias + ' [' + device.deviceId + '] every ' + (logIntervalMs/1000) + ' seconds'); +} + +function writeLog(filePath, log) { + fs.writeFile(filePath, JSON.stringify(log), { flag: 'w' }, (err) => { + if (err) { + console.warn('Error writing log for ' + device.alias + ' [' + device.deviceId + ']', err); + } + }); +} + +function getLogEntries(filePath, callback) { + + fs.access(filePath, fs.constants.F_OK, (err) => { + if(err) { + // No log file, init empty one + writeLog(filePath, []); + callback([]); + } + else { + fs.readFile(filePath, 'utf8', (err, data) => { + if (err) { + console.warn('Error reading usage log ' + filePath, err); + callback([]); + } + else { + callback(JSON.parse(data)); + } + }); + } + }); } function log(device) { @@ -11,49 +60,35 @@ function log(device) { device.emeter.getRealtime().then(response => { let logEntry = { - timestamp: Date.now(), - power: (('power_mw' in response) ? (response.power_mw / 1000) : response.power) + ts: Date.now(), + pw: (('power_mw' in response) ? (response.power_mw / 1000) : response.power) } - // TODO only log up to a max number of entries + let filePath = getLogPath(device.deviceId); - fs.writeFile(device.deviceId + '-log.json', JSON.stringify(logEntry) + '\n', { flag: 'a' }, (err) => { - if(err) { - console.warn('Error writing log entry for ' + device.alias + ' [' + device.deviceId + ']', err); - } - else { - dataBroadcaster.broadcastNewLogEntry(device.deviceId, logEntry); - } + getLogEntries(filePath, (entries) => { + entries.push(logEntry) + + // Remove old entries + entries.splice(0, entries.length - maxLogEntries); - }); + writeLog(filePath, entries); + dataBroadcaster.broadcastNewLogEntry(device.deviceId, logEntry); + }) }); - } -function getAllEntries(deviceId, callback) { - fs.readFile(deviceId + '-log.json', 'utf8', (err, data) => { - if(err) { - console.warn('Error reading usage log ' + deviceId + '-log.json', err); - return; - } - else { - let logLines = data.split(/\r?\n/); - let logEntries = []; - - logLines.forEach(line => { - if(line.length > 0) { - logEntries.push(JSON.parse(line)) - } - }); +function getLogPath(deviceId) { + return deviceId + '-log.json'; +} - callback(logEntries); - } - }); +function getLogEntriesForDevice(deviceId, callback) { + return getLogEntries(getLogPath(deviceId), callback); } module.exports = { startLogging: startLogging, log: log, - getAllEntries: getAllEntries + getLogEntriesForDevice: getLogEntriesForDevice } \ No newline at end of file -- cgit v1.2.3