Improved readability of ghost server and boot

- removed some unused code I added preivously
- refactored boot logging into a mini class for readability
This commit is contained in:
Hannah Wolfe 2021-02-16 11:54:19 +00:00
parent 481e2425af
commit d150516ec3
2 changed files with 70 additions and 54 deletions

View File

@ -10,6 +10,17 @@ require('./server/overrides');
const debug = require('ghost-ignition').debug('boot');
// END OF GLOBAL REQUIRES
class BootLogger {
constructor(logging, startTime) {
this.logging = logging;
this.startTime = startTime;
}
log(message) {
let {logging, startTime} = this;
logging.info(`Ghost ${message} in ${(Date.now() - startTime) / 1000}s`);
}
}
/**
* Get the Database into a ready state
* - DatabaseStateManager handles doing all this for us
@ -191,47 +202,50 @@ async function bootGhost() {
let ghostServer;
try {
// Config is the absolute first thing to do!
// Config must be the first thing we do, because it is required for absolutely everything
debug('Begin: Load config');
const config = require('./shared/config');
debug('End: Load config');
// Version is required by sentry & Migratior config & so is fundamental to booting
// However, it involves reading package.json, so put it here for visibility on how slow it is
// However, it involves reading package.json so its slow
// It's here for visibility on slowness
debug('Begin: Load version info');
require('./server/lib/ghost-version');
debug('End: Load version info');
// Logging is used absolutely everywhere
debug('Begin: Load logging');
const logging = require('./shared/logging');
const bootLogger = new BootLogger(logging, startTime);
debug('End: Load logging');
// Sentry must be initialised early, but requires config
debug('Begin: Load sentry');
require('./shared/sentry');
debug('End: Load sentry');
// Start server with minimal app in maintenance mode
debug('Begin: load server + minimal app');
// Get minimal application in maintenance mode
const rootApp = require('./app');
// Start server with minimal App
const GhostServer = require('./server/ghost-server');
ghostServer = new GhostServer();
await ghostServer.start(rootApp);
bootLogger.log('server started');
// @TODO: move this
ghostServer.rootApp = rootApp;
const logging = require('./shared/logging');
logging.info('Ghost server start', (Date.now() - startTime) / 1000 + 's');
debug('End: load server + minimal app');
debug('Begin: Get DB ready');
// Get the DB ready
debug('Begin: Get DB ready');
await initDatabase({config, logging});
bootLogger.log('database ready');
debug('End: Get DB ready');
// Load Ghost with all its services
debug('Begin: Load Ghost Core Services');
await initCore({ghostServer});
await initFrontend();
const ghostApp = await initExpressApps({});
await initServices({config});
debug('End: Load Ghost Core Services');
@ -239,8 +253,8 @@ async function bootGhost() {
// Mount the full Ghost app onto the minimal root app & disable maintenance mode
mountGhost(rootApp, ghostApp);
// Announce Server Readiness
logging.info('Ghost booted', (Date.now() - startTime) / 1000 + 's');
// We are technically done here
bootLogger.log('booted');
debug('boot announcing readiness');
GhostServer.announceServerReadiness();

View File

@ -52,7 +52,7 @@ class GhostServer {
};
return new Promise(function (resolve, reject) {
if (Object.prototype.hasOwnProperty.call(config.get('server'), 'socket')) {
if (_.has(config.get('server'), 'socket')) {
socketConfig = config.get('server').socket;
if (_.isString(socketConfig)) {
@ -105,38 +105,7 @@ class GhostServer {
// Debug logs output in testmode only
if (config.get('server:testmode')) {
// This is horrible and very temporary
const jobService = require('./services/jobs');
// Output how many connections are open every 5 seconds
const connectionInterval = setInterval(() => self.httpServer.getConnections(
(err, connections) => logging.warn(`${connections} connections currently open`)
), 5000);
// Output a notice when the server closes
self.httpServer.on('close', function () {
clearInterval(connectionInterval);
logging.warn('Server has fully closed');
});
// Output job queue length every 5 seconds
setInterval(() => {
logging.warn(`${jobService.queue.length()} jobs in the queue. Idle: ${jobService.queue.idle()}`);
const runningScheduledjobs = Object.keys(jobService.bree.workers);
if (Object.keys(jobService.bree.workers).length) {
logging.warn(`${Object.keys(jobService.bree.workers).length} jobs running: ${runningScheduledjobs}`);
}
const scheduledJobs = Object.keys(jobService.bree.intervals);
if (Object.keys(jobService.bree.intervals).length) {
logging.warn(`${Object.keys(jobService.bree.intervals).length} scheduled jobs: ${scheduledJobs}`);
}
if (runningScheduledjobs.length === 0 && scheduledJobs.length === 0) {
logging.warn('No scheduled or running jobs');
}
}, 5000);
self._startTestMode();
}
debug('server announcing readiness');
@ -207,6 +176,9 @@ class GhostServer {
logging.info(i18n.t('notices.httpServer.cantTouchThis'));
}
/**
* Add a task that should be called on shutdown
*/
registerCleanupTask(task) {
this.cleanupTasks.push(task);
}
@ -240,15 +212,46 @@ class GhostServer {
.all(this.cleanupTasks.map(task => task()));
}
_onShutdownComplete() {
// Wrap up
events.emit('server.stop');
this.httpServer = null;
this._logStopMessages();
/**
* Internal Method for TestMode.
*/
_startTestMode() {
// This is horrible and very temporary
const jobService = require('./services/jobs');
// Output how many connections are open every 5 seconds
const connectionInterval = setInterval(() => this.httpServer.getConnections(
(err, connections) => logging.warn(`${connections} connections currently open`)
), 5000);
// Output a notice when the server closes
this.httpServer.on('close', function () {
clearInterval(connectionInterval);
logging.warn('Server has fully closed');
});
// Output job queue length every 5 seconds
setInterval(() => {
logging.warn(`${jobService.queue.length()} jobs in the queue. Idle: ${jobService.queue.idle()}`);
const runningScheduledjobs = Object.keys(jobService.bree.workers);
if (Object.keys(jobService.bree.workers).length) {
logging.warn(`${Object.keys(jobService.bree.workers).length} jobs running: ${runningScheduledjobs}`);
}
const scheduledJobs = Object.keys(jobService.bree.intervals);
if (Object.keys(jobService.bree.intervals).length) {
logging.warn(`${Object.keys(jobService.bree.intervals).length} scheduled jobs: ${scheduledJobs}`);
}
if (runningScheduledjobs.length === 0 && scheduledJobs.length === 0) {
logging.warn('No scheduled or running jobs');
}
}, 5000);
}
/**
* ### Log Start Messages
* Log Start Messages
*/
_logStartMessages() {
logging.info(i18n.t('notices.httpServer.ghostIsRunningIn', {env: config.get('env')}));
@ -267,8 +270,7 @@ class GhostServer {
}
/**
* ### Log Stop Messages
* Private / internal API
* Log Stop Messages
*/
_logStopMessages() {
logging.warn(i18n.t('notices.httpServer.ghostHasShutdown'));