|
| 1 | +/* |
| 2 | + LoggingEnhancer can be used to enhance any logging function and can be tested without angular |
| 3 | +*/ |
| 4 | +(function() { |
| 5 | + var LoggingEnhancer = function(sprintf, moment) { |
| 6 | + var self = this; |
| 7 | + |
| 8 | + this.LEVEL = { TRACE: 4, DEBUG: 3, INFO: 2, WARN: 1, ERROR: 0, OFF: -1 }; |
| 9 | + |
| 10 | + // returns a value for testing purposes only |
| 11 | + this.enhanceLogging = function(loggingFunc, level, context, config, datetimePattern, datetimeLocale, prefixPattern) { |
| 12 | + config.logLevels = config.logLevels || []; |
| 13 | + return function() { |
| 14 | + if (levelPassesThreshold(context, level, config)) { |
| 15 | + var enhancedArguments = enhanceLogline(arguments, context, datetimePattern, datetimeLocale, prefixPattern); |
| 16 | + loggingFunc.apply(null, enhancedArguments); |
| 17 | + return enhancedArguments; |
| 18 | + } |
| 19 | + else { |
| 20 | + return null; // no log produced |
| 21 | + } |
| 22 | + }; |
| 23 | + |
| 24 | + function levelPassesThreshold(context, level, config) { |
| 25 | + return level > self.LEVEL.OFF && level <= getLogLevelThreshold(context, config); |
| 26 | + |
| 27 | + function getLogLevelThreshold(context, config) { |
| 28 | + if (context) { |
| 29 | + if (config.logLevels[context] !== undefined) { |
| 30 | + return config.logLevels[context]; |
| 31 | + } |
| 32 | + else if (context.indexOf('.') !== -1) { |
| 33 | + return getLogLevelThreshold(context.substring(0, context.lastIndexOf('.')), config); |
| 34 | + } |
| 35 | + } |
| 36 | + return config.logLevels['*'] !== undefined ? config.logLevels['*'] : self.LEVEL.TRACE; |
| 37 | + } |
| 38 | + } |
| 39 | + |
| 40 | + function enhanceLogline(args, context, datetimePattern, datetimeLocale, prefixPattern) { |
| 41 | + var prefix = generatePrefix(context, datetimePattern, datetimeLocale, prefixPattern); |
| 42 | + var processedArgs = maybeApplySprintf([].slice.call(args)); |
| 43 | + return [prefix].concat([].slice.call(processedArgs)); |
| 44 | + |
| 45 | + function maybeApplySprintf(args) { |
| 46 | + var sprintfAvailable = typeof sprintf !== 'undefined'; |
| 47 | + var sprintfCandidate = sprintfAvailable && args.length >= 2 && typeof args[0] === 'string' && args[0].indexOf('%') !== -1; |
| 48 | + if (sprintfCandidate) { |
| 49 | + try { |
| 50 | + // apply sprintf with the proper arguments |
| 51 | + var placeholderCount = self.countSprintfHolders(args[0]); |
| 52 | + if (placeholderCount > 0) { |
| 53 | + args[0] = sprintf.apply(null, args); |
| 54 | + args.splice(1, placeholderCount); // remove arguments consumed by sprintf |
| 55 | + } |
| 56 | + } |
| 57 | + catch (e) { |
| 58 | + // invalid arguments passed into sprintf, continue without applying |
| 59 | + args.unshift(e); |
| 60 | + } |
| 61 | + } |
| 62 | + |
| 63 | + return args; |
| 64 | + } |
| 65 | + } |
| 66 | + |
| 67 | + function generatePrefix(context, datetimePattern, datetimeLocale, prefixPattern) { |
| 68 | + var dateStr = ''; |
| 69 | + if (typeof moment !== 'undefined') { |
| 70 | + dateStr = moment().locale(datetimeLocale).format(datetimePattern); |
| 71 | + } |
| 72 | + else { |
| 73 | + var d = new Date(); |
| 74 | + var timeStr = new Date().toTimeString().match(/^([0-9]{2}:[0-9]{2}:[0-9]{2})/)[0]; |
| 75 | + dateStr = d.getDate() + '-' + (d.getMonth() + 1) + '-' + d.getFullYear() + ' ' + timeStr; |
| 76 | + } |
| 77 | + |
| 78 | + if (typeof sprintf !== 'undefined') { |
| 79 | + return sprintf(prefixPattern, dateStr, context); |
| 80 | + } |
| 81 | + else { |
| 82 | + // use fixed layout: '%s::[%s]> ' |
| 83 | + return dateStr + '::[' + context + ']> '; |
| 84 | + } |
| 85 | + } |
| 86 | + }; |
| 87 | + |
| 88 | + self.countSprintfHolders = function(pattern) { |
| 89 | + var hasNamedHolders = /\x25\([a-zA-Z0-9_]+\)[b-fijosuxX]/.test(pattern); |
| 90 | + if (hasNamedHolders) { |
| 91 | + return 1; |
| 92 | + } |
| 93 | + |
| 94 | + var placeholderCounter = 0; |
| 95 | + |
| 96 | + function f(index) { |
| 97 | + return function() { |
| 98 | + // keep track of highest arg index, needed for single -but indexed- placeholders placeholder (ie. %6$s consumes the first 6 arguments) |
| 99 | + placeholderCounter = Math.max(placeholderCounter, index); |
| 100 | + }; |
| 101 | + } |
| 102 | + |
| 103 | + sprintf(pattern, f(1), f(2), f(3), f(4), f(5), f(6), f(7), f(8), f(9), f(10)); |
| 104 | + return placeholderCounter; |
| 105 | + }; |
| 106 | + }; |
| 107 | + |
| 108 | + if (typeof module !== 'undefined') { |
| 109 | + module.exports.LoggingEnhancer = LoggingEnhancer; |
| 110 | + } else if (typeof exports !== 'undefined') { |
| 111 | + exports.LoggingEnhancer = LoggingEnhancer; |
| 112 | + } else if (typeof window !== 'undefined') { |
| 113 | + window.loggingEnhancer = new LoggingEnhancer(window.sprintf, window.moment); |
| 114 | + } else { |
| 115 | + throw new Error('unable to expose LoggingEnhancer: no module, exports object and no global window detected'); |
| 116 | + } |
| 117 | + |
| 118 | +})(); |
0 commit comments