2021-10-31 23:55:28 +01:00
|
|
|
const Path = require('path')
|
2022-07-07 02:18:27 +02:00
|
|
|
const date = require('../libs/dateAndTime')
|
2022-07-06 02:53:01 +02:00
|
|
|
const fs = require('../libs/fsExtra')
|
2024-02-15 23:46:19 +01:00
|
|
|
const fileUtils = require('../utils/fileUtils')
|
2021-10-31 23:55:28 +01:00
|
|
|
const Logger = require('../Logger')
|
|
|
|
|
|
|
|
class DailyLog {
|
2024-02-15 23:46:19 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param {string} dailyLogDirPath Path to daily logs /metadata/logs/daily
|
|
|
|
*/
|
|
|
|
constructor(dailyLogDirPath) {
|
|
|
|
this.id = date.format(new Date(), 'YYYY-MM-DD')
|
2021-10-31 23:55:28 +01:00
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
this.dailyLogDirPath = dailyLogDirPath
|
|
|
|
this.filename = this.id + '.txt'
|
|
|
|
this.fullPath = Path.join(this.dailyLogDirPath, this.filename)
|
2021-10-31 23:55:28 +01:00
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
this.createdAt = Date.now()
|
2021-10-31 23:55:28 +01:00
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
/** @type {import('../managers/LogManager').LogObject[]} */
|
2021-10-31 23:55:28 +01:00
|
|
|
this.logs = []
|
2024-02-15 23:46:19 +01:00
|
|
|
/** @type {string[]} */
|
2021-10-31 23:55:28 +01:00
|
|
|
this.bufferedLogLines = []
|
2024-02-15 23:46:19 +01:00
|
|
|
|
2021-10-31 23:55:28 +01:00
|
|
|
this.locked = false
|
|
|
|
}
|
|
|
|
|
|
|
|
static getCurrentDailyLogFilename() {
|
|
|
|
return date.format(new Date(), 'YYYY-MM-DD') + '.txt'
|
|
|
|
}
|
|
|
|
|
|
|
|
static getCurrentDateString() {
|
|
|
|
return date.format(new Date(), 'YYYY-MM-DD')
|
|
|
|
}
|
|
|
|
|
|
|
|
toJSON() {
|
|
|
|
return {
|
|
|
|
id: this.id,
|
|
|
|
dailyLogDirPath: this.dailyLogDirPath,
|
|
|
|
fullPath: this.fullPath,
|
|
|
|
filename: this.filename,
|
|
|
|
createdAt: this.createdAt
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
/**
|
|
|
|
* Append all buffered lines to daily log file
|
|
|
|
*/
|
|
|
|
appendBufferedLogs() {
|
|
|
|
let buffered = [...this.bufferedLogLines]
|
2021-10-31 23:55:28 +01:00
|
|
|
this.bufferedLogLines = []
|
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
let oneBigLog = ''
|
2021-10-31 23:55:28 +01:00
|
|
|
buffered.forEach((logLine) => {
|
2021-11-01 01:10:45 +01:00
|
|
|
oneBigLog += logLine
|
2021-10-31 23:55:28 +01:00
|
|
|
})
|
2024-02-15 23:46:19 +01:00
|
|
|
return this.appendLogLine(oneBigLog)
|
2021-10-31 23:55:28 +01:00
|
|
|
}
|
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
/**
|
|
|
|
*
|
|
|
|
* @param {import('../managers/LogManager').LogObject} logObj
|
|
|
|
*/
|
|
|
|
appendLog(logObj) {
|
2021-10-31 23:55:28 +01:00
|
|
|
this.logs.push(logObj)
|
2024-02-15 23:46:19 +01:00
|
|
|
return this.appendLogLine(JSON.stringify(logObj) + '\n')
|
2021-10-31 23:55:28 +01:00
|
|
|
}
|
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
/**
|
|
|
|
* Append log to daily log file
|
|
|
|
*
|
|
|
|
* @param {string} line
|
|
|
|
*/
|
2021-10-31 23:55:28 +01:00
|
|
|
async appendLogLine(line) {
|
|
|
|
if (this.locked) {
|
|
|
|
this.bufferedLogLines.push(line)
|
|
|
|
return
|
|
|
|
}
|
|
|
|
this.locked = true
|
|
|
|
|
|
|
|
await fs.writeFile(this.fullPath, line, { flag: "a+" }).catch((error) => {
|
|
|
|
console.log('[DailyLog] Append log failed', error)
|
|
|
|
})
|
|
|
|
|
|
|
|
this.locked = false
|
|
|
|
if (this.bufferedLogLines.length) {
|
2024-02-15 23:46:19 +01:00
|
|
|
await this.appendBufferedLogs()
|
2021-10-31 23:55:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
/**
|
|
|
|
* Load all logs from file
|
|
|
|
* Parses lines and re-saves the file if bad lines are removed
|
|
|
|
*/
|
2021-10-31 23:55:28 +01:00
|
|
|
async loadLogs() {
|
2024-02-15 23:46:19 +01:00
|
|
|
if (!await fs.pathExists(this.fullPath)) {
|
2021-10-31 23:55:28 +01:00
|
|
|
console.error('Daily log does not exist')
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
const text = await fileUtils.readTextFile(this.fullPath)
|
2021-11-01 01:10:45 +01:00
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
let hasFailures = false
|
2021-11-01 01:10:45 +01:00
|
|
|
|
2024-02-15 23:46:19 +01:00
|
|
|
let logLines = text.split(/\r?\n/)
|
2021-11-04 13:59:28 +01:00
|
|
|
// remove last log if empty
|
|
|
|
if (logLines.length && !logLines[logLines.length - 1]) logLines = logLines.slice(0, -1)
|
2024-02-15 23:46:19 +01:00
|
|
|
|
|
|
|
// JSON parse log lines
|
2021-11-04 13:59:28 +01:00
|
|
|
this.logs = logLines.map(t => {
|
2021-11-01 01:10:45 +01:00
|
|
|
if (!t) {
|
|
|
|
hasFailures = true
|
|
|
|
return null
|
|
|
|
}
|
2021-10-31 23:55:28 +01:00
|
|
|
try {
|
|
|
|
return JSON.parse(t)
|
|
|
|
} catch (err) {
|
|
|
|
console.error('Failed to parse log line', t, err)
|
2021-11-01 01:10:45 +01:00
|
|
|
hasFailures = true
|
2021-10-31 23:55:28 +01:00
|
|
|
return null
|
|
|
|
}
|
|
|
|
}).filter(l => !!l)
|
|
|
|
|
2021-11-01 01:10:45 +01:00
|
|
|
// Rewrite log file to remove errors
|
|
|
|
if (hasFailures) {
|
2024-02-15 23:46:19 +01:00
|
|
|
const newLogLines = this.logs.map(l => JSON.stringify(l)).join('\n') + '\n'
|
2021-11-01 01:10:45 +01:00
|
|
|
await fs.writeFile(this.fullPath, newLogLines)
|
|
|
|
console.log('Re-Saved log file to remove bad lines')
|
|
|
|
}
|
|
|
|
|
|
|
|
Logger.debug(`[DailyLog] ${this.id}: Loaded ${this.logs.length} Logs`)
|
2021-10-31 23:55:28 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
module.exports = DailyLog
|