You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何修改Python logging模块的路径分隔符?兼谈跨OS适配问题

Python logging模块自定义JSON日志的路径分隔符问题

问题描述

想用Python的logging模块生成自定义JSON格式日志,需要记录pathname变量,但Windows下logging输出的路径用反斜杠\,导致JSON解析时出现Invalid escape character错误。

问题一:路径分隔符是否依赖操作系统?

是的,路径分隔符完全由操作系统决定:

  • Windows系统默认使用**反斜杠\**作为路径分隔符
  • Unix类系统(Linux、macOS等)默认使用**正斜杠/**作为路径分隔符
    代码部署到Unix系统后,pathname会自动使用正斜杠,不会出现JSON转义问题,但Windows环境下需要手动处理。

问题二:如何修改分隔符解决JSON错误?

可以通过两种方式处理,目标是将路径中的反斜杠替换为正斜杠,或者转义为双反斜杠(符合JSON语法要求):


测试代码

config.json

{
    "version": 1,
    "disable_existing_loggers": true,
    "formatters": {
        "standard": {
            "format": "{\"timestamp\":%(created)f,\"time\":\"%(asctime)s\",\"path\":\"%(pathname)s\",\"file\":\"%(filename)s\",\"line\":%(lineno)d,\"level\":\"%(levelname)s\",\"text\":\"%(message)s\"}",
            "datefmt": "%Y/%m/%d-%H:%M:%S"
        }
    },
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "formatter": "standard",
            "level": "DEBUG",
            "stream": "ext://sys.stdout"
        }
    },
    "loggers": {
        "": {
            "handlers": ["console"],
            "level": "DEBUG",
            "propagate": false
        }
    }
}

example.py

import logging
import json
import logging.config

with open("./config.json", "r", encoding="UTF_8") as file:
    config = json.load(file)
logging.config.dictConfig(config)
logger = logging.getLogger(__name__)
logger.info("This is an info log.")

当前输出(Windows下)

{"timestamp":1726603464.416349,"time":"2024/09/17-23:34:24","path":"d:\python\project\example.py","file":"example.py","line":9,"level":"INFO","text":"This is an info log."}

期望输出

# 方式一:转义成双反斜杠
{"timestamp":1726603464.416349,"time":"2024/09/17-23:34:24","path":"d:\\python\\project\\example.py","file":"example.py","line":9,"level":"INFO","text":"This is an info log."}

# 方式二:替换为正斜杠
{"timestamp":1726603464.416349,"time":"2024/09/17-23:34:24","path":"d:/python/project/example.py","file":"example.py","line":9,"level":"INFO","text":"This is an info log."}

解决方案

方案1:自定义Formatter类处理路径分隔符

创建自定义Formatter,在格式化日志时替换路径中的反斜杠:

import logging
import json
import logging.config

class JsonFormatter(logging.Formatter):
    def format(self, record):
        # 替换反斜杠为正斜杠,若要转成双反斜杠则用replace("\\", "\\\\")
        record.pathname = record.pathname.replace("\\", "/")
        return super().format(record)

# 加载配置并替换formatter
with open("./config.json", "r", encoding="UTF_8") as file:
    config = json.load(file)

logging.config.dictConfig(config)
# 为所有handler设置自定义Formatter
for handler in logging.getLogger().handlers:
    handler.setFormatter(JsonFormatter(
        fmt=config["formatters"]["standard"]["format"],
        datefmt=config["formatters"]["standard"]["datefmt"]
    ))

logger = logging.getLogger(__name__)
logger.info("This is an info log.")

方案2:用json.dumps生成合法JSON(推荐)

避免手动拼接JSON字符串,直接构造字典后用json.dumps序列化,自动处理转义:

import logging
import json
import logging.config

class JsonFormatter(logging.Formatter):
    def format(self, record):
        log_dict = {
            "timestamp": record.created,
            "time": self.formatTime(record, self.datefmt),
            "path": record.pathname.replace("\\", "/"),  # 替换为正斜杠,去掉该行则json.dumps自动转义反斜杠
            "file": record.filename,
            "line": record.lineno,
            "level": record.levelname,
            "text": record.getMessage()
        }
        return json.dumps(log_dict)

# 简化配置,无需在config中写JSON字符串
config = {
    "version": 1,
    "disable_existing_loggers": True,
    "handlers": {
        "console": {
            "class": "logging.StreamHandler",
            "level": "DEBUG",
            "stream": "ext://sys.stdout"
        }
    },
    "loggers": {
        "": {
            "handlers": ["console"],
            "level": "DEBUG",
            "propagate": False
        }
    }
}

logging.config.dictConfig(config)
for handler in logging.getLogger().handlers:
    handler.setFormatter(JsonFormatter(datefmt="%Y/%m/%d-%H:%M:%S"))

logger = logging.getLogger(__name__)
logger.info("This is an info log.")

该方案避免了手动拼接JSON的转义错误,稳定性更高。


内容的提问来源于stack exchange,提问作者Aria AAs

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 09:37:05