Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add appender and level inheritance #863

Merged

Conversation

pharapiak
Copy link

@pharapiak pharapiak commented Apr 25, 2019

These changes:

  • use a category's name to infer inheritance from another category
  • merges in unique appenders from parent categories, recursively
  • if no 'level' is defined for a category, it is copied from the nearest parent
  • fills in intermediate parent categories that are not explicitly declared in the config (E.g. given catA and catA.catB.catC, catA.catB will be created if it doesn't exist.
  • added support for boolean category.inherit to disable this, for backwards compatibility.
  • added addPreProcessingListener to config so that this inheritance is applied globally.
  • updated terms.md.

See configuration-inheritance-test.js for examples.

@codecov
Copy link

codecov bot commented Apr 30, 2019

Codecov Report

Merging #863 into master will increase coverage by 0.05%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #863      +/-   ##
==========================================
+ Coverage   97.43%   97.49%   +0.05%     
==========================================
  Files          25       25              
  Lines         937      959      +22     
==========================================
+ Hits          913      935      +22     
  Misses         24       24
Impacted Files Coverage Δ
lib/log4js.js 98.07% <100%> (+0.03%) ⬆️
lib/categories.js 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update d03bcae...045a1fe. Read the comment docs.

@codecov
Copy link

codecov bot commented Apr 30, 2019

Codecov Report

Merging #863 into master will increase coverage by 0.06%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #863      +/-   ##
==========================================
+ Coverage   97.86%   97.92%   +0.06%     
==========================================
  Files          25       25              
  Lines         937      966      +29     
==========================================
+ Hits          917      946      +29     
  Misses         20       20
Impacted Files Coverage Δ
lib/categories.js 100% <100%> (ø) ⬆️
lib/configuration.js 100% <100%> (ø) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update aa6c85c...301dcde. Read the comment docs.

Copy link
Collaborator

@nomiddlename nomiddlename left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to work out how to support your "pre-processing" of the config object before it gets passed to the other modules in a nice way. Right now it will break when read-only config is used, and it goes against the way I've tried to keep the main module from having to know about all the config-related stuff. I'd suggest adding an extra hook into the configuration module for adding pre-processing functions. What do you think?

lib/log4js.js Outdated
@@ -59,6 +59,8 @@ function configure(configurationFileOrObject) {
}
debug(`Configuration is ${configObject}`);

categories.addInheritedConfig(configObject); // copy config from parent to child categories
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this is going to give you problems when users supply read-only config objects (i.e. they've used Object.freeze or something similar). I think the node-config package does this by default. Your addInheritedConfig function modifies the original configObject. That's why the other modules add themselves as config listeners (there's code in the categories module that does this too) - they'll get called after the config object has been cloned, like below.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, I wasn't aware of read only config objects.

I found that I had to put some inheritance 'fixes' into the configuration validation, otherwise it rejects categories that have no directly configured appenders. I was originally just adding inheritance to the cloned config that gets passed to validation, before I realized that left the original config without any inheritance.

Would it make sense to clone the incoming readonly config, and use that clone thereafter? ie: apply inheritance, validate it, and use it for subsequent getLogger calls.

Another approach I considered was augmenting the categories object, with a getter method for appenders and level that considered inheritance, but I though it would be more efficient to just collapse inherited 'stuff' to sub-categories at startup.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, the steps should be the same as on the master branch for log4js.js:

// log4js.js: line 62
configuration.configure(deepClone(configObject));

Then in configuration.js we add an extra set of listeners (addPreProcessingListeners?), and call those functions with the cloned configObject. They can modify the config before it gets validated. So categories.js would add three config listeners - one for pre-processing (apply inheritance), one for the validation rules, and one for the setup.

@nomiddlename
Copy link
Collaborator

The travis CI failure is unrelated to your changes - I'll see if I can work out what's wrong with that test.

@pharapiak
Copy link
Author

Working on those requested changes. The suggested preProcessingListeners approach seems to work cleanly. Now reworking unit tests to verify the results.

Paul Harapiak added 2 commits May 4, 2019 12:10
for preparing config before validation and interpretation
@pharapiak
Copy link
Author

I added requested changes: applying inheritance through preProcessingListener.
I think this PR is ready to go.

@nomiddlename nomiddlename added this to the 4.2.0 milestone May 6, 2019
@nomiddlename nomiddlename merged commit 8c29e78 into log4js-node:master May 6, 2019
@pharapiak pharapiak deleted the inherit-parent-category-config branch May 6, 2019 13:07
@nomiddlename
Copy link
Collaborator

Published to NPM in version 4.2.0

@pharapiak
Copy link
Author

Great!

BTW, this was a milestone for me: my first-ever open source contribution.

@nomiddlename
Copy link
Collaborator

Congratulations, and thanks again for your help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants