logger.js 3.3 KB

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