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

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

Open
mohammad4x opened this issue Aug 8, 2024 · 2 comments
Open

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

mohammad4x opened this issue Aug 8, 2024 · 2 comments

Comments

@mohammad4x
Copy link

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:

  • Flexibility: Allows users to redirect logs to Seq or any other external logging service.
  • Backward Compatibility: Maintains existing behavior by default, ensuring no disruption for current users.
  • Configurability: Enhances the library's adaptability to various logging requirements without modifying core functionality.

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
Copy link

That was excellent!👍🏻👍🏻
Great job.

@mahdisharifloo
Copy link

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

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

No branches or pull requests

3 participants