diff --git a/backend/config.py b/backend/config.py index 640cbf4..e0066a3 100644 --- a/backend/config.py +++ b/backend/config.py @@ -1,5 +1,6 @@ from __future__ import annotations +import json import logging import logging.config import tomllib @@ -79,7 +80,11 @@ def setup_logging(settings: LoggingSettings) -> None: }, "json": { "()": structlog.stdlib.ProcessorFormatter, - "processor": structlog.processors.JSONRenderer(), + "processor": structlog.processors.JSONRenderer( + serializer=lambda obj, **kwargs: json.dumps( + obj, ensure_ascii=False, **kwargs + ) + ), "foreign_pre_chain": shared_processors, }, }, diff --git a/backend/tests/test_config.py b/backend/tests/test_config.py index 398cb2c..a514400 100644 --- a/backend/tests/test_config.py +++ b/backend/tests/test_config.py @@ -1,6 +1,9 @@ from __future__ import annotations -from config import AppSettings, as_public_dict +import json +import logging + +from config import AppSettings, LoggingSettings, as_public_dict, setup_logging def test_app_settings_load_from_toml_and_masks_api_key(tmp_path) -> None: @@ -30,3 +33,14 @@ password_words = [ assert settings.llm.model == "test-model" assert settings.game.hard_mode_rotation_interval == 3 assert public_data["llm"]["api_key"] == "***" + + +def test_file_logs_write_unicode_without_ascii_escaping(tmp_path) -> None: + setup_logging(LoggingSettings(logs_dir=tmp_path, app_log_name="app.log")) + + logging.getLogger().info("Привет") + + log_text = (tmp_path / "app.log").read_text(encoding="utf-8") + + assert "\\u041f" not in log_text + assert json.loads(log_text)["event"] == "Привет"