Структурированное журналирование
Выводите журналы в формате JSON для машинно-читабельных данных.
«Структурированное журналирование» — бесплатный урок Python Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.
Что такое структурированное журналирование
Структурированное журналирование выводит записи журнала в виде машиночитаемых данных (JSON), а не произвольного текста, поэтому их легко индексировать, искать и использовать для оповещений.
import logging, json
def log_json(level, msg, **kw):
record = {"level": level, "msg": msg, **kw}
print(json.dumps(record))
log_json("INFO", "Request received", path="/api/users", method="GET")Пользовательский форматировщик JSON
Создайте подкласс logging.Formatter, чтобы выводить данные в формате JSON вместо обычного текста.
import logging, json
class JSONFormatter(logging.Formatter):
def format(self, record):
return json.dumps({
"time": self.formatTime(record),
"level": record.levelname,
"name": record.name,
"msg": record.getMessage(),
})
handler = logging.StreamHandler()
handler.setFormatter(JSONFormatter())
logging.getLogger().addHandler(handler)python-json-logger
Пакет python-json-logger предоставляет готовый форматировщик JSON со стандартными и дополнительными полями.
# pip install python-json-logger
import logging
from pythonjsonlogger import jsonlogger
logger = logging.getLogger()
handler = logging.StreamHandler()
handler.setFormatter(jsonlogger.JsonFormatter())
logger.addHandler(handler)
logger.info("User created", extra={"user_id": 42})structlog
structlog — популярная сторонняя библиотека, которая отделяет накопление контекста от форматирования и поддерживает конвейеры обработчиков.
# pip install structlog
import structlog
log = structlog.get_logger()
log = log.bind(request_id="abc123")
log.info("payment_processed", amount=49.99, currency="USD")Связывание контекста с помощью structlog
structlog позволяет связывать пары ключ–значение с регистратором, и они сохраняются во всех последующих вызовах.
import structlog
log = structlog.get_logger().bind(
service="auth",
env="prod"
)
log.warning("login_failed", user="alice", reason="bad_password")
# {service:auth, env:prod, user:alice, reason:bad_password}Добавление временных меток и сведений о вызывающем коде
Обработчики могут автоматически дополнять записи. Добавьте TimeStamper и CallsiteParameterAdder в каждую запись журнала.
import structlog
structlog.configure(
processors=[
structlog.processors.TimeStamper(fmt="iso"),
structlog.processors.CallsiteParameterAdder([structlog.processors.CallsiteParameter.FILENAME]),
structlog.processors.JSONRenderer(),
]
)Журналирование ID запросов в веб-приложениях
В веб-фреймворке связывайте ID запроса в начале каждого запроса, чтобы каждая строка журнала во время этого запроса содержала его.
import structlog
def middleware(request, call_next):
req_id = request.headers.get("X-Request-Id", generate_id())
log = structlog.get_logger().bind(request_id=req_id)
log.info("request_started", path=request.url.path)
response = call_next(request)
log.info("request_finished", status=response.status_code)
return responseФормат журналов ECS
Elastic Common Schema (ECS) — стандартный формат журналов JSON, используемый Elastic Stack. Для Python используйте ecs-logging.
# pip install ecs-logging
import logging
import ecs_logging
logger = logging.getLogger("app")
handler = logging.StreamHandler()
handler.setFormatter(ecs_logging.StdlibFormatter())
logger.addHandler(handler)
logger.info("Event logged in ECS format")Системы агрегации журналов
Структурированные журналы JSON естественным образом поступают в инструменты агрегации: Elasticsearch/Kibana (ELK), Grafana Loki, Datadog, AWS CloudWatch Logs Insights.
# Loki query example:
# {app="myservice"} | json | level="ERROR"
# CloudWatch Insights:
# fields @timestamp, level, msg
# | filter level = "ERROR"
# | sort @timestamp descИзбегание PII в журналах
Удаляйте персональные идентификационные данные перед журналированием. Используйте пользовательский обработчик или фильтр, чтобы маскировать адреса электронной почты, токены и пароли.
import re
def mask_pii(_, __, event_dict):
msg = event_dict.get("event", "")
event_dict["event"] = re.sub(
r"[\w.+-]+@[\w-]+\.[\w.]+", "***@***.***", msg
)
return event_dictКомпромиссы структурированных и неструктурированных журналов
Структурированные журналы легко искать и использовать для оповещений, но они многословны. Сочетайте структурированное журналирование в рабочей среде с удобным для человека форматированием при разработке, используя конфигурацию на основе окружения.
import structlog, os
if os.getenv("ENV") == "production":
renderer = structlog.processors.JSONRenderer()
else:
renderer = structlog.dev.ConsoleRenderer()
structlog.configure(processors=[renderer])Проверка
Какое главное преимущество журналов в формате JSON перед обычными текстовыми журналами?
Итоги
Структурированное журналирование выводит записи JSON в формате ключ–значение. Используйте JSONFormatter, python-json-logger или structlog. Связывайте контекст (ID запроса, пользователь) в начале операции, чтобы каждая строка журнала во время этой операции содержала этот контекст.
Часто задаваемые вопросы
Урок «Структурированное журналирование» бесплатный?
Да — полный текст урока «Структурированное журналирование» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.
Чему я научусь в уроке «Структурированное журналирование»?
Выводите журналы в формате JSON для машинно-читабельных данных. Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Python Academy?
Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Структурированное журналирование»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Python Academy?
Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Основы модуля logging
- Обработчики, форматтеры и фильтры
- Структурированное журналирование
- Отладка с помощью pdb