mirror of
				https://github.com/advplyr/audiobookshelf.git
				synced 2025-11-04 03:17:00 -05:00 
			
		
		
		
	Fix: Daily log file not adding newlines to logs, Add: Config log page loads last 5000 logs for the current day #72
This commit is contained in:
		
							parent
							
								
									6ccde8f66f
								
							
						
					
					
						commit
						8ca6c62a03
					
				@ -6,7 +6,7 @@
 | 
			
		||||
        <a v-if="showBack" @click="back" class="rounded-full h-12 w-12 flex items-center justify-center hover:bg-white hover:bg-opacity-10 mr-4 cursor-pointer">
 | 
			
		||||
          <span class="material-icons text-4xl text-white">arrow_back</span>
 | 
			
		||||
        </a>
 | 
			
		||||
        <h1 class="text-2xl font-book mr-6">AudioBookshelf</h1>
 | 
			
		||||
        <h1 class="text-2xl font-book mr-6">audiobookshelf</h1>
 | 
			
		||||
 | 
			
		||||
        <ui-libraries-dropdown />
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -245,9 +245,6 @@ export default {
 | 
			
		||||
    showSuccessToast(message) {
 | 
			
		||||
      this.$toast.success(message)
 | 
			
		||||
    },
 | 
			
		||||
    logEvtReceived(payload) {
 | 
			
		||||
      this.$store.commit('logs/logEvt', payload)
 | 
			
		||||
    },
 | 
			
		||||
    backupApplied() {
 | 
			
		||||
      // Force refresh
 | 
			
		||||
      location.reload()
 | 
			
		||||
@ -313,8 +310,6 @@ export default {
 | 
			
		||||
      this.socket.on('show_error_toast', this.showErrorToast)
 | 
			
		||||
      this.socket.on('show_success_toast', this.showSuccessToast)
 | 
			
		||||
 | 
			
		||||
      this.socket.on('log', this.logEvtReceived)
 | 
			
		||||
 | 
			
		||||
      this.socket.on('backup_applied', this.backupApplied)
 | 
			
		||||
    },
 | 
			
		||||
    showUpdateToast(versionData) {
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,12 @@
 | 
			
		||||
<template>
 | 
			
		||||
  <div id="page-wrapper" class="page p-6 overflow-y-auto" :class="streamAudiobook ? 'streaming' : ''">
 | 
			
		||||
    <div class="w-full max-w-4xl mx-auto">
 | 
			
		||||
      <div class="mb-4 flex items-center justify-between">
 | 
			
		||||
        <p class="text-2xl">Logger</p>
 | 
			
		||||
      <div class="mb-4 flex items-end">
 | 
			
		||||
        <p class="text-2xl mr-4">Logger</p>
 | 
			
		||||
 | 
			
		||||
        <ui-text-input ref="input" v-model="search" placeholder="Search filter.." @input="inputUpdate" clearable class="w-40 h-8 text-sm" />
 | 
			
		||||
 | 
			
		||||
        <div class="flex-grow" />
 | 
			
		||||
 | 
			
		||||
        <div class="w-44">
 | 
			
		||||
          <ui-dropdown v-model="newServerSettings.logLevel" label="Server Log Level" :items="logLevelItems" @input="logLevelUpdated" />
 | 
			
		||||
@ -22,7 +26,6 @@
 | 
			
		||||
 | 
			
		||||
        <div v-if="!logs.length" class="absolute top-0 left-0 w-full h-full flex flex-col items-center justify-center text-center">
 | 
			
		||||
          <p class="text-xl text-gray-200 mb-2">No Logs</p>
 | 
			
		||||
          <p class="text-base text-gray-400">Log listening starts when you login</p>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
@ -38,6 +41,9 @@ export default {
 | 
			
		||||
  },
 | 
			
		||||
  data() {
 | 
			
		||||
    return {
 | 
			
		||||
      search: null,
 | 
			
		||||
      searchTimeout: null,
 | 
			
		||||
      searchText: null,
 | 
			
		||||
      newServerSettings: {},
 | 
			
		||||
      logColors: ['yellow-200', 'gray-400', 'info', 'warning', 'error', 'red-800', 'blue-400'],
 | 
			
		||||
      logLevels: [
 | 
			
		||||
@ -53,7 +59,8 @@ export default {
 | 
			
		||||
          value: 3,
 | 
			
		||||
          text: 'Warn'
 | 
			
		||||
        }
 | 
			
		||||
      ]
 | 
			
		||||
      ],
 | 
			
		||||
      loadedLogs: []
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  watch: {
 | 
			
		||||
@ -73,8 +80,14 @@ export default {
 | 
			
		||||
      return this.logLevels
 | 
			
		||||
    },
 | 
			
		||||
    logs() {
 | 
			
		||||
      return this.$store.state.logs.logs.filter((log) => {
 | 
			
		||||
        return log.level >= this.newServerSettings.logLevel
 | 
			
		||||
      return this.loadedLogs.filter((log) => {
 | 
			
		||||
        if (log.level >= this.newServerSettings.logLevel) {
 | 
			
		||||
          if (this.searchText) {
 | 
			
		||||
            return log.message.toLowerCase().includes(this.searchText)
 | 
			
		||||
          }
 | 
			
		||||
          return true
 | 
			
		||||
        }
 | 
			
		||||
        return false
 | 
			
		||||
      })
 | 
			
		||||
    },
 | 
			
		||||
    serverSettings() {
 | 
			
		||||
@ -85,6 +98,16 @@ export default {
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  methods: {
 | 
			
		||||
    inputUpdate() {
 | 
			
		||||
      clearTimeout(this.searchTimeout)
 | 
			
		||||
      this.searchTimeout = setTimeout(() => {
 | 
			
		||||
        if (!this.search || !this.search.trim()) {
 | 
			
		||||
          this.searchText = ''
 | 
			
		||||
          return
 | 
			
		||||
        }
 | 
			
		||||
        this.searchText = this.search.toLowerCase().trim()
 | 
			
		||||
      }, 500)
 | 
			
		||||
    },
 | 
			
		||||
    updateScroll() {
 | 
			
		||||
      if (this.$refs.container) {
 | 
			
		||||
        this.$refs.container.scrollTop = this.$refs.container.scrollHeight - this.$refs.container.clientHeight
 | 
			
		||||
@ -96,7 +119,7 @@ export default {
 | 
			
		||||
      }
 | 
			
		||||
      this.updateServerSettings(payload)
 | 
			
		||||
 | 
			
		||||
      this.$store.dispatch('logs/setLogListener', this.newServerSettings.logLevel)
 | 
			
		||||
      this.$root.socket.emit('set_log_listener', this.newServerSettings.logLevel)
 | 
			
		||||
      this.$nextTick(this.updateScroll)
 | 
			
		||||
    },
 | 
			
		||||
    updateServerSettings(payload) {
 | 
			
		||||
@ -109,6 +132,14 @@ export default {
 | 
			
		||||
          console.error('Failed to update server settings', error)
 | 
			
		||||
        })
 | 
			
		||||
    },
 | 
			
		||||
    logEvtReceived(payload) {
 | 
			
		||||
      this.loadedLogs.push(payload)
 | 
			
		||||
 | 
			
		||||
      // Dont let logs get too large
 | 
			
		||||
      if (this.loadedLogs.length > 5050) {
 | 
			
		||||
        this.loadedLogs = this.loadedLogs.slice(-5000)
 | 
			
		||||
      }
 | 
			
		||||
    },
 | 
			
		||||
    init(attempts = 0) {
 | 
			
		||||
      if (!this.$root.socket) {
 | 
			
		||||
        if (attempts > 10) {
 | 
			
		||||
@ -119,7 +150,15 @@ export default {
 | 
			
		||||
        }, 250)
 | 
			
		||||
        return
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      this.newServerSettings = this.serverSettings ? { ...this.serverSettings } : {}
 | 
			
		||||
      this.$root.socket.on('daily_logs', this.dailyLogsLoaded)
 | 
			
		||||
      this.$root.socket.on('log', this.logEvtReceived)
 | 
			
		||||
      this.$root.socket.emit('set_log_listener', this.newServerSettings.logLevel)
 | 
			
		||||
      this.$root.socket.emit('fetch_daily_logs')
 | 
			
		||||
    },
 | 
			
		||||
    dailyLogsLoaded(lines) {
 | 
			
		||||
      this.loadedLogs = lines
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  updated() {
 | 
			
		||||
@ -127,6 +166,11 @@ export default {
 | 
			
		||||
  },
 | 
			
		||||
  mounted() {
 | 
			
		||||
    this.init()
 | 
			
		||||
  },
 | 
			
		||||
  beforeDestroy() {
 | 
			
		||||
    if (!this.$root.socket) return
 | 
			
		||||
    this.$root.socket.off('daily_logs', this.dailyLogsLoaded)
 | 
			
		||||
    this.$root.socket.off('log', this.logEvtReceived)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
</script>
 | 
			
		||||
 | 
			
		||||
@ -1,31 +0,0 @@
 | 
			
		||||
export const state = () => ({
 | 
			
		||||
  isListening: false,
 | 
			
		||||
  logs: []
 | 
			
		||||
})
 | 
			
		||||
 | 
			
		||||
export const getters = {
 | 
			
		||||
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const actions = {
 | 
			
		||||
  setLogListener({ state, commit, dispatch }) {
 | 
			
		||||
    dispatch('$nuxtSocket/emit', {
 | 
			
		||||
      label: 'main',
 | 
			
		||||
      evt: 'set_log_listener',
 | 
			
		||||
      msg: 0
 | 
			
		||||
    }, { root: true })
 | 
			
		||||
    commit('setIsListening', true)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const mutations = {
 | 
			
		||||
  setIsListening(state, val) {
 | 
			
		||||
    state.isListening = val
 | 
			
		||||
  },
 | 
			
		||||
  logEvt(state, payload) {
 | 
			
		||||
    state.logs.push(payload)
 | 
			
		||||
    if (state.logs.length > 500) {
 | 
			
		||||
      state.logs = state.logs.slice(50)
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
@ -4,7 +4,6 @@ const fs = require('fs-extra')
 | 
			
		||||
const DailyLog = require('./objects/DailyLog')
 | 
			
		||||
 | 
			
		||||
const Logger = require('./Logger')
 | 
			
		||||
const { getFileSize } = require('./utils/fileUtils')
 | 
			
		||||
 | 
			
		||||
const TAG = '[LogManager]'
 | 
			
		||||
 | 
			
		||||
@ -50,14 +49,16 @@ class LogManager {
 | 
			
		||||
 | 
			
		||||
    if (this.dailyLogFiles.includes(currentDailyLogFilename)) {
 | 
			
		||||
      Logger.debug(TAG, `Daily log file already exists - set in Logger`)
 | 
			
		||||
      this.currentDailyLog.loadLogs()
 | 
			
		||||
      await this.currentDailyLog.loadLogs()
 | 
			
		||||
    } else {
 | 
			
		||||
      this.dailyLogFiles.push(this.currentDailyLog.filename)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Log buffered Logs
 | 
			
		||||
    if (this.dailyLogBuffer.length) {
 | 
			
		||||
      this.dailyLogBuffer.forEach((logObj) => this.currentDailyLog.appendLog(logObj))
 | 
			
		||||
      this.dailyLogBuffer.forEach((logObj) => {
 | 
			
		||||
        this.currentDailyLog.appendLog(logObj)
 | 
			
		||||
      })
 | 
			
		||||
      this.dailyLogBuffer = []
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
@ -68,7 +69,7 @@ class LogManager {
 | 
			
		||||
    if (dailyFiles && dailyFiles.length) {
 | 
			
		||||
      dailyFiles.forEach((logFile) => {
 | 
			
		||||
        if (Path.extname(logFile) === '.txt') {
 | 
			
		||||
          Logger.info('Daily Log file found', logFile)
 | 
			
		||||
          Logger.debug('Daily Log file found', logFile)
 | 
			
		||||
          this.dailyLogFiles.push(logFile)
 | 
			
		||||
        } else {
 | 
			
		||||
          Logger.debug(TAG, 'Unknown File in Daily log files dir', logFile)
 | 
			
		||||
@ -120,5 +121,14 @@ class LogManager {
 | 
			
		||||
    // Append log line to log file
 | 
			
		||||
    this.currentDailyLog.appendLog(logObj)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  socketRequestDailyLogs(socket) {
 | 
			
		||||
    if (!this.currentDailyLog) {
 | 
			
		||||
      return
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var lastLogs = this.currentDailyLog.logs.slice(-5000)
 | 
			
		||||
    socket.emit('daily_logs', lastLogs)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
module.exports = LogManager
 | 
			
		||||
@ -3,7 +3,7 @@ const { LogLevel } = require('./utils/constants')
 | 
			
		||||
class Logger {
 | 
			
		||||
  constructor() {
 | 
			
		||||
    this.logLevel = process.env.NODE_ENV === 'production' ? LogLevel.INFO : LogLevel.TRACE
 | 
			
		||||
    this.logFileLevel = LogLevel.INFO
 | 
			
		||||
    // this.logFileLevel = LogLevel.INFO
 | 
			
		||||
    this.socketListeners = []
 | 
			
		||||
 | 
			
		||||
    this.logManager = null
 | 
			
		||||
@ -60,7 +60,7 @@ class Logger {
 | 
			
		||||
      level
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (level >= this.logFileLevel && this.logManager) {
 | 
			
		||||
    if (level >= this.logLevel && this.logManager) {
 | 
			
		||||
      this.logManager.logToFile(logObj)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -260,6 +260,7 @@ class Server {
 | 
			
		||||
 | 
			
		||||
      // Logs
 | 
			
		||||
      socket.on('set_log_listener', (level) => Logger.addSocketListener(socket, level))
 | 
			
		||||
      socket.on('fetch_daily_logs', () => this.logManager.socketRequestDailyLogs(socket))
 | 
			
		||||
 | 
			
		||||
      // Backups
 | 
			
		||||
      socket.on('create_backup', () => this.backupManager.requestCreateBackup(socket))
 | 
			
		||||
 | 
			
		||||
@ -60,15 +60,14 @@ class DailyLog {
 | 
			
		||||
 | 
			
		||||
    var oneBigLog = ''
 | 
			
		||||
    buffered.forEach((logLine) => {
 | 
			
		||||
      oneBigLog += logLine + '\n'
 | 
			
		||||
      oneBigLog += logLine
 | 
			
		||||
    })
 | 
			
		||||
 | 
			
		||||
    this.appendLogLine(oneBigLog)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  async appendLog(logObj) {
 | 
			
		||||
    this.logs.push(logObj)
 | 
			
		||||
    var line = JSON.stringify(logObj)
 | 
			
		||||
    var line = JSON.stringify(logObj) + '\n'
 | 
			
		||||
    this.appendLogLine(line)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@ -97,16 +96,31 @@ class DailyLog {
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    var text = await readTextFile(this.fullPath)
 | 
			
		||||
 | 
			
		||||
    var hasFailures = false
 | 
			
		||||
 | 
			
		||||
    this.logs = text.split(/\r?\n/).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)
 | 
			
		||||
 | 
			
		||||
    Logger.info(`[DailyLog] ${this.id}: Loaded ${this.logs.length} Logs`)
 | 
			
		||||
    // 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
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user