UNPKG

@lexamica-modules/logger

Version:

The various loggers and transports used for API logging in the Lexamica Eco-system

344 lines (326 loc) 9.9 kB
import { format } from 'logform'; import { isDevelopment, isProduction, isStaging } from './environment'; import winston from 'winston'; import { getFormat } from './formatting'; import SlackTransport from 'winston-slack-webhook-transport'; import DataDogTransport from '@shelf/winston-datadog-logs-transport'; export interface ICreateLoggerEnvironmentOptions { development?: { slack_webhook?: string; }; staging?: { slack_webhook?: string; }; } interface ICreateLoggerOptions { route?: ICreateLoggerEnvironmentOptions; task?: ICreateLoggerEnvironmentOptions; user?: ICreateLoggerEnvironmentOptions; integration?: ICreateLoggerEnvironmentOptions; auth?: ICreateLoggerEnvironmentOptions; } /** * * @param dataDogApiKey {string} * @param service {string} * @param defaultLevel { "silly" |'debug" |"verbose" | "info" | "warning" | "error" | } * @param environment { string } * @param formatType {"color" | "json" } * @param consoleParams { winston.ConsoleTransportOptions } * @param loggerParams { winston.LoggerOptions } * @return {winston.Logger} */ function createLogger({ dataDogApiKey, service, defaultLevel = 'info', environment, formatType = 'json', requireConsoleTransport = false, requireDataDogTransport = false, consoleParams, loggerParams, metadata = {}, slackWebhook, slackLogLevel, options, }: { dataDogApiKey: string; service: string; defaultLevel?: 'verbose' | 'info' | 'warn' | 'error'; environment: string; formatType?: 'color' | 'json'; requireConsoleTransport?: boolean; requireDataDogTransport?: boolean; consoleParams: Record<string, unknown>; loggerParams: Record<string, unknown>; metadata?: Record<string, string>; slackWebhook?: string; slackLogLevel?: 'verbose' | 'info' | 'warn' | 'error'; options?: ICreateLoggerEnvironmentOptions; }): winston.Logger { if ( !dataDogApiKey && (!isDevelopment(environment) || requireDataDogTransport) ) { throw new Error( `Must provide a dataDogApiKey for logger in staging, demo, and production environments` ); } const transports = []; if (isDevelopment(environment) || requireConsoleTransport) { transports.push( new winston.transports.Console({ ...consoleParams, handleExceptions: true, }) ); } if (isProduction(environment) && !!slackWebhook) { const transport = new SlackTransport({ webhookUrl: slackWebhook, level: slackLogLevel ?? 'info', }); transports.push(transport); } if (isDevelopment(environment) && !!options?.development?.slack_webhook) { const transport = new SlackTransport({ webhookUrl: options.development.slack_webhook, level: slackLogLevel ?? 'info', }); transports.push(transport); } if (isStaging(environment) && !!options?.staging?.slack_webhook) { const transport = new SlackTransport({ webhookUrl: options.staging.slack_webhook, level: slackLogLevel ?? 'info', }); transports.push(transport); } if (!isDevelopment(environment) || requireDataDogTransport) { transports.push( new DataDogTransport({ apiKey: dataDogApiKey, metadata: { ...metadata, service, ddsource: `node:${process.version ?? '0.0.0'}`, host: `${service}:${environment}`, environment, }, }) ); } return winston.createLogger({ format: getFormat(formatType), level: defaultLevel || 'info', exitOnError: false, ...loggerParams, transports, }); } /** * Logger initialization function * @param datadog_key the API key to connect to datadog via transporter * @param service a service string. Typically an API name or some other id * @param environment the usage environment. Use the NODE_ENV env var * @param slack_webhook give the webook url to transport these logs to a slack channel * @returns {winston.Logger} */ export const authLogger = ( datadog_key: string, service: string, environment: string, slack_webhook: string, defaultLevel: 'verbose' | 'info' | 'warn' | 'error', options?: ICreateLoggerEnvironmentOptions ) => createLogger({ service: `${service}/auth`, dataDogApiKey: datadog_key, defaultLevel, environment: environment, consoleParams: isDevelopment(environment) ? { format: format.printf(({ message }) => message), } : {}, loggerParams: {}, slackWebhook: slack_webhook, options, }); /** * Logger initialization function * @param datadog_key the API key to connect to datadog via transporter * @param service a service string. Typically an API name or some other id * @param environment the usage environment. Use the NODE_ENV env var * @param slack_webhook give the webook url to transport these logs to a slack channel * @returns {winston.Logger} */ export const taskLogger = ( datadog_key: string, service: string, environment: string, slack_webhook: string, defaultLevel: 'verbose' | 'info' | 'warn' | 'error', options?: ICreateLoggerEnvironmentOptions ) => createLogger({ service: `${service}/tasks`, dataDogApiKey: datadog_key, defaultLevel, environment: environment, consoleParams: isDevelopment(environment) ? { format: format.printf(({ message }) => message), } : {}, loggerParams: {}, slackWebhook: slack_webhook, options, }); /** * Logger initialization function * @param datadog_key the API key to connect to datadog via transporter * @param service a service string. Typically an API name or some other id * @param environment the usage environment. Use the NODE_ENV env var * @param slack_webhook give the webook url to transport these logs to a slack channel * @returns {winston.Logger} */ export const userLogger = ( datadog_key: string, service: string, environment: string, slack_webhook: string, defaultLevel: 'verbose' | 'info' | 'warn' | 'error', options?: ICreateLoggerEnvironmentOptions ) => createLogger({ service: `${service}/users`, dataDogApiKey: datadog_key, defaultLevel, environment: environment, consoleParams: isDevelopment(environment) ? { format: format.printf(({ message }) => message), } : {}, loggerParams: {}, slackWebhook: slack_webhook, options, }); /** * Logger initialization function * @param datadog_key the API key to connect to datadog via transporter * @param service a service string. Typically an API name or some other id * @param environment the usage environment. Use the NODE_ENV env var * @param slack_webhook give the webook url to transport these logs to a slack channel * @returns {winston.Logger} */ export const integrationLogger = ( datadog_key: string, service: string, environment: string, slack_webhook: string, defaultLevel: 'verbose' | 'info' | 'warn' | 'error', options?: ICreateLoggerEnvironmentOptions ) => createLogger({ service: `${service}/integrations`, dataDogApiKey: datadog_key, defaultLevel, environment: environment, consoleParams: isDevelopment(environment) ? { format: format.printf(({ message }) => message), } : {}, loggerParams: {}, slackWebhook: slack_webhook, options, }); /** * Logger initialization function * @param datadog_key the API key to connect to datadog via transporter * @param service a service string. Typically an API name or some other id * @param environment the usage environment. Use the NODE_ENV env var * @returns {winston.Logger} */ export const routeLogger = ( datadog_key: string, service: string, environment: string, defaultLevel: 'verbose' | 'info' | 'warn' | 'error', options?: ICreateLoggerEnvironmentOptions ) => createLogger({ service: `${service}/routes`, dataDogApiKey: datadog_key, defaultLevel, environment: environment, consoleParams: isDevelopment(environment) ? { format: format.printf(({ message }) => message), } : {}, loggerParams: {}, options, }); export class Loggers { RouteLogger: winston.Logger; TaskLogger: winston.Logger; UserLogger: winston.Logger; IntegrationLogger: winston.Logger; AuthLogger: winston.Logger; constructor( datadog_api_key: string, service: string, environment: 'development' | 'staging' | 'demo' | 'production', slack_user_logs_webhook: string, slack_task_logs_webhook: string, slack_auth_logs_webhook: string, slack_integration_logs_webhook: string, defaultLevel: 'verbose' | 'info' | 'warn' | 'error' = 'info', options: ICreateLoggerOptions = {} ) { this.RouteLogger = routeLogger( datadog_api_key, service, environment, defaultLevel, options.route ); this.TaskLogger = taskLogger( datadog_api_key, service, environment, slack_task_logs_webhook, defaultLevel, options.task ); this.UserLogger = userLogger( datadog_api_key, service, environment, slack_user_logs_webhook, defaultLevel, options.user ); this.IntegrationLogger = integrationLogger( datadog_api_key, service, environment, slack_integration_logs_webhook, defaultLevel, options.integration ); this.AuthLogger = authLogger( datadog_api_key, service, environment, slack_auth_logs_webhook, defaultLevel, options.auth ); } }