levels.js 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. 'use strict';
  2. const configuration = require('./configuration');
  3. const validColours = [
  4. 'white', 'grey', 'black',
  5. 'blue', 'cyan', 'green',
  6. 'magenta', 'red', 'yellow'
  7. ];
  8. class Level {
  9. constructor(level, levelStr, colour) {
  10. this.level = level;
  11. this.levelStr = levelStr;
  12. this.colour = colour;
  13. }
  14. toString() {
  15. return this.levelStr;
  16. }
  17. /**
  18. * converts given String to corresponding Level
  19. * @param {Level|String} sArg -- String value of Level OR Log4js.Level
  20. * @param {Level} [defaultLevel] -- default Level, if no String representation
  21. * @return {Level}
  22. */
  23. static getLevel(sArg, defaultLevel) {
  24. if (!sArg) {
  25. return defaultLevel;
  26. }
  27. if (sArg instanceof Level) {
  28. return sArg;
  29. }
  30. // a json-serialised level won't be an instance of Level (see issue #768)
  31. if (sArg instanceof Object && sArg.levelStr) {
  32. sArg = sArg.levelStr;
  33. }
  34. if (typeof sArg === 'string') {
  35. return Level[sArg.toUpperCase()] || defaultLevel;
  36. }
  37. return Level.getLevel(sArg.toString());
  38. }
  39. static addLevels(customLevels) {
  40. if (customLevels) {
  41. const levels = Object.keys(customLevels);
  42. levels.forEach((l) => {
  43. const levelStr = l.toUpperCase();
  44. Level[levelStr] = new Level(
  45. customLevels[l].value,
  46. levelStr,
  47. customLevels[l].colour
  48. );
  49. const existingLevelIndex = Level.levels.findIndex(lvl => lvl.levelStr === levelStr);
  50. if (existingLevelIndex > -1) {
  51. Level.levels[existingLevelIndex] = Level[levelStr];
  52. } else {
  53. Level.levels.push(Level[levelStr]);
  54. }
  55. });
  56. Level.levels.sort((a, b) => a.level - b.level);
  57. }
  58. }
  59. isLessThanOrEqualTo(otherLevel) {
  60. if (typeof otherLevel === 'string') {
  61. otherLevel = Level.getLevel(otherLevel);
  62. }
  63. return this.level <= otherLevel.level;
  64. }
  65. isGreaterThanOrEqualTo(otherLevel) {
  66. if (typeof otherLevel === 'string') {
  67. otherLevel = Level.getLevel(otherLevel);
  68. }
  69. return this.level >= otherLevel.level;
  70. }
  71. isEqualTo(otherLevel) {
  72. if (typeof otherLevel === 'string') {
  73. otherLevel = Level.getLevel(otherLevel);
  74. }
  75. return this.level === otherLevel.level;
  76. }
  77. }
  78. Level.levels = [];
  79. Level.addLevels({
  80. ALL: { value: Number.MIN_VALUE, colour: 'grey' },
  81. TRACE: { value: 5000, colour: 'blue' },
  82. DEBUG: { value: 10000, colour: 'cyan' },
  83. INFO: { value: 20000, colour: 'green' },
  84. WARN: { value: 30000, colour: 'yellow' },
  85. ERROR: { value: 40000, colour: 'red' },
  86. FATAL: { value: 50000, colour: 'magenta' },
  87. MARK: { value: 9007199254740992, colour: 'grey' }, // 2^53
  88. OFF: { value: Number.MAX_VALUE, colour: 'grey' }
  89. });
  90. configuration.addListener((config) => {
  91. const levelConfig = config.levels;
  92. if (levelConfig) {
  93. configuration.throwExceptionIf(
  94. config,
  95. configuration.not(configuration.anObject(levelConfig)),
  96. 'levels must be an object'
  97. );
  98. const newLevels = Object.keys(levelConfig);
  99. newLevels.forEach((l) => {
  100. configuration.throwExceptionIf(
  101. config,
  102. configuration.not(configuration.validIdentifier(l)),
  103. `level name "${l}" is not a valid identifier (must start with a letter, only contain A-Z,a-z,0-9,_)`
  104. );
  105. configuration.throwExceptionIf(
  106. config,
  107. configuration.not(configuration.anObject(levelConfig[l])),
  108. `level "${l}" must be an object`
  109. );
  110. configuration.throwExceptionIf(
  111. config,
  112. configuration.not(levelConfig[l].value),
  113. `level "${l}" must have a 'value' property`
  114. );
  115. configuration.throwExceptionIf(
  116. config,
  117. configuration.not(configuration.anInteger(levelConfig[l].value)),
  118. `level "${l}".value must have an integer value`
  119. );
  120. configuration.throwExceptionIf(
  121. config,
  122. configuration.not(levelConfig[l].colour),
  123. `level "${l}" must have a 'colour' property`
  124. );
  125. configuration.throwExceptionIf(
  126. config,
  127. configuration.not(validColours.indexOf(levelConfig[l].colour) > -1),
  128. `level "${l}".colour must be one of ${validColours.join(', ')}`
  129. );
  130. });
  131. }
  132. });
  133. configuration.addListener((config) => {
  134. Level.addLevels(config.levels);
  135. });
  136. module.exports = Level;