v12.0.0 - initial commit
This commit is contained in:
commit
e2c49ea43c
1145 changed files with 97211 additions and 0 deletions
164
packages/server/lib/logs.js
Normal file
164
packages/server/lib/logs.js
Normal file
|
|
@ -0,0 +1,164 @@
|
|||
const _ = require('lodash/fp')
|
||||
const { format, isValid } = require('date-fns/fp')
|
||||
const { utcToZonedTime } = require('date-fns-tz/fp')
|
||||
|
||||
const db = require('./db')
|
||||
const logger = require('./logger')
|
||||
const pgp = require('pg-promise')()
|
||||
|
||||
const getMachineName = require('./machine-loader').getMachineName
|
||||
|
||||
/**
|
||||
* 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 id, timestamp, serial from logs
|
||||
where device_id=$1
|
||||
order by timestamp desc, serial desc limit 1`
|
||||
return db
|
||||
.oneOrNone(sql, [deviceId])
|
||||
.then(log =>
|
||||
log ? { timestamp: log.timestamp, serial: log.serial, id: log.id } : null,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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) {
|
||||
const cs = new pgp.helpers.ColumnSet(
|
||||
['id', 'device_id', 'log_level', 'timestamp', 'serial', 'message'],
|
||||
{ table: 'logs' },
|
||||
)
|
||||
|
||||
const logs = _.map(log => {
|
||||
const formatted = {
|
||||
id: log.id,
|
||||
deviceId: deviceId,
|
||||
message: log.msg,
|
||||
logLevel: _.contains('error', _.lowerCase(log.msg)) ? 'error' : 'info',
|
||||
timestamp: log.timestamp,
|
||||
serial: log.serial || 0,
|
||||
}
|
||||
return _.mapKeys(_.snakeCase, formatted)
|
||||
}, logLines)
|
||||
const sql = pgp.helpers.insert(logs, cs) + 'on conflict do nothing'
|
||||
|
||||
return db.none(sql)
|
||||
}
|
||||
|
||||
function clearOldLogs() {
|
||||
const sqls = `delete from logs
|
||||
where timestamp < now() - interval '3 days';
|
||||
delete from server_logs
|
||||
where timestamp < now() - interval '3 days';`
|
||||
return db.multi(sqls)
|
||||
}
|
||||
|
||||
function getUnlimitedMachineLogs(deviceId, until = new Date().toISOString()) {
|
||||
// Note: sql is a little confusing here, since timestamp is used both as a column
|
||||
// and a reserved word, but it works.
|
||||
const sql = `select id, log_level, timestamp, message from logs
|
||||
where device_id=$1
|
||||
and timestamp <= $2
|
||||
and timestamp > (timestamp $2 - interval '2 days')
|
||||
order by timestamp desc, serial desc`
|
||||
|
||||
return Promise.all([
|
||||
db.any(sql, [deviceId, until]),
|
||||
getMachineName(deviceId),
|
||||
]).then(([logs, machineName]) => ({
|
||||
logs: _.map(_.mapKeys(_.camelCase), logs),
|
||||
currentMachine: { deviceId, name: machineName },
|
||||
}))
|
||||
}
|
||||
|
||||
function getMachineLogs(
|
||||
deviceId,
|
||||
until = new Date().toISOString(),
|
||||
limit = null,
|
||||
offset = 0,
|
||||
) {
|
||||
const sql = `select id, log_level, timestamp, message from logs
|
||||
where device_id=$1
|
||||
and timestamp <= $2
|
||||
order by timestamp desc, serial desc
|
||||
limit $3
|
||||
offset $4`
|
||||
|
||||
return Promise.all([
|
||||
db.any(sql, [deviceId, until, limit, offset]),
|
||||
getMachineName(deviceId),
|
||||
]).then(([logs, machineName]) => ({
|
||||
logs: _.map(_.mapKeys(_.camelCase), logs),
|
||||
currentMachine: { deviceId, name: machineName },
|
||||
}))
|
||||
}
|
||||
|
||||
function simpleGetMachineLogs(
|
||||
deviceId,
|
||||
from = new Date(0).toISOString(),
|
||||
until = new Date().toISOString(),
|
||||
limit = null,
|
||||
offset = 0,
|
||||
) {
|
||||
const sql = `select id, log_level, timestamp, message from logs
|
||||
where device_id=$1
|
||||
and timestamp >= $2
|
||||
and timestamp <= $3
|
||||
order by timestamp desc, serial desc
|
||||
limit $4
|
||||
offset $5`
|
||||
|
||||
return db
|
||||
.any(sql, [deviceId, from, until, limit, offset])
|
||||
.then(_.map(_.mapKeys(_.camelCase)))
|
||||
}
|
||||
|
||||
function logDateFormat(timezone, logs, fields) {
|
||||
return _.map(log => {
|
||||
const values = _.map(field => {
|
||||
if (_.isNil(log[field])) return null
|
||||
if (!isValid(log[field])) {
|
||||
logger.warn(
|
||||
`Tried to convert to ${timezone} timezone the value ${log[field]} and failed. Returning original value...`,
|
||||
)
|
||||
return log[field]
|
||||
}
|
||||
const date = utcToZonedTime(timezone, log[field])
|
||||
return `${format('yyyy-MM-dd', date)}T${format('HH:mm:ss.SSS', date)}`
|
||||
}, fields)
|
||||
const fieldsToOverride = _.zipObject(fields, values)
|
||||
return {
|
||||
...log,
|
||||
...fieldsToOverride,
|
||||
}
|
||||
}, logs)
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
getUnlimitedMachineLogs,
|
||||
getMachineLogs,
|
||||
simpleGetMachineLogs,
|
||||
update,
|
||||
getLastSeen,
|
||||
clearOldLogs,
|
||||
logDateFormat,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue