logging.ts 2.6 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import winston from "winston";
  2. import nodemailer from "nodemailer";
  3. import TransportStream from "winston-transport";
  4. import Mail from "nodemailer/lib/mailer";
  5. import { hasStackTrace, isHttpError } from "@shared/common/async_utils";
  6. import { inspect } from "util";
  7. import { HTTPError } from "got/dist/source";
  8. export const logger = winston.createLogger({
  9. level: "debug",
  10. transports: [
  11. new winston.transports.Console({
  12. handleExceptions: true,
  13. level: "debug",
  14. debugStdout: true,
  15. format: winston.format.combine(
  16. winston.format.splat(),
  17. winston.format.prettyPrint(),
  18. winston.format.cli()
  19. ),
  20. }),
  21. ]
  22. });
  23. process.on("unhandledRejection", (reason) => {
  24. if (isHttpError<HTTPError>(reason))
  25. throw new Error(`HTTPError: ${reason.request.requestUrl} failed because ${reason}\nStack trace: ${reason.stack}`);
  26. if (hasStackTrace(reason))
  27. throw new Error(`Unhandled rejection: ${reason}\nFull stack trace: ${reason.stack}`);
  28. let contents = `${reason}`;
  29. try {
  30. contents = inspect(reason, true, null);
  31. } catch (e) {
  32. // ignored
  33. }
  34. throw new Error(`Unhandled rejection: ${contents}`);
  35. });
  36. interface LogMessage {
  37. message: string;
  38. }
  39. class EmailTransport extends TransportStream {
  40. private mailer: Mail;
  41. constructor(opts?: TransportStream.TransportStreamOptions) {
  42. super(opts);
  43. console.log(`Username: ${process.env.GMAIL_NAME}`);
  44. this.mailer = nodemailer.createTransport({
  45. host: "smtp.gmail.com",
  46. port: 465,
  47. secure: true,
  48. auth: {
  49. user: process.env.GMAIL_NAME,
  50. pass: process.env.GMAIL_PASSWORD
  51. }
  52. });
  53. }
  54. log(info: LogMessage, next: () => void): void {
  55. setImmediate(() => {
  56. this.emit("logged", info);
  57. });
  58. this.mailer.sendMail({
  59. from: `${process.env.GMAIL_NAME}@gmail.com`,
  60. to: process.env.ERRORS_ADDR,
  61. subject: `Error at ${new Date().toISOString()}`,
  62. text: `Received error data: ${info.message}`
  63. }).catch(err => console.log(`Failed to send email! ${err}`));
  64. next();
  65. }
  66. }
  67. if (process.env.NODE_ENV == "production") {
  68. logger.add(new EmailTransport({
  69. level: "error",
  70. handleExceptions: true,
  71. format: winston.format.combine(
  72. winston.format.splat(),
  73. winston.format.simple()
  74. )
  75. }));
  76. }