From 19b4a5e217e2a7c428db55db5fbcfba1896bc1c0 Mon Sep 17 00:00:00 2001 From: Bobby Wibowo Date: Sat, 2 May 2020 19:28:13 +0700 Subject: [PATCH] Updated Linux-only disk stats Restore disk usage stats even when config.linuxDiskStats is off The said config will now only toggle the 'extended' stats which are disk usage of each directories within the uploads directory --- config.sample.js | 4 +- controllers/utilsController.js | 128 +++++++++++++++++---------------- 2 files changed, 67 insertions(+), 65 deletions(-) diff --git a/config.sample.js b/config.sample.js index 67aee42..42ef30f 100644 --- a/config.sample.js +++ b/config.sample.js @@ -487,8 +487,8 @@ module.exports = { cacheControl: false, /* - Enable Linux-only disk stats in Dashboard's Statistics. - This will use a combination of both "du" and "df" binaries. + Enable Linux-only extended disk stats in Dashboard's Statistics. + This will use "du" binary to query disk usage of each directories within uploads directory. Disabled by default as I personally found it to be very slow with +100k uploads with my ancient potato server. */ diff --git a/controllers/utilsController.js b/controllers/utilsController.js index 51059c8..5b30243 100644 --- a/controllers/utilsController.js +++ b/controllers/utilsController.js @@ -41,6 +41,11 @@ const statsCache = { generating: false, generatedAt: 0 }, + disk: { + cache: null, + generating: false, + generatedAt: 0 + }, albums: { cache: null, generating: false, @@ -61,13 +66,6 @@ const statsCache = { } } -if (config.linuxDiskStats) - statsCache.disk = { - cache: null, - generating: false, - generatedAt: 0 - } - const cloudflareAuth = config.cloudflare && config.cloudflare.apiKey && config.cloudflare.email && config.cloudflare.zoneId @@ -631,7 +629,7 @@ self.stats = async (req, res, next) => { } // Disk usage, only for Linux platform - if (config.linuxDiskStats && os.platform === 'linux') + if (os.platform === 'linux') if (!statsCache.disk.cache && statsCache.disk.generating) { stats.disk = false } else if (((Date.now() - statsCache.disk.generatedAt) <= 60000) || statsCache.disk.generating) { @@ -643,78 +641,48 @@ self.stats = async (req, res, next) => { stats.disk = { _types: { - byte: ['uploads', 'thumbs', 'zips', 'chunks'], byteUsage: ['drive'] }, - drive: null, - // We pre-assign the keys below to fix their order - uploads: 0, - thumbs: 0, - zips: 0, - chunks: 0 + drive: null } - const subdirs = [] + // Linux-only extended disk stats + if (config.linuxDiskStats) { + // We pre-assign the keys below to fix their order + stats.disk._types.byte = ['uploads', 'thumbs', 'zips', 'chunks'] + stats.disk.uploads = 0 + stats.disk.thumbs = 0 + stats.disk.zips = 0 + stats.disk.chunks = 0 - // Get size of uploads path (excluding sub-directories) - await new Promise((resolve, reject) => { - const proc = spawn('du', [ - '--apparent-size', - '--block-size=1', - '--dereference', - '--max-depth=1', - '--separate-dirs', - paths.uploads - ]) + const subdirs = [] - proc.stdout.on('data', data => { - const formatted = String(data) - .trim() - .split(/\s+/) - for (let i = 0; i < formatted.length; i += 2) { - const path = formatted[i + 1] - if (!path) return - - if (path !== paths.uploads) { - subdirs.push(path) - continue - } - - stats.disk.uploads = parseInt(formatted[i]) - } - }) - - const stderr = [] - proc.stderr.on('data', data => stderr.push(String(data))) - - proc.on('exit', code => { - if (code !== 0) return reject(stderr) - resolve() - }) - }) - - await Promise.all(subdirs.map(subdir => { - return new Promise((resolve, reject) => { + // Get size of uploads path (excluding sub-directories) + await new Promise((resolve, reject) => { const proc = spawn('du', [ '--apparent-size', '--block-size=1', '--dereference', - '--summarize', - subdir + '--max-depth=1', + '--separate-dirs', + paths.uploads ]) proc.stdout.on('data', data => { const formatted = String(data) .trim() .split(/\s+/) - if (formatted.length !== 2) return + for (let i = 0; i < formatted.length; i += 2) { + const path = formatted[i + 1] + if (!path) return - const basename = path.basename(formatted[1]) - stats.disk[basename] = parseInt(formatted[0]) + if (path !== paths.uploads) { + subdirs.push(path) + continue + } - // Add to types if necessary - if (!stats.disk._types.byte.includes(basename)) - stats.disk._types.byte.push(basename) + stats.disk.uploads = parseInt(formatted[i]) + } }) const stderr = [] @@ -725,7 +693,41 @@ self.stats = async (req, res, next) => { resolve() }) }) - })) + + await Promise.all(subdirs.map(subdir => { + return new Promise((resolve, reject) => { + const proc = spawn('du', [ + '--apparent-size', + '--block-size=1', + '--dereference', + '--summarize', + subdir + ]) + + proc.stdout.on('data', data => { + const formatted = String(data) + .trim() + .split(/\s+/) + if (formatted.length !== 2) return + + const basename = path.basename(formatted[1]) + stats.disk[basename] = parseInt(formatted[0]) + + // Add to types if necessary + if (!stats.disk._types.byte.includes(basename)) + stats.disk._types.byte.push(basename) + }) + + const stderr = [] + proc.stderr.on('data', data => stderr.push(String(data))) + + proc.on('exit', code => { + if (code !== 0) return reject(stderr) + resolve() + }) + }) + })) + } // Get disk usage of whichever disk uploads path resides on await new Promise((resolve, reject) => {