import winston from "winston"; import nodemailer from "nodemailer"; import TransportStream from "winston-transport"; import Mail from "nodemailer/lib/mailer"; export const logger = winston.createLogger({ level: "debug", transports: [ new winston.transports.Console({ handleExceptions: true, level: "debug", debugStdout: true, format: winston.format.combine( winston.format.splat(), winston.format.cli() ), }), ] }); process.on("unhandledRejection", (reason) => { throw reason; }); interface LogMessage { message: string; } class EmailTransport extends TransportStream { private mailer: Mail; constructor(opts?: TransportStream.TransportStreamOptions) { super(opts); this.mailer = nodemailer.createTransport({ host: "smtp.gmail.com", port: 465, secure: true, auth: { user: process.env.GMAIL_NAME, pass: process.env.GMAIL_PASSWORD } }); } log(info: LogMessage, next: () => void): void { setImmediate(() => { this.emit("logged", info); }); this.mailer.sendMail({ from: `${process.env.GMAIL_NAME}@gmail.com`, to: process.env.ERRORS_ADDR, subject: `Error at ${new Date().toISOString()}`, text: `Received error data: ${info.message}` }).catch(err => console.log(`Failed to send email! ${err}`)); next(); } } if (process.env.NODE_ENV == "production") { logger.add(new EmailTransport({ level: "error", handleExceptions: true, format: winston.format.combine( winston.format.splat(), winston.format.simple() ) })); }