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

PB-511: Django request context in logs - #minor #62

Merged
merged 2 commits into from
Sep 4, 2024

Conversation

benschs
Copy link
Contributor

@benschs benschs commented Aug 29, 2024

Middleware and filter that can be combined to add django request fields to all logs within the scope of the request.
Middleware adds request object to a thread local variable. Filter adds the request from thread to log record. Existing json filter can be used to decide which request fields should be added to the log.

@benschs benschs requested review from boecklic and ltshb August 29, 2024 09:40
@github-actions github-actions bot changed the title PB-511: Django request context in logs PB-511: Django request context in logs - #minor Aug 29, 2024
@benschs benschs force-pushed the feat-PB-511-django-request-log branch from 4da35d2 to 500c438 Compare August 29, 2024 11:39
Copy link
Contributor

@ltshb ltshb left a comment

Choose a reason for hiding this comment

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

Nicer approach, and simpler

Some improvements thoughts to make it more generic

  • move the thread local into logging_utilities/thread_context.py
# thread_context.py
from threading import local

class ThreadContext(local):
   pass

thread_context = ThreadContext()
  • Call the middleware add_context.py
from thread_context import thread_context

def __call__(self, request):
   thread_context.request = request
   # do the processing
   thread_context.request = None   
  • Call the filter add_thread_context.py No django dependencies
from thread_context import thread_context

class AddThreadContext(logging.Filter):
   # contexts := list of context key mapping between thread_context key and logger key, or use a list of dict {logger : "logger key", context: "context key"}
   def __init__(self, contexts = []): 
      self.contexts = contexts

   def filter(self, record):
      for context in contexts:
         if thread_context[context.context_key] != None:
            setattr(record, context.logger_key, thread_context[context.context_key])
      return True

This way we would have a new very generic logging filter that could be reused by any system that require any thread context. And we would have a django filter that could in future add other thread context values, not only request.

Comment on lines 19 to 20
def clear_thread_variable():
REQUEST_VARS.__dict__.clear()
Copy link
Contributor

Choose a reason for hiding this comment

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

Why having a clear if we have a delete function. I would only keep delete. See also my other comment

Comment on lines 30 to 37
def __call__(self, request):
set_variable('request', request)
response = self.get_response(request)
clear_thread_variable()
return response

def process_exception(self, request, exception):
clear_thread_variable()
Copy link
Contributor

Choose a reason for hiding this comment

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

Here in clean up I would only remove the added key and not clear the whole local variable. This is basically the same but make code clearer and we could theoretically use the local variable for something else as well.

Comment on lines 36 to 37
def process_exception(self, request, exception):
clear_thread_variable()
Copy link
Contributor

Choose a reason for hiding this comment

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

IN process exception we need to make sure that the exception has been logged before by another system with the request infos. I'm not sure anymore how it worked on django, but did you verify that in case of an exception the exception is logged before you clear this variable ?

@benschs benschs force-pushed the feat-PB-511-django-request-log branch from 500c438 to 97fcc36 Compare September 2, 2024 10:59
@benschs
Copy link
Contributor Author

benschs commented Sep 2, 2024

@ltshb Thanks for all the input. That all makes sense to me and I have rewritten the parts.

@benschs benschs requested a review from ltshb September 2, 2024 11:02
Middleware and filter that can be combined to add django request fields to all
logs within the scope of the request.
Middleware adds request object to a thread local variable. Filter adds the
request from thread to log record. Existing json filter can be used to
decide which request fields should be added to the log.
Copy link
Contributor

@ltshb ltshb left a comment

Choose a reason for hiding this comment

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

Great ! Would be nice to be a bit more verbose in the readme.

logging_utilities/thread_context.py Outdated Show resolved Hide resolved
Copy link

@boecklic boecklic left a comment

Choose a reason for hiding this comment

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

Very nice work and solution!

Extent documentation for adding django requests to log records. Add
descriptions of the django middleware and the filter to add thread variables to
log records.
Add a use case example in README to add django request context to all log
records, by combining multiple components of this library.
@benschs benschs merged commit 2465f18 into master Sep 4, 2024
3 checks passed
@benschs benschs deleted the feat-PB-511-django-request-log branch September 4, 2024 06:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants