Skip to main content

loki_logger_handler

PyPI PyPI Downloads

A logging handler that sends log messages to (Grafana) Loki in JSON format.

Features

  • Logs pushed in JSON format by default
  • Custom labels definition
  • Allows defining loguru and logger extra keys as labels
  • Logger extra keys added automatically as keys into pushed JSON
  • Publish in batch of Streams
  • Publish logs compressed

Args

  • url (str): The URL of the Loki server.
  • labels (dict): A dictionary of labels to attach to each log message.
  • label_keys (dict, optional): A dictionary of keys to extract from each log message and use as labels. Defaults to None.
  • auth (tuple, optional): Basic authentication credentials for the Loki request. Defaults to None.
  • additional_headers (dict, optional): Additional headers for the Loki request. Defaults to None.
  • timeout (int, optional): Timeout interval in seconds to wait before flushing the buffer. Defaults to 10 seconds.
  • compressed (bool, optional): Whether to compress the log messages before sending them to Loki. Defaults to True.
  • loguru (bool, optional): Whether to use LoguruFormatter. Defaults to False.
  • default_formatter (logging.Formatter, optional): Formatter for the log records. If not provided,LoggerFormatter or LoguruFormatter will be used.
  • enable_self_errors (bool, optional): Set to True to show Hanlder errors on console. Defaults to False

Loki 3.0

  • enable_structured_loki_metadata (bool, optional): Whether to include structured loki_metadata in the logs. Defaults to False. Only supported for Loki 3.0 and above
  • loki_metadata (dict, optional): Default loki_metadata values. Defaults to None. Only supported for Loki 3.0 and above
  • loki_metadata_keys (arrray, optional): Specific log record keys to extract as loki_metadata. Only supported for Loki 3.0 and above

Formatters

  • LoggerFormatter: Formatter for default python logging implementation
  • LoguruFormatter: Formatter for Loguru python library

How to use

