Skip to content

Commit 84441e4

Browse files
committed
add context to logs
1 parent c7910bb commit 84441e4

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

pp/log.py

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,13 @@ class LogLevel:
5050

5151
class LogFormatter(logging.Formatter):
5252
'Custom log formatter that formats log messages as JSON, aka "Structured Logging".'
53+
def __init__(self, *args, defaults: dict = field(default_factory=dict), **kwargs):
54+
'''
55+
Initializes the log formatter with optional default context.
56+
- `defaults` is a dictionary of default context values to include in every log message.
57+
'''
58+
self.defaults = defaults
59+
super().__init__(*args, **kwargs)
5360

5461
def format(self, record) -> str:
5562
'Formats the log message as JSON.'
@@ -67,15 +74,21 @@ def format(self, record) -> str:
6774
{
6875
'timestamp': datetime.now().isoformat(),
6976
'msg': record.msg,
70-
'data': {'args': args} if args else {} | kwargs or {}
77+
'data': {'args': args} if args else {} | kwargs or {},
78+
'context': self.defaults or {},
7179
},
7280
default=_json_default,
7381
)
7482
record.args = ()
7583
return super().format(record)
7684

7785

78-
def _getLogger(name: str, level: int = logging.CRITICAL, handlers: list[logging.Handler] = []) -> logging.Logger:
86+
def _getLogger(
87+
name: str,
88+
level: int = logging.CRITICAL,
89+
handlers: list[logging.Handler] = [],
90+
context: dict = field(default_factory=dict),
91+
) -> logging.Logger:
7992
'''
8093
Creates a logger with the given name, level, and handlers.
8194
- If no handlers are provided, the logger will not output any logs.
@@ -109,7 +122,7 @@ def _getLogger(name: str, level: int = logging.CRITICAL, handlers: list[logging.
109122

110123
if logger.handlers:
111124
# only set the first handler to use the custom formatter
112-
logger.handlers[0].setFormatter(LogFormatter())
125+
logger.handlers[0].setFormatter(LogFormatter(defaults=context))
113126

114127
return logger
115128

@@ -119,6 +132,7 @@ def getLogger(
119132
level: int = logging.INFO,
120133
stream: io.TextIOBase = sys.stderr,
121134
files: dict[LogLevel, str] = dict(),
135+
context: dict = field(default_factory=dict),
122136
) -> logging.Logger:
123137
'''
124138
Creates a logger with the given name, level, and handlers.
@@ -143,4 +157,4 @@ def getLogger(
143157
handler.setLevel(flevel)
144158
handlers.append(handler)
145159

146-
return _getLogger(name, level, handlers)
160+
return _getLogger(name, level, handlers, context=context)

0 commit comments

Comments
 (0)