feat(pm2): got pm2 working, needs tests

This commit is contained in:
Gareth Jones 2017-07-18 22:42:06 +10:00
parent c2f1d7bf5d
commit 84ab47d6e5
3 changed files with 40 additions and 16 deletions

View File

@ -76,7 +76,7 @@ class Configuration {
debug(`DEPRECATION: Appender ${config.type} exports a shutdown function.`);
}
if (cluster.isMaster) {
if (cluster.isMaster || (this.pm2 && process.env[this.pm2InstanceVar] === '0')) {
return appenderModule.configure(
config,
layouts,
@ -195,6 +195,9 @@ class Configuration {
this.throwExceptionIf(not(anObject(candidate.appenders)), 'must have a property "appenders" of type object.');
this.throwExceptionIf(not(anObject(candidate.categories)), 'must have a property "categories" of type object.');
this.pm2 = this.candidate.pm2;
this.pm2InstanceVar = this.candidate.pm2InstanceVar || 'NODE_APP_INSTANCE';
this.levels = candidate.levels;
this.appenders = candidate.appenders;
this.categories = candidate.categories;

View File

@ -139,7 +139,7 @@ function sendLogEventToAppender(logEvent) {
function workerDispatch(logEvent) {
debug(`sending message to master from worker ${process.pid}`);
process.send({ type: '::log4js-message', event: serialise(logEvent) });
process.send({ topic: 'log4js:message', data: serialise(logEvent) });
}
/**
@ -162,6 +162,21 @@ function loadConfigurationFile(filename) {
return filename;
}
// in a multi-process node environment, worker loggers will use
// process.send
const receiver = (worker, message) => {
// prior to node v6, the worker parameter was not passed (args were message, handle)
debug('cluster message received from worker ', worker, ': ', message);
if (worker.topic && worker.data) {
message = worker;
worker = undefined;
}
if (message && message.topic && message.topic === 'log4js:message') {
debug('received message: ', message.data);
sendLogEventToAppender(deserialise(message.data));
}
};
function configure(configurationFileOrObject) {
let configObject = configurationFileOrObject;
@ -175,6 +190,15 @@ function configure(configurationFileOrObject) {
Logger = loggerModule.Logger;
LoggingEvent = loggerModule.LoggingEvent;
module.exports.connectLogger = connectModule(config.levels).connectLogger;
// PM2 cluster support
// PM2 runs everything as workers - install pm2-intercom for this to work.
// we only want one of the app instances to write logs
if (config.pm2 && process.env[config.pm2InstanceVar] === '0') {
debug('listening for PM2 broadcast messages');
process.on('message', receiver);
}
enabled = true;
}
@ -236,20 +260,7 @@ const log4js = {
module.exports = log4js;
// in a multi-process node environment, worker loggers will use
// process.send
cluster.on('message', (worker, message) => {
// prior to node v6, the worker parameter was not passed (args were message, handle)
debug('cluster message received from worker ', worker, ': ', message);
if (worker.type && worker.event) {
message = worker;
worker = undefined;
}
if (message && message.type && message.type === '::log4js-message') {
debug('received message: ', message.event);
sendLogEventToAppender(deserialise(message.event));
}
});
cluster.on('message', receiver);
// set ourselves up
configure(process.env.LOG4JS_CONFIG || defaultConfig);

View File

@ -0,0 +1,10 @@
'use strict';
const test = require('tap').test;
test('PM2 Cluster support', (batch) => {
batch.test('should listen for messages if pm2 support enabled');
batch.test('should write messages on NODE_APP_INSTANCE - 0');
batch.test('should send messages with the correct format');
batch.end();
});