vishalanandl177 / DRF-API-Logger

An API Logger for your Django Rest Framework project.
https://github.com/vishalanandl177/DRF-API-Logger
Apache License 2.0
308 stars 56 forks source link

Proposal: Add Customizable Log Handling for drf-api-logger #99

Open mohammad4x opened 2 months ago

mohammad4x commented 2 months ago

Hello,

I appreciate the work put into the drf-api-logger library, which has been incredibly helpful for logging API requests and responses in Django applications. I would like to propose an enhancement to make log handling more flexible and customizable, allowing users to specify their own logic for processing logs.

Current Behavior:

Currently, the InsertLogIntoDatabase class inserts logs directly into the database using the _insert_into_data_base method. This approach works well for many use cases, but it limits users who wish to send logs to external services, such as Seq or other logging solutions.

Proposed Enhancement:

Introduce a mechanism that allows users to provide a custom handler for processing logs. This could be achieved by defining a new setting in settings.py that specifies the path to a custom function or callable responsible for handling the logs. This would allow the default behavior of inserting logs into the database to remain unchanged while providing flexibility for users who wish to customize their log handling.

Implementation Details:

  1. Custom Handler Setting:

    Add a new setting in settings.py:

    
    DRF_API_LOGGER_CUSTOM_HANDLER = None  # Default to None, or provide a path to a custom function
  2. Modify InsertLogIntoDatabase:

    Update the InsertLogIntoDatabase class to check for the presence of the custom handler setting and use it if defined. Here is a brief outline of the changes:

    
    from importlib import import_module
    
    class InsertLogIntoDatabase(Thread):
       # Existing initialization code...
    
       def __init__(self):
           # Existing setup...
           self.custom_handler = getattr(settings, 'DRF_API_LOGGER_CUSTOM_HANDLER', None)
           if self.custom_handler:
               self.custom_handler = self._import_custom_handler(self.custom_handler)
    
       def _import_custom_handler(self, handler_path):
           """
           Import the custom handler function from a given string path.
           """
           module_path, func_name = handler_path.rsplit('.', 1)
           module = import_module(module_path)
           return getattr(module, func_name)
    
       def _insert_into_data_base(self, bulk_item):
           """
           Insert the bulk item into the database or use a custom handler if defined.
           """
           if self.custom_handler:
               try:
                   self.custom_handler(bulk_item)
               except Exception as e:
                   print('DRF API LOGGER CUSTOM HANDLER EXCEPTION:', e)
           else:
               try:
                   APILogsModel.objects.using(self.DRF_API_LOGGER_DEFAULT_DATABASE).bulk_create(bulk_item)
               except OperationalError:
                   raise Exception("""
                   DRF API LOGGER EXCEPTION
                   Model does not exist.
                   Did you forget to migrate?
                   """)
               except Exception as e:
                   print('DRF API LOGGER EXCEPTION:', e)
  3. Example Custom Handler:

    Users can create their own handler functions, for example, to send logs to Seq:

    
    # my_logging_handlers.py
    
    import logging
    
    def send_logs_to_seq(bulk_item):
       logger = logging.getLogger(__name__)
       for log in bulk_item:
           logger.info('API Log',
               extra={
                   'requested_at': log.requested_at,
                   'response_time': log.response_time,
                   'method': log.method,
                   'path': log.path,
                   'remote_addr': log.remote_addr,
                   'status_code': log.status_code,
                   'request_body': log.request_body,
                   'response_body': log.response_body,
               }
           )
  4. And then set it in settings.py:

    
    DRF_API_LOGGER_CUSTOM_HANDLER = 'my_project.my_logging_handlers.send_logs_to_seq'

Benefits:

I believe this enhancement would make the drf-api-logger library even more valuable by providing greater flexibility in how logs are handled. Please let me know if you have any questions or need further clarification on this proposal.

Thank you for considering this enhancement!

Best regards,

[Mohammad]

bakhtiariali commented 2 months ago

That was excellent!👍🏻👍🏻 Great job.

mahdisharifloo commented 2 months ago

How hard I worked to customize the DRF logging system. Great Job