-
Notifications
You must be signed in to change notification settings - Fork 14k
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
[SIP-109] Global logs context #26019
Comments
Thanks for the SIP @eschutho. I have some questions that may help improve its definition:
Can you detail the motivation behind this restriction? What problems do you perceive if this expands to full objects?
Can we programmatically enforce this restriction?
Should we rename the decorator and Flask global class namespace to |
Thanks for the feedback @michael-s-molina, I was actually just going to update the SIP with a new name for the context to includes some more specifics about usage. (#4 comment) My original thoughts on this:
My intention is to clearly define the scope of the context and to keep the contents very limited in order to dissuade users from making it a catch-all that can be misused. Obviously storing data in a global variable is not standard practice, so if we decide to store data here, I think we should be very explicit about what can be stored in this variable so that not only it does not get bloated, but also so that others won't use this as a precedence to store other types of data in a global variable. To me, storing only the id and fetching further information from the metadata is the cleanest way to keep the scope of the data in this variable limited. Do you think that there are downsides to that approach? Having to fetch from metadata can be a downside, but in many cases, the data would have to be fetched before adding it to the context anyway.
That's a great question. We could look to see if the data is already stored in the context and then not overwrite it. But it's not actually the practice of overwriting it that is the problem, so much as again the practice and intention of the context: it shouldn't be used as a way to store any kind of state that needs to be fetched or manipulated to be saved later in the metadata or returned or raised from an api. If we're only storing resource ids, though, that could likely also enforce that data isn't changed because it would be unlikely that the id of a resource would change in any state management. |
Thanks for the additional context @eschutho. If we implement the safe guards correctly, avoiding your concerns, then this a great improvement over the current prop drilling. My suggestions would be:
|
[SIP-109] Proposal for global logs context
Motivation
We have a few examples in the codebase where for logging purposes we need to pass data down to parts of the codebase that have no need to know about this data. It creates very coupled and bloated modules that often are just passing data down without needing or acting on it. This change proposes the use of a global context dictionary that is used for read-only purposes for logging.
There are three current examples where this solution would help to simplify the codebase. These examples show the existing method of passing data around through multiple modules and levels of the code. There is this PR that logs a report execution id to help tie together multiple logs to the same report execution.
Another example is this PR that sends data to an smtp event for logging in a mail server.
And the third use case is this PR that passes data into the sql mutator for logging. In all three cases, we have needed to pass extraneous information across many levels of the codebase to get it to where we need to do the logging.
Proposed Change
Using Flask's built in global class, create a context dictionary that holds references to items in that request.
To limit the scope of this dictionary, only resource ids should be stored in this context. When a module needs to log some data, it can check the context for any relevant resources and then look up the resource for more context if needed.
New or Changed Public Interfaces
A new decorator @context that when applied to a method, will store information that is passed in either from the function arguments or directly into the decorator. Some examples:
Usage:
Per the above example, only the values in the
available_logs_context_values
will be added to the global logs_context. For example:will only add
execution_id
to the global logs_context.A few rules:
This first iteration of this change only takes arguments that are ids. If we wanted to expand this decorator to take entire objects like report_schedule in this example, and then extract and store the id, we could do that if needed, but for now we're able to get by with just the arguments that are already ids.
To add data that is in scope, but not an argument of the function, we can pass in items directly, such as:
If needed, the data could be added to the global logs_context without using the decorator, but I would advise against it. When extracting data from the global logs_context, one should be able to refer to the decorator's list of acceptable values
available_logs_context_values
as the de facto set of values that are available in the logs_context.Here's an example PR that is a POC for this new logs_context.
New dependencies
None
Migration Plan and Compatibility
None
Rejected Alternatives
The text was updated successfully, but these errors were encountered: