logger.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. 'use strict';
  2. var f = require('util').format,
  3. MongoError = require('../error').MongoError;
  4. // Filters for classes
  5. var classFilters = {};
  6. var filteredClasses = {};
  7. var level = null;
  8. // Save the process id
  9. var pid = process.pid;
  10. // current logger
  11. var currentLogger = null;
  12. /**
  13. * Creates a new Logger instance
  14. * @class
  15. * @param {string} className The Class name associated with the logging instance
  16. * @param {object} [options=null] Optional settings.
  17. * @param {Function} [options.logger=null] Custom logger function;
  18. * @param {string} [options.loggerLevel=error] Override default global log level.
  19. * @return {Logger} a Logger instance.
  20. */
  21. var Logger = function(className, options) {
  22. if (!(this instanceof Logger)) return new Logger(className, options);
  23. options = options || {};
  24. // Current reference
  25. this.className = className;
  26. // Current logger
  27. if (options.logger) {
  28. currentLogger = options.logger;
  29. } else if (currentLogger == null) {
  30. currentLogger = console.log;
  31. }
  32. // Set level of logging, default is error
  33. if (options.loggerLevel) {
  34. level = options.loggerLevel || 'error';
  35. }
  36. // Add all class names
  37. if (filteredClasses[this.className] == null) classFilters[this.className] = true;
  38. };
  39. /**
  40. * Log a message at the debug level
  41. * @method
  42. * @param {string} message The message to log
  43. * @param {object} object additional meta data to log
  44. * @return {null}
  45. */
  46. Logger.prototype.debug = function(message, object) {
  47. if (
  48. this.isDebug() &&
  49. ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className]) ||
  50. (Object.keys(filteredClasses).length === 0 && classFilters[this.className]))
  51. ) {
  52. var dateTime = new Date().getTime();
  53. var msg = f('[%s-%s:%s] %s %s', 'DEBUG', this.className, pid, dateTime, message);
  54. var state = {
  55. type: 'debug',
  56. message: message,
  57. className: this.className,
  58. pid: pid,
  59. date: dateTime
  60. };
  61. if (object) state.meta = object;
  62. currentLogger(msg, state);
  63. }
  64. };
  65. /**
  66. * Log a message at the warn level
  67. * @method
  68. * @param {string} message The message to log
  69. * @param {object} object additional meta data to log
  70. * @return {null}
  71. */
  72. (Logger.prototype.warn = function(message, object) {
  73. if (
  74. this.isWarn() &&
  75. ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className]) ||
  76. (Object.keys(filteredClasses).length === 0 && classFilters[this.className]))
  77. ) {
  78. var dateTime = new Date().getTime();
  79. var msg = f('[%s-%s:%s] %s %s', 'WARN', this.className, pid, dateTime, message);
  80. var state = {
  81. type: 'warn',
  82. message: message,
  83. className: this.className,
  84. pid: pid,
  85. date: dateTime
  86. };
  87. if (object) state.meta = object;
  88. currentLogger(msg, state);
  89. }
  90. }),
  91. /**
  92. * Log a message at the info level
  93. * @method
  94. * @param {string} message The message to log
  95. * @param {object} object additional meta data to log
  96. * @return {null}
  97. */
  98. (Logger.prototype.info = function(message, object) {
  99. if (
  100. this.isInfo() &&
  101. ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className]) ||
  102. (Object.keys(filteredClasses).length === 0 && classFilters[this.className]))
  103. ) {
  104. var dateTime = new Date().getTime();
  105. var msg = f('[%s-%s:%s] %s %s', 'INFO', this.className, pid, dateTime, message);
  106. var state = {
  107. type: 'info',
  108. message: message,
  109. className: this.className,
  110. pid: pid,
  111. date: dateTime
  112. };
  113. if (object) state.meta = object;
  114. currentLogger(msg, state);
  115. }
  116. }),
  117. /**
  118. * Log a message at the error level
  119. * @method
  120. * @param {string} message The message to log
  121. * @param {object} object additional meta data to log
  122. * @return {null}
  123. */
  124. (Logger.prototype.error = function(message, object) {
  125. if (
  126. this.isError() &&
  127. ((Object.keys(filteredClasses).length > 0 && filteredClasses[this.className]) ||
  128. (Object.keys(filteredClasses).length === 0 && classFilters[this.className]))
  129. ) {
  130. var dateTime = new Date().getTime();
  131. var msg = f('[%s-%s:%s] %s %s', 'ERROR', this.className, pid, dateTime, message);
  132. var state = {
  133. type: 'error',
  134. message: message,
  135. className: this.className,
  136. pid: pid,
  137. date: dateTime
  138. };
  139. if (object) state.meta = object;
  140. currentLogger(msg, state);
  141. }
  142. }),
  143. /**
  144. * Is the logger set at info level
  145. * @method
  146. * @return {boolean}
  147. */
  148. (Logger.prototype.isInfo = function() {
  149. return level === 'info' || level === 'debug';
  150. }),
  151. /**
  152. * Is the logger set at error level
  153. * @method
  154. * @return {boolean}
  155. */
  156. (Logger.prototype.isError = function() {
  157. return level === 'error' || level === 'info' || level === 'debug';
  158. }),
  159. /**
  160. * Is the logger set at error level
  161. * @method
  162. * @return {boolean}
  163. */
  164. (Logger.prototype.isWarn = function() {
  165. return level === 'error' || level === 'warn' || level === 'info' || level === 'debug';
  166. }),
  167. /**
  168. * Is the logger set at debug level
  169. * @method
  170. * @return {boolean}
  171. */
  172. (Logger.prototype.isDebug = function() {
  173. return level === 'debug';
  174. });
  175. /**
  176. * Resets the logger to default settings, error and no filtered classes
  177. * @method
  178. * @return {null}
  179. */
  180. Logger.reset = function() {
  181. level = 'error';
  182. filteredClasses = {};
  183. };
  184. /**
  185. * Get the current logger function
  186. * @method
  187. * @return {function}
  188. */
  189. Logger.currentLogger = function() {
  190. return currentLogger;
  191. };
  192. /**
  193. * Set the current logger function
  194. * @method
  195. * @param {function} logger Logger function.
  196. * @return {null}
  197. */
  198. Logger.setCurrentLogger = function(logger) {
  199. if (typeof logger !== 'function') throw new MongoError('current logger must be a function');
  200. currentLogger = logger;
  201. };
  202. /**
  203. * Set what classes to log.
  204. * @method
  205. * @param {string} type The type of filter (currently only class)
  206. * @param {string[]} values The filters to apply
  207. * @return {null}
  208. */
  209. Logger.filter = function(type, values) {
  210. if (type === 'class' && Array.isArray(values)) {
  211. filteredClasses = {};
  212. values.forEach(function(x) {
  213. filteredClasses[x] = true;
  214. });
  215. }
  216. };
  217. /**
  218. * Set the current log level
  219. * @method
  220. * @param {string} level Set current log level (debug, info, error)
  221. * @return {null}
  222. */
  223. Logger.setLevel = function(_level) {
  224. if (_level !== 'info' && _level !== 'error' && _level !== 'debug' && _level !== 'warn') {
  225. throw new Error(f('%s is an illegal logging level', _level));
  226. }
  227. level = _level;
  228. };
  229. module.exports = Logger;