From 3e51ff7f7c6da2dde833ed2755bc8ea07dd02a25 Mon Sep 17 00:00:00 2001 From: emergenz Date: Wed, 1 Jan 2025 09:23:01 +0000 Subject: [PATCH 1/2] feat: add structured metadata via extra={"metadata":... --- logging_loki/emitter.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/logging_loki/emitter.py b/logging_loki/emitter.py index 949ceea..05b22d6 100644 --- a/logging_loki/emitter.py +++ b/logging_loki/emitter.py @@ -136,8 +136,13 @@ def build_payload(self, record: logging.LogRecord, line) -> dict: labels = self.build_tags(record) ns = 1e9 ts = str(int(time.time() * ns)) + + # Include structured metadata + metadata = getattr(record, "metadata", {}) + value = [ts, line, metadata] if metadata else [ts, line] + stream = { "stream": labels, - "values": [[ts, line]], + "values": [value], } - return {"streams": [stream]} + return {"streams": [stream]} \ No newline at end of file From 3c2caa666c65ad0783feee6d775c5f7d795f8ff5 Mon Sep 17 00:00:00 2001 From: emergenz Date: Fri, 3 Jan 2025 14:32:07 +0000 Subject: [PATCH 2/2] feat: add metadata logging documentation --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 54c7642..93e36c2 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -python-logging-loki +python-logging-loki (with structured metadata support) =================== [![PyPI version](https://img.shields.io/pypi/v/python-logging-loki.svg)](https://pypi.org/project/python-logging-loki/) @@ -6,7 +6,8 @@ python-logging-loki [![License](https://img.shields.io/pypi/l/python-logging-loki.svg)](https://opensource.org/licenses/MIT) [![Build Status](https://travis-ci.org/GreyZmeem/python-logging-loki.svg?branch=master)](https://travis-ci.org/GreyZmeem/python-logging-loki) -Python logging handler for Loki. +A fork of the python logging handler for Loki, supporting structured metadata. + https://grafana.com/loki Installation @@ -44,7 +45,16 @@ Example above will send `Something happened` message along with these labels: - Logger's name as `logger` - Labels from `tags` item of `extra` dict -The given example is blocking (i.e. each call will wait for the message to be sent). +To log structured metadata, simply add a `metadata` field to `extra`: + +```python +logger.info( + f'Epoch [{epoch+1}/{epochs}], Loss: {loss:.4f}', + extra={"tags": {"experiment": "example"}, "metadata": {"epoch": f"{epoch}", "loss": f"{loss:.4f}"}}, + ) +``` + +The given examples are blocking (i.e. each call will wait for the message to be sent). But you can use the built-in `QueueHandler` and` QueueListener` to send messages in a separate thread. ```python