audiobookshelf/server/objects/DailyLog.js
2022-07-06 19:18:27 -05:00

129 lines
3.1 KiB
JavaScript

const Path = require('path')
const date = require('../libs/dateAndTime')
const fs = require('../libs/fsExtra')
const { readTextFile } = require('../utils/fileUtils')
const Logger = require('../Logger')
class DailyLog {
constructor() {
this.id = null
this.datePretty = null
this.dailyLogDirPath = null
this.filename = null
this.path = null
this.fullPath = null
this.createdAt = null
this.logs = []
this.bufferedLogLines = []
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,
datePretty: this.datePretty,
path: this.path,
dailyLogDirPath: this.dailyLogDirPath,
fullPath: this.fullPath,
filename: this.filename,
createdAt: this.createdAt
}
}
setData(data) {
this.id = date.format(new Date(), 'YYYY-MM-DD')
this.datePretty = date.format(new Date(), 'ddd, MMM D YYYY')
this.dailyLogDirPath = data.dailyLogDirPath
this.filename = this.id + '.txt'
this.path = Path.join('backups', this.filename)
this.fullPath = Path.join(this.dailyLogDirPath, this.filename)
this.createdAt = Date.now()
}
async appendBufferedLogs() {
var buffered = [...this.bufferedLogLines]
this.bufferedLogLines = []
var oneBigLog = ''
buffered.forEach((logLine) => {
oneBigLog += logLine
})
this.appendLogLine(oneBigLog)
}
async appendLog(logObj) {
this.logs.push(logObj)
var line = JSON.stringify(logObj) + '\n'
this.appendLogLine(line)
}
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) {
this.appendBufferedLogs()
}
}
async loadLogs() {
var exists = await fs.pathExists(this.fullPath)
if (!exists) {
console.error('Daily log does not exist')
return
}
var text = await readTextFile(this.fullPath)
var hasFailures = false
var logLines = text.split(/\r?\n/)
// remove last log if empty
if (logLines.length && !logLines[logLines.length - 1]) logLines = logLines.slice(0, -1)
this.logs = logLines.map(t => {
if (!t) {
hasFailures = true
return null
}
try {
return JSON.parse(t)
} catch (err) {
console.error('Failed to parse log line', t, err)
hasFailures = true
return null
}
}).filter(l => !!l)
// Rewrite log file to remove errors
if (hasFailures) {
var newLogLines = this.logs.map(l => JSON.stringify(l)).join('\n') + '\n'
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`)
}
}
module.exports = DailyLog