Use structured logging with appropriate context and log levels to maximize the value of log messages. Include relevant metadata with each log message to facilitate filtering and debugging:

  1. Use structured logging patterns that allow consistent inclusion of contextual information:
    # Instead of:
    logger.info("Processing item")
       
    # Do this:
    logger.info("Processing item", extra={"project_id": project.id, "item_type": item.type})
       
    # Or with Sentry SDK:
    sentry_sdk.set_context("operation_context", {"project_id": project.id, "item_type": item.type})
    
  2. Choose log levels based on actionability:

    Instead of removing logging statements, consider lowering their level to DEBUG for infrequently needed information.

  3. When logging exceptions:
  4. Avoid duplicate logging. If using a framework that handles logging (like lifecycle), add context to it rather than creating separate log entries:
    # Instead of:
    lifecycle.record_halt(reason)
    logger.info("Operation halted", extra={"reason": reason})
       
    # Do this:
    lifecycle.add_extras({"project_id": project.id})
    lifecycle.record_halt(reason)
    

Following these practices improves troubleshooting efficiency, enables better log filtering, and ensures that logs provide maximum value for debugging production issues.