Metadata-Version: 2.4
Name: mlog-util
Version: 2026.4.28
Summary: 多进程安全的日志轮转工具，基于 Python logging 扩展
Requires-Python: >=3.11
Description-Content-Type: text/markdown
Requires-Dist: rich>=14.2.0
Requires-Dist: portalocker

# mlog-util

多进程安全的 Python 日志轮转工具，基于标准 `logging` 模块扩展。

## 特性

- **多进程安全轮转** — 多个进程同时写入同一日志文件，通过文件锁 (`portalocker`) + 临时文件机制保证不丢日志
- **大小轮转** — 文件达到 `maxBytes` 自动轮转，支持 `"1 M"`、`"5K"`、`"2G"` 等人类可读格式
- **时间轮转** — 按秒/分/时/天/午夜轮转，多进程共享轮转时间点
- **分级别日志** — 通过 `HandlerConfig` 为每个 handler 独立设置级别、格式、过滤条件，实现不同级别写入不同文件
- **Rich 控制台** — 默认带颜色的 Rich 控制台输出

## 安装

```bash
pip install mlog-util
```

## 快速使用

```python
from mlog_util import get_logger

# 基础用法：控制台 + 文件
logger = get_logger("my_app", log_file="app.log")
logger.info("服务启动")
```

## 多进程轮转

```python
from mlog_util import get_logger, MultiProcessSafeSizeRotatingHandler, MultiProcessSafeTimeRotatingHandler

# 大小轮转
handler = MultiProcessSafeSizeRotatingHandler("app.log", maxBytes="10 M", backupCount=5)
logger = get_logger("my_app", custom_handlers=handler)

# 时间轮转（每天）
handler = MultiProcessSafeTimeRotatingHandler("app.log", when="D", backupCount=7)
logger = get_logger("my_app", custom_handlers=handler)
```

## 分级别日志

不同级别写入不同文件：

```python
from mlog_util import get_logger, MultiProcessSafeSizeRotatingHandler
from mlog_util.log_manager import HandlerConfig, FORMAT_SIMPLE
import logging

error_handler = MultiProcessSafeSizeRotatingHandler("error.log", maxBytes="50 M")
app_handler = MultiProcessSafeSizeRotatingHandler("app.log", maxBytes="50 M")

logger = get_logger("my_app", custom_handlers=[
    HandlerConfig(error_handler, level=logging.ERROR),  # ERROR 及以上 → error.log
    HandlerConfig(app_handler, level=logging.INFO),      # INFO 及以上 → app.log
])
```

Filter 按模块名分流：

```python
class ModuleFilter(logging.Filter):
    def __init__(self, prefix):
        super().__init__()
        self.prefix = prefix
    def filter(self, record):
        return record.name.startswith(self.prefix)

logger = get_logger("my_app", custom_handlers=[
    HandlerConfig(handler, filters=[ModuleFilter("core")]),  # 只收 core.* 日志
])
```

## Formatter 样式

```python
from mlog_util.log_manager import make_formatter, FORMAT_DETAIL, FORMAT_SIMPLE, FORMAT_PLAIN, FORMAT_JSON

# 4 种预设样式
h.setFormatter(make_formatter())            # FORMAT_DETAIL: 时间 | 名称 | 级别 | 消息
h.setFormatter(make_formatter(FORMAT_SIMPLE))  # 简洁：时间 | 消息
h.setFormatter(make_formatter(FORMAT_PLAIN))   # 纯文本：名称 - 级别 - 消息
h.setFormatter(make_formatter(FORMAT_JSON))    # JSON 结构化
```

## Changelog

## [v2026.04.28]
- ✨ `log_manager` 优化
  - 提取公共 Formatter 常量：`FORMAT_DETAIL`、`FORMAT_SIMPLE`、`FORMAT_PLAIN`、`FORMAT_JSON` 和 `make_formatter()` 工厂函数
  - `custom_handlers` 支持列表和 `HandlerConfig`，可为每个 handler 单独配置级别、格式、过滤条件
  - `HandlerConfig(handler, level=ERROR, formatter=fmt, filters=[...])`
- 🐛 `handlers` 修复
  - `maxBytes` 支持 G 单位（`"2G"`）
  - `maxBytes` 解析前自动去除空格（`"1 M "` → 正确解析）
  - 修复极端并发下临时文件竞态导致的日志丢失（`_write_to_tmp` 增加文件存在性检查）
- ✨ 添加 pytest 测试套件（85 个测试），添加 `dev/` 演示脚本

## [v0.1.7] - 2025-10-28
### ✨ 添加新功能 🐛 修改Bug
- 调整 时间轮询基准时间(从 UTC 改成 本地时间)
- 新增 * *, 轮询时间和文件大小(默认按 1天 5M)

## [v2025.12.03]
- 🐛 删除 时间轮询方式
- 🐛 修改 文件大小轮询方式

## [v2025.12.11]
- ✨ 重新添加 时间轮询方式，添加测试

## [v2025.12.16]
- ♻️ 修改 format 为 "%(asctime)s | %(name)-8s | %(levelname)-4s | %(message)s"

## [v2025.12.23]
- 🧹 调整 时间轮询默认时间是 天

## [v0.1.6] - 2025-10-17
### ♻️ 调整结构
- 调整 整体结构， 修复 v0.1.4 不可用效果

## [v0.1.5] - 2025-10-17

## [v0.1.4] - 2025-10-17
### ♻️ 优化/重构
- 调整 `log_manager` 模块结构
