I have a logging config in my project:
import logging
import json
from copy import deepcopy
from logging import config
from typing import Any, Dict
class JsonBodyFilter(logging.Filter):
def filter(self, record):
if hasattr(record, 'body'):
try:
record.body = json.loads(record.body)
except (ValueError, TypeError):
pass
return True
LOGGING_DICT: Dict[str, Any] = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"json": {
"()": "pythonjsonlogger.orjson.OrjsonFormatter",
"format": "%(levelname)s %(asctime)s %(name)s %(message)s",
"datefmt": "%Y-%m-%dT%H:%M:%S.%03d",
"json_indent": False,
},
},
"filters": {
"json_body": {
"()": JsonBodyFilter,
},
},
"handlers": {
"console": {
"formatter": "json",
"filters": ["json_body"],
"class": "logging.StreamHandler",
"stream": "ext://sys.stdout",
},
},
"loggers": {},
}
def configure_logging(
logging_dict: dict[str, Any] | None = None,
app_log_level_map: dict[str, str] | None = None,
) -> None:
logging_dict = logging_dict or deepcopy(LOGGING_DICT)
logging_config = logging_dict.copy()
if app_log_level_map:
for app_name, log_level in app_log_level_map.items():
if app_name not in logging_config["loggers"]:
logging_config["loggers"][app_name] = {}
logging_config["loggers"][app_name]["level"] = log_level
logging_config["loggers"][app_name]["handlers"] = ["console"]
logging.config.dictConfig(logging_config)
There is a Kubernetes cluster with nodes where my applications are deployed. Each node has a Promtail agent that scrapes logs from endpoints and sends them to the Loki cluster (which consists of multiple services responsible for validation, storage, etc.).
For Promtail, which collects logs and pushes them to Loki, I have the following config:
scrape_configs:
- pipeline_stages:
- docker: {}
- multiline:
firstline: ‘^\d{4}-\d{2}-\d{2} \d{1,2}:\d{2}:\d{2}’
max_lines: 128
max_wait_time: 3s
job_name: kubernetes-pods-name
kubernetes_sd_configs:
- role: pod
relabel_configs:
- action: replace
source_labels:
- __meta_kubernetes_namespace
target_label: namespace
- action: replace
source_labels:
- __meta_kubernetes_pod_node_name
target_label: host
- action: replace
source_labels:
- __meta_kubernetes_pod_name
target_label: pod
- action: replace
source_labels:
- __meta_kubernetes_pod_container_name
target_label: container
- action: labelmap
regex: _meta_kubernetes_pod_label(.+)
- replacement: /var/log/pods/$1/.log
separator: /
source_labels:
- __meta_kubernetes_pod_uid
- __meta_kubernetes_pod_container_name
target_label: path
Grafana is connected to Loki as a data source, and it fetches logs by querying the loki-storage service.
If I write this query in Grafana:
{app=“$app”, namespace=“hmi-$stand”} | json
I get the error JSONParserErr.
I also tried using “Prettify JSON” in the panel settings, but nothing worked.
Currently my logs look like this:
but I want them to look like this — expanded and pretty-printed JSON:





