blob: 84aec3aed29320783915ca35f1a3d83ef65960ad [file] [log] [blame]
'use strict';
const mailer = require('nodemailer');
const os = require('os');
/**
* SMTP Appender. Sends logging events using SMTP protocol.
* It can either send an email on each event or group several
* logging events gathered during specified interval.
*
* @param _config appender configuration data
* config.sendInterval time between log emails (in seconds), if 0
* then every event sends an email
* config.shutdownTimeout time to give up remaining emails (in seconds; defaults to 5).
* @param _layout a function that takes a logevent and returns a string (defaults to basicLayout).
*/
function smtpAppender(config, layout, subjectLayout) {
if (!config.attachment) {
config.attachment = {};
}
config.attachment.enable = !!config.attachment.enable;
config.attachment.message = config.attachment.message || 'See logs as attachment';
config.attachment.filename = config.attachment.filename || 'default.log';
const sendInterval = config.sendInterval * 1000 || 0;
const shutdownTimeout = ('shutdownTimeout' in config ? config.shutdownTimeout : 5) * 1000;
const transport = mailer.createTransport(getTransportOptions());
const logEventBuffer = [];
let unsentCount = 0;
let sendTimer;
function sendBuffer() {
if (logEventBuffer.length > 0) {
const firstEvent = logEventBuffer[0];
let body = '';
const count = logEventBuffer.length;
while (logEventBuffer.length > 0) {
body += `${layout(logEventBuffer.shift(), config.timezoneOffset)}\n`;
}
const msg = {
to: config.recipients,
subject: config.subject || subjectLayout(firstEvent),
headers: { Hostname: os.hostname() }
};
if (config.attachment.enable === true) {
msg[config.html ? 'html' : 'text'] = config.attachment.message;
msg.attachments = [
{
filename: config.attachment.filename,
contentType: 'text/x-log',
content: body
}
];
} else {
msg[config.html ? 'html' : 'text'] = body;
}
if (config.sender) {
msg.from = config.sender;
}
transport.sendMail(msg, (error) => {
if (error) {
console.error('log4js.smtpAppender - Error happened', error);
}
transport.close();
unsentCount -= count;
});
}
}
function getTransportOptions() {
let options = null;
if (config.SMTP) {
options = config.SMTP;
} else if (config.transport) {
options = config.transport.options || {};
options.transport = config.transport.plugin || 'smtp';
}
return options;
}
function scheduleSend() {
if (!sendTimer) {
sendTimer = setTimeout(() => {
sendTimer = null;
sendBuffer();
}, sendInterval);
}
}
function shutdown(cb) {
if (shutdownTimeout > 0) {
setTimeout(() => {
if (sendTimer) {
clearTimeout(sendTimer);
}
sendBuffer();
}, shutdownTimeout);
}
(function checkDone() {
if (unsentCount > 0) {
setTimeout(checkDone, 100);
} else {
cb();
}
}());
}
const appender = (loggingEvent) => {
unsentCount++; // eslint-disable-line no-plusplus
logEventBuffer.push(loggingEvent);
if (sendInterval > 0) {
scheduleSend();
} else {
sendBuffer();
}
};
appender.shutdown = shutdown;
return appender;
}
function configure(config, layouts) {
const subjectLayout = layouts.messagePassThroughLayout;
let layout = layouts.basicLayout;
if (config.layout) {
layout = layouts.layout(config.layout.type, config.layout);
}
return smtpAppender(config, layout, subjectLayout);
}
module.exports.configure = configure;