categories.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. const configuration = require('./configuration');
  2. const levels = require('./levels');
  3. const appenders = require('./appenders');
  4. const debug = require('debug')('log4js:categories');
  5. const categories = new Map();
  6. configuration.addListener((config) => {
  7. configuration.throwExceptionIf(
  8. config,
  9. configuration.not(configuration.anObject(config.categories)),
  10. 'must have a property "categories" of type object.'
  11. );
  12. const categoryNames = Object.keys(config.categories);
  13. configuration.throwExceptionIf(
  14. config,
  15. configuration.not(categoryNames.length),
  16. 'must define at least one category.'
  17. );
  18. categoryNames.forEach((name) => {
  19. const category = config.categories[name];
  20. configuration.throwExceptionIf(
  21. config,
  22. [
  23. configuration.not(category.appenders),
  24. configuration.not(category.level)
  25. ],
  26. `category "${name}" is not valid (must be an object with properties "appenders" and "level")`
  27. );
  28. configuration.throwExceptionIf(
  29. config,
  30. configuration.not(Array.isArray(category.appenders)),
  31. `category "${name}" is not valid (appenders must be an array of appender names)`
  32. );
  33. configuration.throwExceptionIf(
  34. config,
  35. configuration.not(category.appenders.length),
  36. `category "${name}" is not valid (appenders must contain at least one appender name)`
  37. );
  38. category.appenders.forEach((appender) => {
  39. configuration.throwExceptionIf(
  40. config,
  41. configuration.not(appenders.get(appender)),
  42. `category "${name}" is not valid (appender "${appender}" is not defined)`
  43. );
  44. });
  45. configuration.throwExceptionIf(
  46. config,
  47. configuration.not(levels.getLevel(category.level)),
  48. `category "${name}" is not valid (level "${category.level}" not recognised;` +
  49. ` valid levels are ${levels.levels.join(', ')})`
  50. );
  51. });
  52. configuration.throwExceptionIf(
  53. config,
  54. configuration.not(config.categories.default),
  55. 'must define a "default" category.'
  56. );
  57. });
  58. const setup = (config) => {
  59. categories.clear();
  60. const categoryNames = Object.keys(config.categories);
  61. categoryNames.forEach((name) => {
  62. const category = config.categories[name];
  63. const categoryAppenders = [];
  64. category.appenders.forEach((appender) => {
  65. categoryAppenders.push(appenders.get(appender));
  66. debug(`Creating category ${name}`);
  67. categories.set(
  68. name,
  69. { appenders: categoryAppenders, level: levels.getLevel(category.level) }
  70. );
  71. });
  72. });
  73. };
  74. setup({ categories: { default: { appenders: ['out'], level: 'OFF' } } });
  75. configuration.addListener(setup);
  76. const configForCategory = (category) => {
  77. debug(`configForCategory: searching for config for ${category}`);
  78. if (categories.has(category)) {
  79. debug(`configForCategory: ${category} exists in config, returning it`);
  80. return categories.get(category);
  81. }
  82. if (category.indexOf('.') > 0) {
  83. debug(`configForCategory: ${category} has hierarchy, searching for parents`);
  84. return configForCategory(category.substring(0, category.lastIndexOf('.')));
  85. }
  86. debug('configForCategory: returning config for default category');
  87. return configForCategory('default');
  88. };
  89. const appendersForCategory = category => configForCategory(category).appenders;
  90. const getLevelForCategory = category => configForCategory(category).level;
  91. const setLevelForCategory = (category, level) => {
  92. let categoryConfig = categories.get(category);
  93. debug(`setLevelForCategory: found ${categoryConfig} for ${category}`);
  94. if (!categoryConfig) {
  95. const sourceCategoryConfig = configForCategory(category);
  96. debug('setLevelForCategory: no config found for category, ' +
  97. `found ${sourceCategoryConfig} for parents of ${category}`);
  98. categoryConfig = { appenders: sourceCategoryConfig.appenders };
  99. }
  100. categoryConfig.level = level;
  101. categories.set(category, categoryConfig);
  102. };
  103. module.exports = {
  104. appendersForCategory,
  105. getLevelForCategory,
  106. setLevelForCategory
  107. };