I'm trying to send an email within a simple node.js application with the log file just created using log4js. I can send an email with sendgrid, and it has an attachment, but the attachment is empty. Any help would be appreciated. Here is the app.js code:
const fs = require('fs');
require('dotenv').config();
const sub = require('./app-sub');
const log = require('./logger').logger.getLogger('app');
// Make some log entries out to console and to app.log
log.info('******************************')
log.info('Start test1')
log.info('')
log.trace("trace message")
log.debug("Some debug messages");
log.info("some info")
log.warn("a warning")
log.error("an error")
log.fatal("a fatal error")
// Call a function in another file to test
sub.sub_funct1();
log.info('')
log.info('******************************')
log.info('End test1')
// Send email with log as attachment
const sgMail = require('@sendgrid/mail');
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
// Read log file base 64
path = 'app.log';
attachment = fs.readFileSync(path, { encoding: 'base64' });
const msg = {
to: 'dgarvin57@gmail.com',
from: 'darvin57@gmail.com',
subject: 'Test email 1',
text: 'Results sent from log_test',
html: '<strong>and easy to do anywhere, even with Node.js</strong>',
attachments: [
{
content: attachment,
filename: 'app.log',
type: 'text/html', // plain/text application/pdf
disposition: 'attachment',
content_id: 'app.log'
// inline, attachment
},
],
};
sgMail.send(msg)
.then(result => { })
.catch(err => console.log(err.response.body));
and the log4js logger config in logger.js:
const log4js = require('log4js');
const level = process.env.NODE_LOGGING_LEVEL || 'debug';
log4js.configure({
appenders: {
app: { type: 'file', filename: 'app.log', flags: 'w' },
out: { type: 'stdout' },
},
categories: { default: { appenders: ['out', 'app'], level: level } }
});
module.exports.logger = log4js;
When I run it, I see the log output in the terminal and in the app.log file in the same folder as app.js:
[2019-12-25T15:43:46.677] [INFO] app - ******************************
[2019-12-25T15:43:46.679] [INFO] app - Start test1
[2019-12-25T15:43:46.680] [INFO] app -
[2019-12-25T15:43:46.688] [DEBUG] app - Some debug messages
[2019-12-25T15:43:46.689] [INFO] app - some info
[2019-12-25T15:43:46.690] [WARN] app - a warning
[2019-12-25T15:43:46.691] [ERROR] app - an error
[2019-12-25T15:43:46.691] [FATAL] app - a fatal error
[2019-12-25T15:43:46.692] [INFO] app - some info from app-sub
[2019-12-25T15:43:46.692] [INFO] app -
[2019-12-25T15:43:46.692] [INFO] app - ******************************
[2019-12-25T15:43:46.693] [INFO] app - End test1
The email is sent to my gmail account with an attachment named app.log. But when I open it, it is blank. So, not sure if I'm failing on the base64 conversion of a text file or the attachments section when sending the email. Thanks in advance.
I was able to get this to work back then and wanted to document a solution. I think the key was to shutdown the log file first, since it could not be attached when still in use. Here's the code that shuts down the log file and calls my sendEmail utility function:
log.shutown;
email.sendEmail(to, subject, body, logPath)
Here's the sendMail function:
require('dotenv').config();
const sgMail = require('@sendgrid/mail');
const fs = require('fs');
function sendEmail(to, subject, body, attachmentPath) {
// Send email with log as attachment
sgMail.setApiKey(process.env.SENDGRID_API_KEY);
const msg = {
to: to,
from: 'myEmail@gmail.com',
subject: subject,
text: 'Results:',
html: body
};
// Read log file base 64
if (attachmentPath != undefined) {
attachment = fs.readFileSync(attachmentPath, { encoding: 'base64' });
msg.attachments = [
{
content: attachment,
filename: attachmentPath,
type: 'text/plain',
disposition: 'attachment'
},
]
} else {
msg.attachments = undefined;
}
sgMail.send(msg)
.then(result => { })
.catch(err => console.log(err.response.body));
}