UNPKG

mongoose-execution-time

Version:

Mongoose plugin for measuring and logging query execution time

139 lines (111 loc) 3.47 kB
export interface LogExecutionTimeConfig { logger?: any; loggerLevel?: string; loggerVerbosity?: LoggerVerbosity, loggerFunction?: LoggerFunction } export enum LoggerVerbosity { Normal, High } type LoggerFunction = ( operation: string, collectionName: string, executionTimeMS: number, filter: Object | null, update: Object | null, additionalLogProperties: any, aggregationPipeline?: Array<Object> | null | undefined, ) => void; let logger : any = console; let loggerLevel: string = 'debug'; let loggerVerbosity : LoggerVerbosity = LoggerVerbosity.High; let loggerFunction : LoggerFunction = defaultLoggingFunction; export function logExecutionTime (targetSchema : any, config ?: LogExecutionTimeConfig) { targetSchema.query.additionalLogProperties = function(additionalProperties: Object | string | number | boolean) { this.__additionalProperties = additionalProperties; return this; }; if(!config) { config = {} as LogExecutionTimeConfig; } if(config.logger) { logger = config.logger; } if(config.loggerLevel) { loggerLevel = config.loggerLevel; } if(config.loggerVerbosity != null) { loggerVerbosity = config.loggerVerbosity; } if(config.loggerFunction) { loggerFunction = config.loggerFunction; } const targetMethods = [ 'find', 'findOne', 'count', 'countDocuments', 'estimatedDocumentCount', 'findOneAndUpdate', 'findOneAndRemove', 'findOneAndDelete', 'deleteOne', 'deleteMany', 'remove', 'aggregate', ] targetMethods.forEach( method => { targetSchema.pre(method, preQueryHook); targetSchema.post(method, postQueryHook); }) } function preQueryHook() { // @ts-ignore this.__startTime = Date.now(); } function postQueryHook() { // @ts-ignore const target = this; if (target.__startTime != null) { const op = target.constructor.name === 'Aggregate' ? 'aggregate' : target.op; const collectionName = target._collection ? target._collection.collectionName : target._model.collection.collectionName; loggerFunction( op, collectionName, Date.now() - target.__startTime, target._conditions, target._update, target.__additionalProperties, target._pipeline ) } } function defaultLoggingFunction( operation: string, collectionName: string, executionTimeMS: number, filter: Object | null, update: Object | null, additionalLogProperties: any, aggregationPipeline: Array<Object> | null | undefined) { let logProperties: any = null; if(loggerVerbosity == LoggerVerbosity.High) { logProperties = {} if(filter) { logProperties.filter = filter } if(update) { logProperties.update = update } if(aggregationPipeline) { logProperties.aggregationPipeline = JSON.stringify(aggregationPipeline) } } if(additionalLogProperties) { logProperties = logProperties ? { ...logProperties, additionalLogProperties } : { additionalLogProperties } } logger[loggerLevel](`Query: ${operation} in ${collectionName} completed in: ${executionTimeMS} ms`, logProperties) }