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

Document use of extra with json logging #195

Open
kislyuk opened this issue Jan 30, 2024 · 4 comments
Open

Document use of extra with json logging #195

kislyuk opened this issue Jan 30, 2024 · 4 comments

Comments

@kislyuk
Copy link
Owner

kislyuk commented Jan 30, 2024

logger.info(..., extra={...})

@alexminza
Copy link

alexminza commented Oct 23, 2024

@kislyuk extra parameters currently are not sent to CloudWatch Logs:

import logging
import watchtower

logging.basicConfig(level="DEBUG")
logger = logging.getLogger()
logger.setLevel("DEBUG")

cloudwatch_handler = watchtower.CloudWatchLogHandler(log_group_name="log_group_name")
cloudwatch_handler.formatter.add_log_record_attrs=["name", "levelname", "filename", "lineno", "funcName", "message"]
logger.addHandler(cloudwatch_handler)
test_extra = {"test": 'test}
logging.info("TEST JSON LOGGING", extra={"test_extra": test_extra})
Screenshot 2024-10-23 at 09 31 47

@alexminza
Copy link

alexminza commented Oct 23, 2024

@alexminza
Copy link

Here's a basic monkey patch to get extra parameters logged:

class CloudWatchLogMonkeyPatchedFormatter(watchtower.CloudWatchLogFormatter):
    #https://github.com/aws-powertools/powertools-lambda-python/blob/develop/aws_lambda_powertools/logging/formatter.py
    RESERVED_LOG_ATTRS = (
        "name",
        "msg",
        "message",
        "args",
        "level",
        "levelname",
        "levelno",
        "pathname",
        "filename",
        "module",
        "exc_info",
        "exc_text",
        "stack_info",
        "lineno",
        "funcName",
        "created",
        "msecs",
        "relativeCreated",
        "thread",
        "threadName",
        "processName",
        "process",
        "asctime",
        "location",
        "timestamp",
    )

    def format(self, message):
        extras = {k: v for k, v in message.__dict__.items() if k not in self.RESERVED_LOG_ATTRS}
        extras['msg'] = message.msg
        message.msg = extras
        format_message = super().format(message)
        return format_message
watchtower_handler = watchtower.CloudWatchLogHandler(log_group_name='log_group_name')
watchtower_formatter = CloudWatchLogMonkeyPatchedFormatter()
watchtower_formatter.add_log_record_attrs=["name", "levelname", "filename", "lineno", "funcName", "message"]
watchtower_handler.setFormatter(watchtower_formatter)
logger.addHandler(watchtower_handler)

@alexminza
Copy link

Or even simpler - log whole record:

class CloudWatchLogJSONFormatter(watchtower.CloudWatchLogFormatter):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)

    def format(self, message):
        formatted_message = json.dumps(message.__dict__, default=self.json_serialize_default)
        return formatted_message

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

2 participants