Skip to main content

A python context logger with thread-local storage and context propagation for Python applications.

Project description

Python Context Logger

A Python context logger using thread-local storage for log context propagation across threads, designed to simplify logging in multi-threaded applications. The logger dynamically updates log context based on function parameters and provides flexibility for customization at initialization.

Features

  • Thread-local storage for log context: Each thread maintains its own isolated log context, ensuring no cross-thread interference.
  • Dynamic log context updating: Automatically updates log context based on function parameters, enabling detailed logging.
  • Log context propagation across threads: Ensures log context consistency in multi-threaded environments.
  • Decorators for easy integration: Integrate logging into functions and classes using decorators for cleaner and more maintainable code.
  • Optional logRequestId generation: Automatically track request IDs if explicitly enabled.
  • Configurable logger: Customize the logger name, level, and format during initialization.
  • Constant key-value pairs: Set log constants to ensure that specific key-value pairs are present in every log entry.
  • Retrieve log property values: Get specific log property values (e.g., requestId) to propagate across services.

Installation

pip install py-context-logger

Usage

Basic Initialization

from context_logger import ContextLogger

# Initialize logger
context_logger = ContextLogger()

# Optional: Configure logger name, log format, and log level
context_logger.initialize_context_logger(name="MyLogger", log_format="%(asctime)s - %(message)s", level="INFO")

# Optional: Configure GCP logger
# credentials: google.auth.credentials.Credentials
context_logger.initialize_context_logger(enable_gcp_logger=True,gcp_credentials=credentials)

Flask Example

Integrating the logger into a Flask application to automatically log request context and function parameters.

from flask import Flask, request
from context_logger import UseContextLogger, ClearLogContext

app = Flask(__name__)
context_logger = ContextLogger()

# Initialize context logger
context_logger.initialize_context_logger()

@app.route('/some-endpoint', methods=['POST'])
@UseContextLogger({
    'resource_name': 'name',
    'resource_id': 'id',
    'headers.requestId': 'requestId',
    'headers.mailId': 'requestedMail'
})
@ClearLogContext()
def some_endpoint(resource_name: str, resource_id: str, headers: dict, logger=None):
    logger.info("Processing request")
    data = request.get_json()

    # Class method logging example
    sample_class = SampleClass()
    user_name, company_name = "Sample user", "Sample company"
    sample_class.method_one(user_name=user_name, user_company=company_name)

    return {"status": "success"}

if __name__ == '__main__':
    app.run(debug=True)

Class-Level Logging

Decorate class methods to automatically add context information to logs.

from context_logger import UseContextLogger

@UseContextLogger()
class SampleClass:
    def __init__(self, logger=None):
        self.logger = logger

    @UseContextLogger({"user_name": "username", "log_constants": {"company_city": "New York"}})
    def method_one(self, user_name: str, user_company: str, logger=None):
        self.logger.info(f"Processing method_one with user")
        self.method_two(user_company=user_company)

    def method_two(self, user_company: str):
        self.logger.info(f"Processing method_two with company: {user_company}")
    
    # Fetch log property to pass across services
    def method_three(self, user_company: str):
        requestId = self.logger.get_property_value(log_property="requestId")
        self.logger.info(f"Processing method_three with company: {user_company} and requestId: {requestId}")

Customization of Logger

You can initialize the logger with a custom name, log level, and format.

context_logger.initialize_context_logger(
    name="CustomLogger",
    log_format="%(asctime)s - %(levelname)s - %(message)s",
    level="DEBUG"
)

Retrieve Log Properties

At any point in the application, you can retrieve a log property (e.g., requestId) to pass it to other services or systems.

requestId = context_logger.get_property_value("logRequestId")

Sample Log Format

2024-07-16 16:20:54,197 - main.py:79 - INFO - {'name': 'sample_resource', 'id': '123', 'logRequestId': '6239237f-1f96-48c6-93f3-89fd2c63ea6d', 'requestedMail': 'sample-user@gmail.com'} - Processing request
2024-07-16 16:20:54,198 - main.py:79 - INFO - {'name': 'sample_resource', 'id': '123', 'logRequestId': '6239237f-1f96-48c6-93f3-89fd2c63ea6d', 'requestedMail': 'sample-user@gmail.com', 'username': 'Sample user', 'company_city': 'New York'} - Processing method_one with user
2024-07-16 16:20:54,199 - main.py:79 - INFO - {'name': 'sample_resource', 'id': '123', 'logRequestId': '6239237f-1f96-48c6-93f3-89fd2c63ea6d', 'requestedMail': 'sample-user@gmail.com', 'username': 'Sample user', 'company_city': 'New York'} - Processing method_two with company: Sample company
2024-07-16 16:20:55,000 - main.py:79 - INFO - {'name': 'sample_resource', 'id': '123', 'logRequestId': '6239237f-1f96-48c6-93f3-89fd2c63ea6d', 'requestedMail': 'sample-user@gmail.com', 'username': 'Sample user', 'company_city': 'New York'} - Processing method_three with company: Sample company

Security Considerations

  1. Sensitive Data: Ensure sensitive information (e.g., user credentials, personal data) is not logged unless absolutely necessary.
  2. Log Access Control: Limit access to logs to authorized personnel only.
  3. Log Integrity: Implement security measures to detect and prevent log manipulation or tampering.

Performance

  • Thread-local storage: The use of thread-local storage ensures isolated log contexts for each thread, minimizing contention in multi-threaded applications.
  • Efficient context propagation: Log context is efficiently propagated across threads without introducing significant performance overhead.
  • Minimal overhead: The custom logger and decorators are designed to introduce minimal performance impact, allowing for high-throughput logging.

License

This project is licensed under the MIT License.


Conclusion

The py-context-logger package provides a flexible, powerful logging system designed for multi-threaded Python applications. With easy-to-use decorators, thread-local storage, and support for custom log contexts, this logger simplifies complex logging scenarios while maintaining performance and flexibility.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

py_context_logger-1.1.5.tar.gz (9.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

py_context_logger-1.1.5-py3-none-any.whl (8.4 kB view details)

Uploaded Python 3

File details

Details for the file py_context_logger-1.1.5.tar.gz.

File metadata

  • Download URL: py_context_logger-1.1.5.tar.gz
  • Upload date:
  • Size: 9.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/5.1.1 CPython/3.9.6

File hashes

Hashes for py_context_logger-1.1.5.tar.gz
Algorithm Hash digest
SHA256 c32a81fb4120e1814d253ba3fe1667a77e832e304bcccab1cb05d0c13d824c90
MD5 ad773a1e7d4991d84addf7953d355cf6
BLAKE2b-256 12214857340585d2ab8185656165383bc80138cb9fab857cb19ec5f54162f2df

See more details on using hashes here.

File details

Details for the file py_context_logger-1.1.5-py3-none-any.whl.

File metadata

File hashes

Hashes for py_context_logger-1.1.5-py3-none-any.whl
Algorithm Hash digest
SHA256 0f20d4814861884e9d120e3a5b9bb9ac418af1cea61688b41bed46261066bc13
MD5 61311a77882547d3ce48d7e7138f6bf8
BLAKE2b-256 e5b1388b8006c8df7f1916fbb75f6e9fcd1153f9bfbd152c845efc2ba19d8648

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page