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

Per Tenant Logging - Complete Implementation #2425

Closed

Conversation

shaangill025
Copy link
Contributor

@shaangill025 shaangill025 commented Aug 16, 2023

resolve #2359

@shaangill025 shaangill025 marked this pull request as ready for review August 22, 2023 14:51
@dbluhm
Copy link
Contributor

dbluhm commented Aug 23, 2023

I'm not terribly fond of this approach. In order to keep it going, we have to remember to get a logger instance with a profile which adds overhead to a task that should incur as little overhead as possible -- if not at execution time, it at least adds overhead in code. This means more lines of code that maintainers need to scan through to find issues.

So here's my suggestion: can we use context variables and a custom log formatter that reads a wallet_id context var to retrieve the wallet id (or any other subwallet specific values) when it's available?

@shaangill025
Copy link
Contributor Author

@dbluhm Based on your feedback, I have reworked the logging mechanism.

I added configure_per_tenant function to LoggingConfigurator which will be called during startup once here. Also added get_adapted_logger_inst utility function in aries_cloudagent/config/logging.py to improve code readability and reduce duplication, this will be called upon from different classes to get an adapted logger instance [formatted with wallet_id], if applicable.

@WadeBarnes
Copy link
Contributor

WadeBarnes commented Aug 29, 2023

What throws me off with this implementation is there is now a "special" way the get a "special" logger, rather than one consistent way to get a logger. A developer needs to be conscious of which logger they are using in a given context in order to have the desired behavior.

It would be better if the implementation was more compatible with the built in logging functionality so it would be completely transparent to the developer. So the implementation may consist of a custom log handler and a custom log formatter. I believe this is inline with @dbluhm's suggestion of a custom log formatter.

@shaangill025
Copy link
Contributor Author

shaangill025 commented Aug 29, 2023

What throws me off with this implementation is there is now a "special" way the get a "special" logger, rather than one consistent way to get a logger. A developer needs to be conscious of which logger they are using in a given context in order to have the desired behavior.

@WadeBarnes The reworked implementation adds a conditional to the existing app configuration to configure logger here:

  • If --log-file is passed then configure_per_tenant is called. The log handlers will then be added [i.e configuration applied] to all loggers across that agent instance. There are no special loggers in case log.file setting is involved as this will be the only type of logger.

It would be better if the implementation was more compatible with the built in logging functionality so it would be completely transparent to the developer. So the implementation may consist of a custom log handler and a custom log formatter. I believe this is inline with @dbluhm's suggestion of a custom log formatter

  • Re implementation may consist of a custom log handler and a custom log formatter, that is implemented in configure_per_tenant. This function is called once during startup to apply the configuration to all loggers. But the thing is that each Logger instance declared on different files also needs to be adapted with a contextual wallet_id identifier from profile settings. And this is done by calling get_adapted_logger_inst, you will see calls to this function across most files in this PR.

Re A developer needs to be conscious of which logger they are using in a given context in order to have the desired behavior, If the file where a logger is to be declared involves just access by the root_profile then LOGGER = logging.getLogger(__name__) declaration will be sufficient [just like before]. Each wallet_id entry in log file will be set as null in this case. But if the file is expected to be accessed by tenant profiles then a call to get_adapted_logger_inst is required which update logger with wallet_id identifier.

Does this address your concerns?

@WadeBarnes
Copy link
Contributor

WadeBarnes commented Aug 29, 2023

It's the calls to get_adapted_logger_inst that are really throwing me off, this implies "special" logger processing, and requires the developer to be aware of whether or not to use the modified logging behavior. I'm wondering whether this can be implemented in a custom log handler that looks up the wallet_id identifier automatically and then the whole process becomes completely transparent; no need to call get_adapted_logger_inst to change the logging behavior.

From the compatibility standpoint I was thinking an implementation that was more compatible with the logging.config.dictConfig(), where the logging configuration could be "defined" rather than "coded". This would help clean up aries_cloudagent/config/util.py and allow the per-tenant logging configuration to be defined in a log config file.

