1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- import * as winston from "winston";
- import * as nodemailer from "nodemailer";
- import TransportStream from "winston-transport";
- import Mail from "nodemailer/lib/mailer";
- import { hasStackTrace } from "./async_utils";
- import { inspect } from "util";
- export function createLogger(opts?: {
- errorHandler?: (reason: unknown) => Error | undefined
- }) {
- process.on("unhandledRejection", (reason) => {
- if (opts?.errorHandler) {
- const c = opts.errorHandler(reason);
- if (c !== undefined)
- throw c;
- }
- if (hasStackTrace(reason))
- throw new Error(`Unhandled rejection: ${reason}\nFull stack trace: ${reason.stack}`);
- let contents = `${reason}`;
- try {
- contents = inspect(reason, true, null);
- } catch (e) {
- // ignored
- }
- throw new Error(`Unhandled rejection: ${contents}`);
- });
- 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.prettyPrint(),
- winston.format.cli()
- ),
- }),
- ]
- });
- if (process.env.NODE_ENV == "production" && process.env.GMAIL_NAME !== undefined && process.env.GMAIL_PASSWORD !== undefined) {
- logger.add(new EmailTransport({
- level: "error",
- handleExceptions: true,
- format: winston.format.combine(
- winston.format.splat(),
- winston.format.simple()
- )
- }));
- }
- return logger;
- }
- 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();
- }
- }
|