logger.js 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /* eslint no-underscore-dangle:0 */
  2. 'use strict';
  3. const debug = require('debug')('log4js:logger');
  4. const LoggingEvent = require('./LoggingEvent');
  5. const levels = require('./levels');
  6. const clustering = require('./clustering');
  7. const categories = require('./categories');
  8. const configuration = require('./configuration');
  9. const stackReg = /at (?:(.+)\s+\()?(?:(.+?):(\d+)(?::(\d+))?|([^)]+))\)?/;
  10. function defaultParseCallStack(data, skipIdx = 4) {
  11. const stacklines = data.stack.split('\n').slice(skipIdx);
  12. const lineMatch = stackReg.exec(stacklines[0]);
  13. if (lineMatch && lineMatch.length === 6) {
  14. return {
  15. functionName: lineMatch[1],
  16. fileName: lineMatch[2],
  17. lineNumber: parseInt(lineMatch[3], 10),
  18. columnNumber: parseInt(lineMatch[4], 10),
  19. callStack: stacklines.join('\n'),
  20. };
  21. }
  22. return null;
  23. }
  24. /**
  25. * Logger to log messages.
  26. * use {@see log4js#getLogger(String)} to get an instance.
  27. *
  28. * @name Logger
  29. * @namespace Log4js
  30. * @param name name of category to log to
  31. * @param level - the loglevel for the category
  32. * @param dispatch - the function which will receive the logevents
  33. *
  34. * @author Stephan Strittmatter
  35. */
  36. class Logger {
  37. constructor(name) {
  38. if (!name) {
  39. throw new Error('No category provided.');
  40. }
  41. this.category = name;
  42. this.context = {};
  43. this.parseCallStack = defaultParseCallStack;
  44. debug(`Logger created (${this.category}, ${this.level})`);
  45. }
  46. get level() {
  47. return levels.getLevel(categories.getLevelForCategory(this.category), levels.TRACE);
  48. }
  49. set level(level) {
  50. categories.setLevelForCategory(this.category, levels.getLevel(level, this.level));
  51. }
  52. get useCallStack() {
  53. return categories.getEnableCallStackForCategory(this.category);
  54. }
  55. set useCallStack(bool) {
  56. categories.setEnableCallStackForCategory(this.category, (bool === true));
  57. }
  58. log(level, ...args) {
  59. const logLevel = levels.getLevel(level, levels.INFO);
  60. if (this.isLevelEnabled(logLevel)) {
  61. this._log(logLevel, args);
  62. }
  63. }
  64. isLevelEnabled(otherLevel) {
  65. return this.level.isLessThanOrEqualTo(otherLevel);
  66. }
  67. _log(level, data) {
  68. debug(`sending log data (${level}) to appenders`);
  69. const loggingEvent = new LoggingEvent(
  70. this.category,
  71. level,
  72. data,
  73. this.context,
  74. (this.useCallStack) && this.parseCallStack(new Error())
  75. );
  76. clustering.send(loggingEvent);
  77. }
  78. addContext(key, value) {
  79. this.context[key] = value;
  80. }
  81. removeContext(key) {
  82. delete this.context[key];
  83. }
  84. clearContext() {
  85. this.context = {};
  86. }
  87. setParseCallStackFunction(parseFunction) {
  88. this.parseCallStack = parseFunction;
  89. }
  90. }
  91. function addLevelMethods(target) {
  92. const level = levels.getLevel(target);
  93. const levelStrLower = level.toString().toLowerCase();
  94. const levelMethod = levelStrLower.replace(/_([a-z])/g, g => g[1].toUpperCase());
  95. const isLevelMethod = levelMethod[0].toUpperCase() + levelMethod.slice(1);
  96. Logger.prototype[`is${isLevelMethod}Enabled`] = function () {
  97. return this.isLevelEnabled(level);
  98. };
  99. Logger.prototype[levelMethod] = function (...args) {
  100. this.log(level, ...args);
  101. };
  102. }
  103. levels.levels.forEach(addLevelMethods);
  104. configuration.addListener(() => {
  105. levels.levels.forEach(addLevelMethods);
  106. });
  107. module.exports = Logger;