First create a environment varialble to setup your loki url with this structure (Ej: https://100239:wdadw....dwad@logs-prod-eu-west-0.grafana.net/loki/api/v1/push)

LOKI_URL="https://{{USER}}:{{PASSWORD}}@{{GRAFANA_LOKI_URL}}/loki/api/v1/push"

Install

pip install loki-logger-handler

Logger

from loki_logger_handler.loki_logger_handler import LokiLoggerHandler,
import logging
import os 

# Set up logging
logger = logging.getLogger("custom_logger")
logger.setLevel(logging.DEBUG)

# Create an instance of the custom handler
custom_handler = LokiLoggerHandler(
    url=os.environ["LOKI_URL"],
    labels={"application": "Test", "environment": "Develop"},
    label_keys={},
    timeout=10,
)
# Create an instance of the custom handler

logger.addHandler(custom_handler)
logger.debug("Debug message", extra={'custom_field': 'custom_value'})

Loguru

from loki_logger_handler.loki_logger_handler import LokiLoggerHandler
from loki_logger_handler.formatters.loguru_formatter import LoguruFormatter
from loguru import logger
import os 

custom_handler = LokiLoggerHandler(
    url=os.environ["LOKI_URL"],
    labels={"application": "Test", "environment": "Develop"},
    label_keys={},
    timeout=10,
    default_formatter=LoguruFormatter(),
)
logger.configure(handlers=[{"sink": custom_handler, "serialize": True}])

logger.info(
    "Response code {code} HTTP/1.1 GET {url}", code=200, url="https://loki_handler.io"
)

Loki messages samples

Without extra

{
  "message": "Starting service",
  "timestamp": 1681638266.542849,
  "process": 48906,
  "thread": 140704422327936,
  "function": "run",
  "module": "test",
  "name": "__main__"
}

With extra

{
  "message": "Response code  200 HTTP/1.1 GET https://loki_handler.io",
  "timestamp": 1681638225.877143,
  "process": 48870,
  "thread": 140704422327936,
  "function": "run",
  "module": "test",
  "name": "__main__",
  "code": 200,
  "url": "https://loki_handler.io"
}

Exceptions

{
  "message": "name 'plan' is not defined",
  "timestamp": 1681638284.358464,
  "process": 48906,
  "thread": 140704422327936,
  "function": "run",
  "module": "test",
  "name": "__main__",
  "file": "test.py",
  "path": "/test.py",
  "line": 39
}

Loki Query Sample

Loki query sample :

{environment="Develop"} |= `` | json

Filter by level:

{environment="Develop", level="INFO"} |= `` | json

Filter by extra:

{environment="Develop", level="INFO"} |= `` | json | code=`200`

Loki Structured Metadata

Loki structured metadata to include additional context in your logs. This can be useful for filtering and querying logs in Loki.

We can add metadata in 3 ways:

  1. Defile static loki_metadata that will be injected into all logs lines
  2. Use logger extra options adding metadata inside loki_metadata key
  3. Use logger loki_metadata_keys to move logs keys to loki metadata.

Example global metadata

from loki_logger_handler.loki_logger_handler import LokiLoggerHandler
import logging
import os

# Set up logging
logger = logging.getLogger("custom_logger")
logger.setLevel(logging.DEBUG)

# Create an instance of the custom handler with structured metadata
custom_handler = LokiLoggerHandler(
  url=os.environ["LOKI_URL"],
  labels={"application": "Test", "environment": "Develop"},
  label_keys={},
  timeout=10,
  enable_structured_loki_metadata=True,
  loki_metadata={"service": "user-service", "version": "1.0.0"}
)

logger.addHandler(custom_handler)

In this example, the loki_metadata dictionary includes metadata that will be attached to every log message. The enable_structured_loki_metadata flag ensures that this metadata is included in the logs.

Example log metadata

from loki_logger_handler.loki_logger_handler import LokiLoggerHandler
import logging
import os

# Set up logging
logger = logging.getLogger("custom_logger")
logger.setLevel(logging.DEBUG)

# Create an instance of the custom handler with structured metadata
custom_handler = LokiLoggerHandler(
  url=os.environ["LOKI_URL"],
  labels={"application": "Test", "environment": "Develop"},
  label_keys={},
  timeout=10,
  enable_structured_loki_metadata=True,
  loki_metadata={"service": "user-service", "version": "1.0.0"}
)

logger.addHandler(custom_handler)

logger.info("User acction", extra={"loki_metadata": {"user_id": 12345, "operation": "update", "status": "success"}})
from loki_logger_handler.loki_logger_handler import LokiLoggerHandler
import logging
import os

# Set up logging
logger = logging.getLogger("custom_logger")
logger.setLevel(logging.DEBUG)

# Create an instance of the custom handler with structured metadata
custom_handler = LokiLoggerHandler(
  url=os.environ["LOKI_URL"],
  labels={"application": "Test", "environment": "Develop"},
  label_keys={},
  timeout=10,
  enable_structured_loki_metadata=True,
  loki_metadata={"service": "user-service", "version": "1.0.0"},
  loki_metadata_keys=["trace_id"]
)

logger.addHandler(custom_handler)

logger.info("User acction", extra={"loki_metadata": {"user_id": 12345, "operation": "update", "status": "success"}, "trace_id": "000-000000-0000"})

Querying Logs with Structured Metadata

You can query logs in Loki using the structured metadata.

This query will return all logs where the service metadata is set to user-service.

{application="Test"} |= `` | service="user-service"

This query will return all logs where the user_id metadata is set to 12345.

{application="Test"} |= `` | user_id="12345"

This query will return all logs where the trace_id metadata is set to 000-000000-0000.

{application="Test"} |= `` | trace_id="000-000000-0000"

Development Environment: Dev Container

This project uses a Dev Container to provide a consistent and reproducible development environment. A Dev Container ensures all team members have the same tools, dependencies, and configurations, avoiding "works on my machine" issues.


Why Use a Dev Container?

  • Consistency: Ensures everyone works in the same environment, regardless of the host OS.
  • Isolation: Keeps project dependencies separate from your system.
  • Portability: Easily onboard new developers by setting up the environment with a single command.
  • Pre-configured Tools: Includes all required tools and dependencies for the project.

Getting Started with the Dev Container

To start working with the Dev Container, follow these steps:

Prerequisites

  1. Install Docker Desktop (required for running containers).
  2. Install Visual Studio Code (VS Code).
  3. Install the Dev Containers extension in VS Code:
    • Go to Extensions (Ctrl+Shift+X / Cmd+Shift+X) and search for Dev Containers.
    • Install the extension by Microsoft.

Setup Instructions

  1. Clone the repository
  2. Open in VS Code
  3. Open the Command Palette (Ctrl+Shift+P / Cmd+Shift+P) and select: Dev Containers: Reopen in Container
  • VS Code will:
    • Pull the Dev Container image.
    • Install all dependencies and tools specified.

Resources

The loki_logger_handler Dev Container provides the following resources:

  • Grafana: Accessible externally at http://localhost:3000.
  • Loki: Accessible internally at http://loki:3100/loki/api/v1/push. You can use this URL in your code as the publish endpoint for logs. Logs can be viewed and queried via the Grafana interface.
os.environ["LOKI_URL"]=http://loki:3100/loki/api/v1/push

License

The MIT License

Metadata

Release files for loki-logger-handler 1.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for loki-logger-handler 1.1.2
File Size Uploaded
loki_logger_handler-1.1.2.tar.gz 16.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for loki-logger-handler 1.1.2
File Interpreter ABI Platform
loki_logger_handler-1.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 30.3 kB

Release files / loki_logger_handler-1.1.2.tar.gz

Download URL loki_logger_handler-1.1.2.tar.gz
Size 16.0 kB
Tags Source
SHA-256 checksum
How to use checksums
b3b588903420197ac9bb477f9c8fd6c18edf3e475b94f3d27d2aeed3930eb5d1
BLAKE2b-256 checksum
How to use checksums
ea606c212ae881abf82e6b85fddd6ef338404c4dbf812c3b1cb88527903c7633
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 26, 2025.

Transparency log

Release files / loki_logger_handler-1.1.2-py3-none-any.whl

Download URL loki_logger_handler-1.1.2-py3-none-any.whl
Size 14.3 kB
Tags Python 3
SHA-256 checksum
How to use checksums
7ee10259162caf6aa21b784d753dc2f73102225517857bb40051b7e933cfd07d
BLAKE2b-256 checksum
How to use checksums
090093631b307a801d8fe48867e20923fdb161f5d0aa165ca322b71544c35b96
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.12.9

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on May 26, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

1.1.2 This release

2 release files

1.1.1

2 release files

1.1.0

2 release files

1.0.2

2 release files

1.0.1

2 release files

1.0.0

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page