@shaangill025

This comment was marked as outdated.

@WadeBarnes
Copy link
Contributor

WadeBarnes commented Aug 29, 2023

I'm not super familiar with extending logging in python, but per-tenant logging, on the surface, to me, feels like an extension to the built in file log handler (or RotatingFileHandler) that collects the additional context and writes to individual files (one for each tenant), or a custom log formatter that collects and writes the additional context. In the case of the custom log formatter, it would be configured on a file log handler which is configured to write to a dynamic set of files (one for each tenant).

@shaangill025
Copy link
Contributor Author

I'm wondering whether this can be implemented in a custom log handler that looks up the wallet_id identifier automatically and then the whole process becomes completely transparent; no need to call get_adapted_logger_inst to change the logging behavior.

For example, in aries_cloudagent/connections/base_manager.py, the wallet_id will only be known once BaseConnectionManager is being initialized. In BaseConnectionManager.__init__ Instead of calling get_adapted_logger_inst I can have the same logic [as included in the function] in there. My rationale behind get_adapted_logger_inst was to extract common code out in a utility function.

@shaangill025 shaangill025 marked this pull request as draft August 29, 2023 15:56
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
@shaangill025 shaangill025 marked this pull request as ready for review September 16, 2023 21:41
Signed-off-by: Shaanjot Gill <gill.shaanjots@gmail.com>
@shaangill025
Copy link
Contributor Author

@WadeBarnes @esune This is ready for review, all changes requested should be incorporated now [incl DictConfig support]. The Logging.md has been updated and can be of help in testing this out.

@swcurran swcurran requested review from dbluhm and esune October 5, 2023 20:46
@swcurran
Copy link
Contributor

swcurran commented Oct 5, 2023

Let’s get this reviewed and merged in the next few days. Causing grief in debugging in multi-tenant worlds.

Thanks!

@WadeBarnes
Copy link
Contributor

@esune, @loneil, @shaangill025, @swcurran, I've created a ore release image for this PR if you'd like to test it out with a traction instance; https://github.com/hyperledger/aries-cloudagent-python/pkgs/container/aries-cloudagent-python/134985613?tag=py3.9-0.11.0-pr2425-pre0

Copy link
Member

@esune esune left a comment

Choose a reason for hiding this comment

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

This is looking a lot better than the first pass 🙂
I added a couple comments/questions, but other than that it looks good to me. If @dbluhm and/or @usingtechnology want to give it a look as they are more frequently involved in code changes for ACA-Py it would be great.

aries_cloudagent/config/logging.py Outdated Show resolved Hide resolved
Comment on lines +29 to +31
LOG_FORMAT_FILE_ALIAS_PATTERN = (
"%(asctime)s %(wallet_id)s %(levelname)s %(pathname)s:%(lineno)d %(message)s"
)
Copy link
Member

Choose a reason for hiding this comment

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

This looks like the same pattern/variable that is held in default_per_tenant_logging_config.ini - any reason to have the setting it repeated here?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It is used in the following conditional code, where --log-file is provided and --multitenant enabled but no file handler is specified in a custom config (different from default):
https://github.com/hyperledger/aries-cloudagent-python/blob/1fd858763897039b39815a110e4417ce67f48763/aries_cloudagent/config/logging.py#L136

@sonarqubecloud
Copy link

Kudos, SonarCloud Quality Gate passed!    Quality Gate passed

Bug A 0 Bugs
Vulnerability A 0 Vulnerabilities
Security Hotspot A 0 Security Hotspots
Code Smell A 0 Code Smells

No Coverage information No Coverage information
No Duplication information No Duplication information

@WadeBarnes
Copy link
Contributor

@shaangill025
Copy link
Contributor Author

Closing this PR and opening #2550 due to an issue with legacy (removed) code being in the pre-release images.

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.

Test Per Tenant Log Access and expand out
5 participants