create-logger.js 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. /**
  2. * create-logger.js: Logger factory for winston logger instances.
  3. *
  4. * (C) 2010 Charlie Robbins
  5. * MIT LICENCE
  6. */
  7. 'use strict';
  8. const { LEVEL } = require('triple-beam');
  9. const config = require('./config');
  10. const Logger = require('./logger');
  11. const debug = require('diagnostics')('winston:create-logger');
  12. /**
  13. * DerivedLogger to attach the logs level methods.
  14. * @type {DerivedLogger}
  15. * @extends {Logger}
  16. */
  17. class DerivedLogger extends Logger {
  18. /**
  19. * Create a new class derived logger for which the levels can be attached to
  20. * the prototype of. This is a V8 optimization that is well know to increase
  21. * performance of prototype functions.
  22. * @param {!Object} options - Options for the created logger.
  23. */
  24. constructor(options) {
  25. super(options);
  26. this._setupLevels();
  27. }
  28. /**
  29. * Create the log level methods for the derived logger.
  30. * @returns {undefined}
  31. * @private
  32. */
  33. _setupLevels() {
  34. Object.keys(this.levels).forEach(level => {
  35. debug('Define prototype method for "%s"', level);
  36. if (level === 'log') {
  37. // eslint-disable-next-line no-console
  38. console.warn('Level "log" not defined: conflicts with the method "log". Use a different level name.');
  39. return;
  40. }
  41. // Define prototype methods for each log level
  42. // e.g. logger.log('info', msg) <––> logger.info(msg) & logger.isInfoEnabled()
  43. this[level] = (...args) => {
  44. // Optimize the hot-path which is the single object.
  45. if (args.length === 1) {
  46. const [msg] = args;
  47. const info = msg && msg.message && msg || { message: msg };
  48. info.level = info[LEVEL] = level;
  49. this.write(info);
  50. return this;
  51. }
  52. // Otherwise build argument list which could potentially conform to
  53. // either:
  54. // . v3 API: log(obj)
  55. // 2. v1/v2 API: log(level, msg, ... [string interpolate], [{metadata}], [callback])
  56. return this.log(level, ...args);
  57. };
  58. this[isLevelEnabledFunctionName(level)] = () => this.isLevelEnabled(level);
  59. });
  60. }
  61. }
  62. function isLevelEnabledFunctionName(level) {
  63. return 'is' + level.charAt(0).toUpperCase() + level.slice(1) + 'Enabled';
  64. }
  65. /**
  66. * Create a new instance of a winston Logger. Creates a new
  67. * prototype for each instance.
  68. * @param {!Object} opts - Options for the created logger.
  69. * @returns {Logger} - A newly created logger instance.
  70. */
  71. module.exports = (opts = { levels: config.npm.levels }) => (
  72. new DerivedLogger(opts)
  73. );