python-logging-best-practices by terrylica/cc-skills
npx skills add https://github.com/terrylica/cc-skills --skill python-logging-best-practices在以下情况下使用此技能:
为 Python 日志记录模式提供统一参考,针对机器可读性(Claude Code 分析)和操作可靠性进行了优化。
防止日志无限增长 - 为所有日志文件配置轮转:
# Loguru 模式(推荐用于现代脚本)
from loguru import logger
logger.add(
log_path,
rotation="10 MB", # 在 10MB 时轮转
retention="7 days", # 保留 7 天
compression="gz" # 压缩旧日志
)
# RotatingFileHandler 模式(仅使用标准库)
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler(
log_path,
maxBytes=100 * 1024 * 1024, # 100MB
backupCount=5 # 保留 5 个备份(最大约 500MB)
)
对于 Claude Code 或其他工具将要分析的日志,请使用 JSONL(.jsonl)格式:
# 每行一个 JSON 对象 - 可通过 jq 解析
{"timestamp": "2026-01-14T12:45:23.456Z", "level": "info", "message": "..."}
{"timestamp": "2026-01-14T12:45:24.789Z", "level": "error", "message": "..."}
广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
文件扩展名:始终使用 .jsonl(而非 .json 或 .log)
验证:cat file.jsonl | jq -c .
术语:JSONL 是规范术语。等效术语:NDJSON、JSON Lines。
| 方法 | 使用场景 | 优点 | 缺点 |
|---|---|---|---|
loguru | 现代脚本、CLI 工具 | 零配置、异步安全、内置轮转 | 外部依赖 |
RotatingFileHandler | LaunchAgent 守护进程、仅使用标准库 | 无依赖 | 设置更复杂 |
logger_setup.py | 富终端应用程序 | 输出美观 | 设置复杂 |
使用结构化 JSONL 输出处理跨平台日志目录:
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.11"
# dependencies = ["loguru", "platformdirs"]
# ///
import json
import sys
from pathlib import Path
from uuid import uuid4
import platformdirs
from loguru import logger
def json_formatter(record) -> str:
"""用于 Claude Code 分析的 JSONL 格式化器。"""
log_entry = {
"timestamp": record["time"].strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z",
"level": record["level"].name.lower(),
"component": record["function"],
"operation": record["extra"].get("operation", "unknown"),
"operation_status": record["extra"].get("status", None),
"trace_id": record["extra"].get("trace_id"),
"message": record["message"],
"context": {k: v for k, v in record["extra"].items()
if k not in ("operation", "status", "trace_id", "metrics")},
"metrics": record["extra"].get("metrics", {}),
"error": None
}
if record["exception"]:
exc_type, exc_value, _ = record["exception"]
log_entry["error"] = {
"type": exc_type.__name__ if exc_type else "Unknown",
"message": str(exc_value) if exc_value else "Unknown error",
}
return json.dumps(log_entry)
def setup_logger(app_name: str = "my-app"):
"""为机器可读的 JSONL 输出配置 Loguru。"""
logger.remove()
# 控制台输出(JSONL 到 stderr)
logger.add(sys.stderr, format=json_formatter, level="INFO")
# 跨平台日志目录
# macOS: ~/Library/Logs/{app_name}/
# Linux: ~/.local/state/{app_name}/log/
log_dir = Path(platformdirs.user_log_dir(
appname=app_name,
ensure_exists=True
))
# 带轮转的文件输出
logger.add(
str(log_dir / f"{app_name}.jsonl"),
format=json_formatter,
rotation="10 MB",
retention="7 days",
compression="gz",
level="DEBUG"
)
return logger
# 用法示例
setup_logger("my-app")
trace_id = str(uuid4())
logger.info(
"操作已开始",
operation="my_operation",
status="started",
trace_id=trace_id
)
logger.info(
"操作完成",
operation="my_operation",
status="success",
trace_id=trace_id,
metrics={"duration_ms": 150, "items_processed": 42}
)
| 字段 | 类型 | 用途 |
|---|---|---|
timestamp | ISO 8601 带 Z | 事件排序 |
level | 字符串 | debug/info/warning/error/critical |
component | 字符串 | 模块/函数名称 |
operation | 字符串 | 正在执行的操作 |
operation_status | 字符串 | started/success/failed/skipped |
trace_id | UUID4 | 异步操作关联标识 |
message | 字符串 | 人类可读的描述 |
context | 对象 | 操作特定的元数据 |
metrics | 对象 | 定量数据(计数、持续时间) |
error | 对象/空值 | 失败时的异常详情 |
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 找不到 loguru | 未安装 | 运行 uv add loguru |
| 日志未出现 | 日志级别错误 | 将级别设置为 DEBUG 以进行故障排除 |
| 日志轮转不工作 | 缺少轮转配置 | 向 logger.add() 添加 rotation 参数 |
| platformdirs 导入错误 | 未安装 | 运行 uv add platformdirs |
| JSONL 解析错误 | 格式错误的日志行 | 检查是否有未转义的特殊字符 |
| 日志在错误目录中 | 使用了硬编码路径 | 使用 platformdirs.user_log_dir() |
每周安装次数
144
代码仓库
GitHub 星标数
22
首次出现时间
Jan 24, 2026
安全审计
安装于
opencode134
gemini-cli131
codex128
cursor126
github-copilot122
claude-code115
Use this skill when:
Unified reference for Python logging patterns optimized for machine readability (Claude Code analysis) and operational reliability.
Prevent unbounded log growth - configure rotation for ALL log files:
# Loguru pattern (recommended for modern scripts)
from loguru import logger
logger.add(
log_path,
rotation="10 MB", # Rotate at 10MB
retention="7 days", # Keep 7 days
compression="gz" # Compress old logs
)
# RotatingFileHandler pattern (stdlib-only)
from logging.handlers import RotatingFileHandler
handler = RotatingFileHandler(
log_path,
maxBytes=100 * 1024 * 1024, # 100MB
backupCount=5 # Keep 5 backups (~500MB max)
)
Use JSONL (.jsonl) for logs that Claude Code or other tools will analyze:
# One JSON object per line - jq-parseable
{"timestamp": "2026-01-14T12:45:23.456Z", "level": "info", "message": "..."}
{"timestamp": "2026-01-14T12:45:24.789Z", "level": "error", "message": "..."}
File extension : Always use .jsonl (not .json or .log)
Validation : cat file.jsonl | jq -c .
Terminology : JSONL is canonical. Equivalent terms: NDJSON, JSON Lines.
| Approach | Use Case | Pros | Cons |
|---|---|---|---|
loguru | Modern scripts, CLI tools | Zero-config, async-safe, built-in rotation | External dependency |
RotatingFileHandler | LaunchAgent daemons, stdlib-only | No dependencies | More setup |
logger_setup.py | Rich terminal apps | Beautiful output | Complex setup |
Cross-platform log directory handling with structured JSONL output:
#!/usr/bin/env python3
# /// script
# requires-python = ">=3.11"
# dependencies = ["loguru", "platformdirs"]
# ///
import json
import sys
from pathlib import Path
from uuid import uuid4
import platformdirs
from loguru import logger
def json_formatter(record) -> str:
"""JSONL formatter for Claude Code analysis."""
log_entry = {
"timestamp": record["time"].strftime("%Y-%m-%dT%H:%M:%S.%f")[:-3] + "Z",
"level": record["level"].name.lower(),
"component": record["function"],
"operation": record["extra"].get("operation", "unknown"),
"operation_status": record["extra"].get("status", None),
"trace_id": record["extra"].get("trace_id"),
"message": record["message"],
"context": {k: v for k, v in record["extra"].items()
if k not in ("operation", "status", "trace_id", "metrics")},
"metrics": record["extra"].get("metrics", {}),
"error": None
}
if record["exception"]:
exc_type, exc_value, _ = record["exception"]
log_entry["error"] = {
"type": exc_type.__name__ if exc_type else "Unknown",
"message": str(exc_value) if exc_value else "Unknown error",
}
return json.dumps(log_entry)
def setup_logger(app_name: str = "my-app"):
"""Configure Loguru for machine-readable JSONL output."""
logger.remove()
# Console output (JSONL to stderr)
logger.add(sys.stderr, format=json_formatter, level="INFO")
# Cross-platform log directory
# macOS: ~/Library/Logs/{app_name}/
# Linux: ~/.local/state/{app_name}/log/
log_dir = Path(platformdirs.user_log_dir(
appname=app_name,
ensure_exists=True
))
# File output with rotation
logger.add(
str(log_dir / f"{app_name}.jsonl"),
format=json_formatter,
rotation="10 MB",
retention="7 days",
compression="gz",
level="DEBUG"
)
return logger
# Usage
setup_logger("my-app")
trace_id = str(uuid4())
logger.info(
"Operation started",
operation="my_operation",
status="started",
trace_id=trace_id
)
logger.info(
"Operation complete",
operation="my_operation",
status="success",
trace_id=trace_id,
metrics={"duration_ms": 150, "items_processed": 42}
)
| Field | Type | Purpose |
|---|---|---|
timestamp | ISO 8601 with Z | Event ordering |
level | string | debug/info/warning/error/critical |
component | string | Module/function name |
operation | string | What action is being performed |
operation_status | string | started/success/failed/skipped |
| Issue | Cause | Solution |
|---|---|---|
| loguru not found | Not installed | Run uv add loguru |
| Logs not appearing | Wrong log level | Set level to DEBUG for troubleshooting |
| Log rotation not working | Missing rotation config | Add rotation param to logger.add() |
| platformdirs import error | Not installed | Run uv add platformdirs |
| JSONL parse errors | Malformed log line | Check for unescaped special characters |
| Logs in wrong directory | Using hardcoded path | Use platformdirs.user_log_dir() |
Weekly Installs
144
Repository
GitHub Stars
22
First Seen
Jan 24, 2026
Security Audits
Gen Agent Trust HubPassSocketPassSnykPass
Installed on
opencode134
gemini-cli131
codex128
cursor126
github-copilot122
claude-code115
agent-browser 浏览器自动化工具 - Vercel Labs 命令行网页操作与测试
159,700 周安装
ln-780-bootstrap-verifier:项目引导验证协调器 | 构建测试容器编排与报告生成
213 周安装
Prompt Guard - AI提示注入防御系统,检测并阻止恶意指令劫持攻击
218 周安装
ln-400故事执行编排器:自动化任务执行与审核工作流,提升软件开发效率
211 周安装
Paseo委员会技能:AI代理协作解决复杂技术问题的根本原因分析与规划
212 周安装
CORS跨域配置指南:ASP.NET Core与FastAPI安全策略设置
214 周安装
ln-100-documents-pipeline:自动化文档生成流水线,一键创建完整项目文档系统
214 周安装
trace_id | UUID4 | Correlation for async operations |
message | string | Human-readable description |
context | object | Operation-specific metadata |
metrics | object | Quantitative data (counts, durations) |
error | object/null | Exception details if failed |