diff --git a/lib/admin/admin-server.js b/lib/admin/admin-server.js index 5d44914e..0a757ab6 100644 --- a/lib/admin/admin-server.js +++ b/lib/admin/admin-server.js @@ -191,6 +191,17 @@ app.get('/api/logs/:deviceId', (req, res, next) => { .catch(next) }) +app.get('/api/logs', (req, res, next) => { + return machineLoader.getMachines() + .then(machines => { + const firstMachine = _.first(machines) + if (!firstMachine) return res.status(404).send({Error: 'No machines'}) + return logs.getMachineLogs(firstMachine.deviceId) + .then(r => res.send(r)) + }) + .catch(next) +}) + /** * Endpoint for patching customer's data * diff --git a/lib/logs.js b/lib/logs.js index da54e414..aaec25b3 100644 --- a/lib/logs.js +++ b/lib/logs.js @@ -1,10 +1,24 @@ const _ = require('lodash/fp') const db = require('./db') -const machineLoader = require('./machine-loader') +const pgp = require('pg-promise')() + +const settingsLoader = require('./settings-loader') +const configManager = require('./config-manager') const NUM_RESULTS = 1000 +/** + * Get the latest log's timestamp + * + * @name getLastSeen + * @function + * @async + * + * @param {string} deviceId Machine id to get the last timestamp for + * + * @returns {date} Last timestamp + */ function getLastSeen (deviceId) { const sql = `select timestamp from logs where device_id=$1 @@ -13,27 +27,35 @@ function getLastSeen (deviceId) { .then(log => log ? log.timestamp : null) } -function insert (log) { - console.log('inserting', log) - const sql = `insert into logs - (id, device_id, log_level, timestamp, message) values - ($1, $2, $3, $4, $5) on conflict do nothing` - return db.oneOrNone(sql, [log.id, log.deviceId, log.logLevel, log.timestamp, log.message]) -} - +/** + * Update logs in db + * + * @name update + * @function + * @async + * + * @param {string} deviceId Machine Id to which logs belong to + * @param {array} logLines Logs to be saved + * + * @returns {null} + */ function update (deviceId, logLines) { - // Prepare logs to update + const cs = new pgp.helpers.ColumnSet([ + 'id', 'device_id', 'log_level', 'timestamp', 'message'], + {table: 'logs'}) + const logs = _.map(log => { - return { + const formatted = { id: log.id, deviceId: deviceId, message: log.msg, logLevel: log.level, timestamp: log.timestamp } + return _.mapKeys(_.snakeCase, formatted) }, logLines) - // Batch save logs - return Promise.all(_.map(insert, _.compact(logs))) + const sql = pgp.helpers.insert(logs, cs) + return db.none(sql) } /** @@ -47,51 +69,32 @@ function update (deviceId, logLines) { * @returns {array} Array of logs for the requested machinej */ function getMachineLogs (deviceId) { - const sql = `select * from logs + const sql = `select id, log_level, timestamp, message from logs where device_id=$1 order by timestamp desc limit $2` - return db.any(sql, [ deviceId, NUM_RESULTS ]) - .then(_.map(camelize)) - .then(logs => { - return getMachineById(deviceId) - .then(currentMachine => { - return { - logs, - currentMachine - } - }) - }) + return Promise.all([db.any(sql, [ deviceId, NUM_RESULTS ]), getMachineName(deviceId)]) + .then(([logs, machineName]) => ({ + logs: _.map(_.mapKeys(_.camelCase), logs), + currentMachine: {deviceId, name: machineName} + })) } /** - * Find machine by id + * Given the machine id, get the machine name * - * @name getMachineById + * @name getMachineName * @function * @async * - * @param {string} deviceId machine's id - * - * @returns {object} Found machine + * @param {string} machineId machine id + * @returns {string} machine name */ -function getMachineById (deviceId) { - return machineLoader.getMachineNames().then(names => { - return _.find({deviceId}, names) +function getMachineName (machineId) { + return settingsLoader.loadRecentConfig() + .then(config => { + const machineScoped = configManager.machineScoped(machineId, config) + return machineScoped.machineName }) } -/** - * Camelize log fields - * Note: return null if log is undefined - * - * @name camelize - * @function - * - * @param {object} log Log with snake_case fields - * @returns {object} Camelized Log object - */ -function camelize (log) { - return log ? _.mapKeys(_.camelCase, log) : null -} - module.exports = { getMachineLogs, update, getLastSeen } diff --git a/public/elm.js b/public/elm.js index 8205142b..40dbb107 100644 --- a/public/elm.js +++ b/public/elm.js @@ -34135,9 +34135,9 @@ var _user$project$Logs_Types$Machine = F2( function (a, b) { return {deviceId: a, name: b}; }); -var _user$project$Logs_Types$Log = F5( - function (a, b, c, d, e) { - return {id: a, deviceId: b, timestamp: c, logLevel: d, message: e}; +var _user$project$Logs_Types$Log = F4( + function (a, b, c, d) { + return {id: a, timestamp: b, logLevel: c, message: d}; }); var _user$project$Logs_Types$Logs = F2( function (a, b) { @@ -35547,13 +35547,9 @@ var _user$project$Logs_Decoder$logDecoder = A3( _elm_lang$core$Json_Decode$nullable(_elm_community$json_extra$Json_Decode_Extra$date), A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'deviceId', - _elm_lang$core$Json_Decode$nullable(_elm_lang$core$Json_Decode$string), - A3( - _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, - 'id', - _elm_lang$core$Json_Decode$string, - _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$decode(_user$project$Logs_Types$Log)))))); + 'id', + _elm_lang$core$Json_Decode$string, + _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$decode(_user$project$Logs_Types$Log))))); var _user$project$Logs_Decoder$logsDecoder = A3( _NoRedInk$elm_decode_pipeline$Json_Decode_Pipeline$required, 'currentMachine', @@ -35696,45 +35692,45 @@ var _user$project$Logs_View$logsView = function (logs) { { ctor: '::', _0: A2( - _elm_lang$html$Html$h2, - {ctor: '[]'}, + _elm_lang$html$Html$table, { ctor: '::', - _0: _elm_lang$html$Html$text('Logs'), + _0: _user$project$Css_Admin$class( + { + ctor: '::', + _0: _user$project$Css_Classes$TxTable, + _1: {ctor: '[]'} + }), _1: {ctor: '[]'} - }), - _1: { - ctor: '::', - _0: A2( - _elm_lang$html$Html$table, - { - ctor: '::', - _0: _user$project$Css_Admin$class( - { - ctor: '::', - _0: _user$project$Css_Classes$TxTable, - _1: {ctor: '[]'} - }), - _1: {ctor: '[]'} - }, - { - ctor: '::', - _0: A2( - _elm_lang$html$Html$thead, - {ctor: '[]'}, - { - ctor: '::', - _0: A2( - _elm_lang$html$Html$tr, - {ctor: '[]'}, - { + }, + { + ctor: '::', + _0: A2( + _elm_lang$html$Html$thead, + {ctor: '[]'}, + { + ctor: '::', + _0: A2( + _elm_lang$html$Html$tr, + {ctor: '[]'}, + { + ctor: '::', + _0: A2( + _elm_lang$html$Html$td, + {ctor: '[]'}, + { + ctor: '::', + _0: _elm_lang$html$Html$text('Date'), + _1: {ctor: '[]'} + }), + _1: { ctor: '::', _0: A2( _elm_lang$html$Html$td, {ctor: '[]'}, { ctor: '::', - _0: _elm_lang$html$Html$text('Date'), + _0: _elm_lang$html$Html$text('Level'), _1: {ctor: '[]'} }), _1: { @@ -35744,36 +35740,25 @@ var _user$project$Logs_View$logsView = function (logs) { {ctor: '[]'}, { ctor: '::', - _0: _elm_lang$html$Html$text('Level'), + _0: _elm_lang$html$Html$text('Message'), _1: {ctor: '[]'} }), - _1: { - ctor: '::', - _0: A2( - _elm_lang$html$Html$td, - {ctor: '[]'}, - { - ctor: '::', - _0: _elm_lang$html$Html$text('Message'), - _1: {ctor: '[]'} - }), - _1: {ctor: '[]'} - } + _1: {ctor: '[]'} } - }), - _1: {ctor: '[]'} - }), - _1: { - ctor: '::', - _0: A2( - _elm_lang$html$Html$tbody, - {ctor: '[]'}, - A2(_elm_lang$core$List$map, _user$project$Logs_View$rowView, logs.logs)), + } + }), _1: {ctor: '[]'} - } - }), - _1: {ctor: '[]'} - } + }), + _1: { + ctor: '::', + _0: A2( + _elm_lang$html$Html$tbody, + {ctor: '[]'}, + A2(_elm_lang$core$List$map, _user$project$Logs_View$rowView, logs.logs)), + _1: {ctor: '[]'} + } + }), + _1: {ctor: '[]'} }); }; var _user$project$Logs_View$logs = function (model) { @@ -35786,7 +35771,7 @@ var _user$project$Logs_View$logs = function (model) { {ctor: '[]'}); case 'Loading': return A2( - _elm_lang$html$Html$h2, + _elm_lang$html$Html$div, {ctor: '[]'}, { ctor: '::', @@ -35884,37 +35869,26 @@ var _user$project$Logs_View$machinesView = function (machines) { { ctor: '::', _0: A2( - _elm_lang$html$Html$h2, - {ctor: '[]'}, + _elm_lang$html$Html$div, { ctor: '::', - _0: _elm_lang$html$Html$text('Machines'), + _0: _user$project$Css_Admin$class( + { + ctor: '::', + _0: _user$project$Css_Classes$TxTable, + _1: {ctor: '[]'} + }), + _1: {ctor: '[]'} + }, + { + ctor: '::', + _0: A2( + _elm_lang$html$Html$ul, + {ctor: '[]'}, + A2(_elm_lang$core$List$map, _user$project$Logs_View$machineItemView, machines)), _1: {ctor: '[]'} }), - _1: { - ctor: '::', - _0: A2( - _elm_lang$html$Html$div, - { - ctor: '::', - _0: _user$project$Css_Admin$class( - { - ctor: '::', - _0: _user$project$Css_Classes$TxTable, - _1: {ctor: '[]'} - }), - _1: {ctor: '[]'} - }, - { - ctor: '::', - _0: A2( - _elm_lang$html$Html$ul, - {ctor: '[]'}, - A2(_elm_lang$core$List$map, _user$project$Logs_View$machineItemView, machines)), - _1: {ctor: '[]'} - }), - _1: {ctor: '[]'} - } + _1: {ctor: '[]'} }); }; var _user$project$Logs_View$machines = function (model) { @@ -35927,7 +35901,7 @@ var _user$project$Logs_View$machines = function (model) { {ctor: '[]'}); case 'Loading': return A2( - _elm_lang$html$Html$h2, + _elm_lang$html$Html$div, {ctor: '[]'}, { ctor: '::', @@ -35999,8 +35973,19 @@ var _user$project$Logs_View$view = function (model) { }, { ctor: '::', - _0: _user$project$Logs_View$machines(model), - _1: {ctor: '[]'} + _0: A2( + _elm_lang$html$Html$h2, + {ctor: '[]'}, + { + ctor: '::', + _0: _elm_lang$html$Html$text('Machines'), + _1: {ctor: '[]'} + }), + _1: { + ctor: '::', + _0: _user$project$Logs_View$machines(model), + _1: {ctor: '[]'} + } }), _1: { ctor: '::', @@ -36018,8 +36003,19 @@ var _user$project$Logs_View$view = function (model) { }, { ctor: '::', - _0: _user$project$Logs_View$logs(model), - _1: {ctor: '[]'} + _0: A2( + _elm_lang$html$Html$h2, + {ctor: '[]'}, + { + ctor: '::', + _0: _elm_lang$html$Html$text('Logs'), + _1: {ctor: '[]'} + }), + _1: { + ctor: '::', + _0: _user$project$Logs_View$logs(model), + _1: {ctor: '[]'} + } }), _1: {ctor: '[]'} }