Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | 11x 9x 1x 8x 1x 8x 8x 8x 8x 8x 8x 8x 8x 8x 8x 2x 8x 1x 1x | 'use strict'; /** * This is a wrapper for the logger provided by service runner. * It provides more user-friendly logging APIs and better error * signaling for when it is used incorrectly. * * This is the logger that other scripts in this project will interact with. * Usage: * const logger = new LoggerWrapper( <somelogger> ); * logger.log('warn', 'hello this is a message'); * logger.warn('hello this is also a message'); */ class LoggerWrapper { constructor( logger ) { this._logger = logger; } /** * Logs a message on a given severity level. * Acceptable levels: 'trace', 'debug', 'info', 'warn', 'error', and 'fatal'. * * @param {string} level Severity level using one of the level options. * Can also be: 'trace' or 'trace/request'. * * @param {Object} data Contains message and any relevant info for the log. * @param {string|undefined} data.message Log message string * @param {string|undefined} data.requestId The 'x-request-id' HTTP header, for traceability * @param {string|Object|undefined} data.info request details or JSON object */ log( level, data = { message: 'No message set!', requestId: 'No requestId set!', info: 'No info set!' } ) { // TODO (T369560): // confirm in Logstash Prod that message param is key of an object, not string; // and that is what actually gets emitted as 'message' && 'msg'; i.e. function-evaluator if ( !level || !data ) { // The service runner implementation will just silently no-op // in this situation. We want to alert the caller here. throw new Error( `Incorrect usage of the logger. Both arguments need to be present. E.g. logger.log(level, data).` ); } // temporarily adding this in case there's an undetected old version of logging somewhere if ( typeof data === 'string' ) { data = { message: data }; } // We want to output the request ID under this special name, but it's awkward. data[ 'x-request-id' ] = data.requestId; delete data.requestId; // add timestamp and stacktrace per log const timeStamp = new Date().toISOString(); data.time = timeStamp; const stackTrace = new Error().stack; const detailedStack = stackTrace.split( '\n' ).slice( 2 ).join( '\n' ); // adding compacted details to message, in case data object gets swallowed up in Logstash const simpleTrace = detailedStack.split( '\n' )[ 0 ].trim(); data.trace = simpleTrace; data.message = data.message + `, time: ${ timeStamp }, reqId: ${ data[ 'x-request-id' ] }, trace: ${ simpleTrace }`; // this is so we can easily debug/detect in docker logs if ( process.env.WIKIFUNCTIONS_DEBUG_LOCAL ) { console.log( 'Logging LEVEL:', level, ', MESSAGE:', data.message, ', DATA:', data, ', DETAILS:', detailedStack ); } this._logger.log( level, data ); } /** * Creates a child logger for a sub-component of your application. * This directly wraps its core logger obj's implementation. * * @param {*} args arguments for the child wrapper. * @return {LoggerWrapper} A new logger for the sub-component. */ child( args ) { return new LoggerWrapper( this._logger.child( args ) ); } } module.exports = { LoggerWrapper }; |