Skip to content

Commit

Permalink
vdk-core: VdkBoundLogger (#2823)
Browse files Browse the repository at this point in the history
This change introduces the VdkBoundLogger and addresses #2802.

Testing done: locally tested

Signed-off-by: Gabriel Georgiev <[email protected]>
  • Loading branch information
gabrielgeorgiev1 authored Oct 26, 2023
1 parent 22cee2d commit 85bffc0
Showing 1 changed file with 51 additions and 0 deletions.
51 changes: 51 additions & 0 deletions projects/vdk-core/src/vdk/internal/core/logging.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# Copyright 2021-2023 VMware, Inc.
# SPDX-License-Identifier: Apache-2.0
import logging


class VdkBoundLogger(logging.LoggerAdapter):
"""
This class wraps around a Logger to append additional context to log records.
Logger-wide context can be included by providing it in the `context` parameter of the
`bind_logger` method.
Log statement-specific context can be included by including an `extra` kwarg to the log call and
providing a dictionary object (or any object which implements __getitem__ and __iter__) with the
required additional log fields.
It is intended to be instantiated using the `bind_logger` function and providing it with the current
log object and the additional context which will be included in dictionary form.
Example use::
import logging
from vdk.internal.builtin_plugins.config.log_config import bind_logger
bound_logger = bind_logger(logging.getLogger(__name__), {"logger_wide_bound_key": "logger_wide_bound_value"})
bound.warning("From vdk_initialize", extra={"first_key": "first_value"})
bound.warning("Something else from vdk_initialize")
Now, the LogRecord produced by the first log statement will have both
"logger_wide_bound_key": "logger_wide_bound_value" and "first_key": "first_value" included in its __dict__,
while the second one will only have "first_key": "first_value" in it.
Note that these will not be automatically included in the output log and must be processed downstream by
something like vdk-structlog.
"""

def process(self, msg: str, kwargs: dict):
# merge bound extra dict with existing extra dict if any
if "extra" in kwargs:
kwargs["extra"] = {**self.extra, **kwargs["extra"]}
else:
kwargs["extra"] = self.extra
return msg, kwargs


def bind_logger(log: logging.Logger, context: dict):
"""
Instantiates a VdkBoundLogger object.
:param log: current log object
:param context: dictionary containing the additional context we want to include in log statements
:return: a VdkBoundLogger instance
"""
return VdkBoundLogger(log, context)

0 comments on commit 85bffc0

Please sign in to comment.