Mwalker has uploaded a new change for review. https://gerrit.wikimedia.org/r/148738
Change subject: Add path and size information to health check ...................................................................... Add path and size information to health check TODO: This has just revealed a horrible problem with the config object; in that the defaults are computed in the backgrond thread which is a separate process from the frontend -- meaning the frontend has no clue what the backend did to the config options. Solution: always set paths statically in the config file... Change-Id: Icd8c6d43eb1ba57b75b70c3d63c14212a4f3ea8a --- M lib/threads/frontend.js 1 file changed, 82 insertions(+), 35 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/Collection/OfflineContentGenerator refs/changes/38/148738/1 diff --git a/lib/threads/frontend.js b/lib/threads/frontend.js index 1400c6b..e9fea68 100644 --- a/lib/threads/frontend.js +++ b/lib/threads/frontend.js @@ -30,6 +30,7 @@ var fs = require( 'fs' ); var http = require( 'http' ); var mime = require( 'mime' ); +var path = require( 'path' ); var url = require( 'url' ); var util = require( 'util' ); @@ -290,43 +291,60 @@ * @param response */ function handleHealthCheck( requestId, args, response ) { - var responseAry = {}; + var responseAry = { + 'host': config.coordinator.hostname, + 'directories': { + 'temp': { path: config.backend.temp_dir, size: 0 }, + 'output': { path: config.backend.output_dir, size: 0 }, + 'postmortem': { path: config.backend.post_mortem_dir, size: 0 } + } + }; - return redisClient - .llen( config.redis.job_queue_name ) - .then( function( len ) { - responseAry.JobQueue = { - name: config.redis.job_queue_name, - length: len - }; - } ).then( function() { - return redisClient.hlen( config.redis.status_set_name ); - } ).then( function( len ) { - responseAry.StatusObjects = { - name: config.redis.status_set_name, - length: len - }; - } ).then( function() { - // Add a time to the response so we know it's current - responseAry.time = Date.now(); - response.writeHead( 200, "OK" ); - response.write( JSON.stringify( responseAry ) ); - response.end(); - } ).then( function() { - statsd.gauge( 'job_queue_length', responseAry.JobQueue.length ); - statsd.gauge( 'status_objects', responseAry.StatusObjects.length ); - } ).catch( function( err ) { - console.error( - 'Health failed with error: %s', - err, - { - channel: 'frontend.error', - error: eh.jsonify( err ), - request: { id: requestId } - } - ); - throw new FrontendError( 'Status check failed (redis failure?)', 500 ); + var resolveSize = function ( node ) { + return Promise.resolve( getFolderSize( node.path ) ).then( function( size ) { + node.size = size; } ); + }; + + return Promise.all( [ + resolveSize( responseAry.directories.temp ), + resolveSize( responseAry.directories.output ), + resolveSize( responseAry.directories.postmortem ), + ] ).then( function() { + return redisClient.llen( config.redis.job_queue_name ) + } ).then( function( len ) { + responseAry.JobQueue = { + name: config.redis.job_queue_name, + length: len + }; + } ).then( function() { + return redisClient.hlen( config.redis.status_set_name ); + } ).then( function( len ) { + responseAry.StatusObjects = { + name: config.redis.status_set_name, + length: len + }; + } ).then( function() { + // Add a time to the response so we know it's current + responseAry.time = Date.now(); + response.writeHead( 200, "OK" ); + response.write( JSON.stringify( responseAry ) ); + response.end(); + } ).then( function() { + statsd.gauge( 'job_queue_length', responseAry.JobQueue.length ); + statsd.gauge( 'status_objects', responseAry.StatusObjects.length ); + } ).catch( function( err ) { + console.error( + 'Health failed with error: %s', + err, + { + channel: 'frontend.error', + error: eh.jsonify( err ), + request: { id: requestId } + } + ); + throw new FrontendError( 'Status check failed (redis failure?)', 500 ); + } ); } /** @@ -637,6 +655,35 @@ } /** + * Obtain the size in bytes of all the contents of a folder + * @param {string} fspath - File system path + * @returns {int} Size in bytes of the folder + */ +function getFolderSize( fspath ) { + var lstat = Promise.promisify( fs.lstat, false, fs ); + var readdir = Promise.promisify( fs.readdir, false, fs ); + + if ( !fspath ) { + return 0; + } + + return lstat( fspath ).then( function( stat ) { + if ( stat.isDirectory() ) { + return readdir( fspath ).map( function( item ) { + return getFolderSize( path.join( fspath, item ) ); + } ).then( function ( sizes ) { + return sizes.reduce( function( prev, current ) { return prev + current; }, 0 ); + } ); + } else { + return stat.size; + } + } ).catch( function( err ) { + console.warn( "Could not find size of '%s': %s", fspath, err ); + return 0; + } ); +} + +/** * HTTP error analogue; throw and code will be returned to HTTP client * * @param {string} message - Message that will be logged -- To view, visit https://gerrit.wikimedia.org/r/148738 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: Icd8c6d43eb1ba57b75b70c3d63c14212a4f3ea8a Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/Collection/OfflineContentGenerator Gerrit-Branch: master Gerrit-Owner: Mwalker <mwal...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits