iboxpay-xlog 0.1.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 iboxpay / renruiquan
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,4 @@
1
+ include README.md
2
+ include LICENSE
3
+ include pyproject.toml
4
+ recursive-include src/iboxpay_xlog py.typed
@@ -0,0 +1,213 @@
1
+ Metadata-Version: 2.4
2
+ Name: iboxpay-xlog
3
+ Version: 0.1.0
4
+ Summary: iboxpay 通用日志框架:基于 Loguru 的统一格式、分文件路由与脱敏能力
5
+ Author: renruiquan
6
+ License: MIT
7
+ Project-URL: Homepage, https://pypi.org/project/iboxpay-xlog/
8
+ Project-URL: Issues, https://pypi.org/project/iboxpay-xlog/
9
+ Keywords: logging,loguru,iboxpay,structured-logging,redaction
10
+ Classifier: Development Status :: 4 - Beta
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Topic :: System :: Logging
19
+ Requires-Python: >=3.10
20
+ Description-Content-Type: text/markdown
21
+ License-File: LICENSE
22
+ Requires-Dist: loguru>=0.7.3
23
+ Provides-Extra: dev
24
+ Requires-Dist: build>=1.2.2; extra == "dev"
25
+ Requires-Dist: pytest>=8.3.0; extra == "dev"
26
+ Requires-Dist: pytest-cov>=6.0.0; extra == "dev"
27
+ Requires-Dist: twine>=5.1.0; extra == "dev"
28
+ Requires-Dist: ruff>=0.6.0; extra == "dev"
29
+ Dynamic: license-file
30
+
31
+ # iboxpay-xlog
32
+
33
+ > iboxpay 通用日志框架:基于 [Loguru](https://github.com/Delgan/loguru) 的统一格式、分文件路由与脱敏能力。
34
+
35
+ `iboxpay-xlog` 把 iboxpay 后端服务里反复用到的日志规范沉淀为一个可复用的库,让所有 Python 服务在同一套约定下输出日志:
36
+
37
+ - 类 Logback 文本格式:`[time] [thread] [level] [name] [transactionId] [spanId] [timeDiff] [serviceId] [protocol] [logType] - message`
38
+ - 标准库 `logging` 与 Loguru 自动桥接,第三方库(uvicorn、httpx 等)的输出与业务日志统一格式
39
+ - 默认 5 类文件 sink:`app` / `interface` / `access` / `error` / `remote`,按 logger 名称自动路由
40
+ - 文件按 100MB 或小时维度滚动,可关闭或调整阈值
41
+ - 内置身份证、银行卡脱敏,并避免误伤大陆手机号
42
+ - 完全 dataclass 化的 `LoggingSettings`,无侵入接入任何项目
43
+
44
+ ---
45
+
46
+ ## 安装
47
+
48
+ ```bash
49
+ pip install iboxpay-xlog
50
+ ```
51
+
52
+ 依赖:`loguru>=0.7.3`,Python `>=3.10`。
53
+
54
+ ## 快速开始
55
+
56
+ ```python
57
+ from iboxpay_xlog import configure_logging, get_logger
58
+
59
+ configure_logging()
60
+
61
+ log = get_logger(__name__)
62
+ log.info("service started")
63
+
64
+ remote_log = get_logger("remote").bind(
65
+ protocol="http",
66
+ logType="remote",
67
+ serviceId="sms-gateway",
68
+ )
69
+ remote_log.info("sms request finished")
70
+ ```
71
+
72
+ 默认行为:
73
+
74
+ - 控制台输出(`stdout`,INFO 级别)
75
+ - 文件输出到当前工作目录下的 `logs/`,子目录分别为 `app/` `interface/` `access/` `error/` `remote/`
76
+
77
+ ## 自定义配置
78
+
79
+ ```python
80
+ from pathlib import Path
81
+
82
+ from iboxpay_xlog import LoggingSettings, configure_logging
83
+
84
+ configure_logging(
85
+ LoggingSettings(
86
+ service_name="iboxpay-foo",
87
+ log_base_dir=Path("/var/log/iboxpay-foo"),
88
+ console_level="DEBUG",
89
+ rotation_max_bytes=200 * 1024 * 1024,
90
+ rotate_hourly=False,
91
+ )
92
+ )
93
+ ```
94
+
95
+ 也可以通过环境变量切换日志根目录。例如 `service_name="iboxpay-foo"` 会自动认环境变量 `IBOXPAY_FOO_LOG_BASE_DIR`:
96
+
97
+ ```bash
98
+ export IBOXPAY_FOO_LOG_BASE_DIR=/data/logs/foo
99
+ ```
100
+
101
+ 需要完全自定义文件 sink 时,传入 `LogSink` 元组:
102
+
103
+ ```python
104
+ from iboxpay_xlog import LogSink, LoggingSettings, configure_logging
105
+
106
+ configure_logging(
107
+ LoggingSettings(
108
+ service_name="iboxpay-bar",
109
+ sinks=(
110
+ LogSink(name="app", level="INFO", exclude_logger_names=frozenset({"audit"})),
111
+ LogSink(name="audit", level="INFO", include_logger_names=frozenset({"audit"})),
112
+ ),
113
+ )
114
+ )
115
+ ```
116
+
117
+ 仅希望输出到控制台时关闭文件输出:
118
+
119
+ ```python
120
+ configure_logging(LoggingSettings(enable_file_logging=False))
121
+ ```
122
+
123
+ ## 脱敏
124
+
125
+ ```python
126
+ from iboxpay_xlog import redact_log_text, redact_log_value
127
+
128
+ redact_log_text("user 110101199003078888 paid via 6222021234567890123")
129
+ # 'user 110101******8888 paid via 622202*********0123'
130
+
131
+ redact_log_value({"id_card": "110101199003078888", "phone": "13800138000"})
132
+ # {'id_card': '110101******8888', 'phone': '13800138000'}
133
+ ```
134
+
135
+ - 身份证、银行卡保留前 6 位与后 4 位
136
+ - 11 位以 `1[3-9]` 开头的大陆手机号 **不** 脱敏
137
+
138
+ ## 与标准库 logging 协同
139
+
140
+ `configure_logging()` 默认会把根 logger 的 handler 替换为内置的 `InterceptHandler`,并:
141
+
142
+ - 将 `httpx` 调整为 `WARNING` 级别(可通过 `silenced_loggers` 覆盖)
143
+ - 把 `uvicorn`、`uvicorn.error` 桥接进 Loguru
144
+ - 禁用 `uvicorn.access`,由你自行用 `get_logger("access")` 控制访问日志
145
+
146
+ 如需关闭桥接:
147
+
148
+ ```python
149
+ configure_logging(LoggingSettings(intercept_stdlib=False))
150
+ ```
151
+
152
+ ## 自动记录请求/响应报文(伴生包)
153
+
154
+ `iboxpay-xlog` 本身只做日志框架,不绑定任何 Web 框架或 HTTP 客户端。需要“开箱即用”的请求/响应自动记录,可直接安装两个伴生包:
155
+
156
+ | 包 | 作用 |
157
+ |---|---|
158
+ | [`iboxpay-xlog-fastapi`](https://pypi.org/project/iboxpay-xlog-fastapi/) | FastAPI/Starlette `HttpLoggingMiddleware`,自动记录入站请求体、响应体、`X-Request-ID`、耗时 |
159
+ | [`iboxpay-xlog-httpx`](https://pypi.org/project/iboxpay-xlog-httpx/) | httpx 事件钩子,自动把出站 HTTP 调用写入 `remote` 日志 |
160
+
161
+ ```bash
162
+ pip install iboxpay-xlog iboxpay-xlog-fastapi iboxpay-xlog-httpx
163
+ ```
164
+
165
+ ```python
166
+ import httpx
167
+ from fastapi import FastAPI
168
+ from iboxpay_xlog import configure_logging
169
+ from iboxpay_xlog_fastapi import HttpLoggingMiddleware
170
+ from iboxpay_xlog_httpx import attach_logging
171
+
172
+ configure_logging()
173
+
174
+ app = FastAPI()
175
+ app.add_middleware(HttpLoggingMiddleware)
176
+
177
+ sms_client = attach_logging(httpx.Client(), service_id="sms-gateway")
178
+ ```
179
+
180
+ ## 测试
181
+
182
+ ```python
183
+ from iboxpay_xlog import configure_logging, get_logger
184
+ from iboxpay_xlog.testing import capture_records
185
+
186
+ configure_logging()
187
+ with capture_records() as records:
188
+ get_logger("demo").info("hi")
189
+
190
+ assert records[-1]["message"] == "hi"
191
+ ```
192
+
193
+ ## 重置 / 重新配置
194
+
195
+ ```python
196
+ from iboxpay_xlog import configure_logging, reset_logging_for_tests
197
+
198
+ reset_logging_for_tests()
199
+ configure_logging(new_settings)
200
+ ```
201
+
202
+ ## 本地开发
203
+
204
+ ```bash
205
+ pip install -e ".[dev]"
206
+ pytest
207
+ python -m build
208
+ twine check dist/*
209
+ ```
210
+
211
+ ## License
212
+
213
+ MIT
@@ -0,0 +1,183 @@
1
+ # iboxpay-xlog
2
+
3
+ > iboxpay 通用日志框架:基于 [Loguru](https://github.com/Delgan/loguru) 的统一格式、分文件路由与脱敏能力。
4
+
5
+ `iboxpay-xlog` 把 iboxpay 后端服务里反复用到的日志规范沉淀为一个可复用的库,让所有 Python 服务在同一套约定下输出日志:
6
+
7
+ - 类 Logback 文本格式:`[time] [thread] [level] [name] [transactionId] [spanId] [timeDiff] [serviceId] [protocol] [logType] - message`
8
+ - 标准库 `logging` 与 Loguru 自动桥接,第三方库(uvicorn、httpx 等)的输出与业务日志统一格式
9
+ - 默认 5 类文件 sink:`app` / `interface` / `access` / `error` / `remote`,按 logger 名称自动路由
10
+ - 文件按 100MB 或小时维度滚动,可关闭或调整阈值
11
+ - 内置身份证、银行卡脱敏,并避免误伤大陆手机号
12
+ - 完全 dataclass 化的 `LoggingSettings`,无侵入接入任何项目
13
+
14
+ ---
15
+
16
+ ## 安装
17
+
18
+ ```bash
19
+ pip install iboxpay-xlog
20
+ ```
21
+
22
+ 依赖:`loguru>=0.7.3`,Python `>=3.10`。
23
+
24
+ ## 快速开始
25
+
26
+ ```python
27
+ from iboxpay_xlog import configure_logging, get_logger
28
+
29
+ configure_logging()
30
+
31
+ log = get_logger(__name__)
32
+ log.info("service started")
33
+
34
+ remote_log = get_logger("remote").bind(
35
+ protocol="http",
36
+ logType="remote",
37
+ serviceId="sms-gateway",
38
+ )
39
+ remote_log.info("sms request finished")
40
+ ```
41
+
42
+ 默认行为:
43
+
44
+ - 控制台输出(`stdout`,INFO 级别)
45
+ - 文件输出到当前工作目录下的 `logs/`,子目录分别为 `app/` `interface/` `access/` `error/` `remote/`
46
+
47
+ ## 自定义配置
48
+
49
+ ```python
50
+ from pathlib import Path
51
+
52
+ from iboxpay_xlog import LoggingSettings, configure_logging
53
+
54
+ configure_logging(
55
+ LoggingSettings(
56
+ service_name="iboxpay-foo",
57
+ log_base_dir=Path("/var/log/iboxpay-foo"),
58
+ console_level="DEBUG",
59
+ rotation_max_bytes=200 * 1024 * 1024,
60
+ rotate_hourly=False,
61
+ )
62
+ )
63
+ ```
64
+
65
+ 也可以通过环境变量切换日志根目录。例如 `service_name="iboxpay-foo"` 会自动认环境变量 `IBOXPAY_FOO_LOG_BASE_DIR`:
66
+
67
+ ```bash
68
+ export IBOXPAY_FOO_LOG_BASE_DIR=/data/logs/foo
69
+ ```
70
+
71
+ 需要完全自定义文件 sink 时,传入 `LogSink` 元组:
72
+
73
+ ```python
74
+ from iboxpay_xlog import LogSink, LoggingSettings, configure_logging
75
+
76
+ configure_logging(
77
+ LoggingSettings(
78
+ service_name="iboxpay-bar",
79
+ sinks=(
80
+ LogSink(name="app", level="INFO", exclude_logger_names=frozenset({"audit"})),
81
+ LogSink(name="audit", level="INFO", include_logger_names=frozenset({"audit"})),
82
+ ),
83
+ )
84
+ )
85
+ ```
86
+
87
+ 仅希望输出到控制台时关闭文件输出:
88
+
89
+ ```python
90
+ configure_logging(LoggingSettings(enable_file_logging=False))
91
+ ```
92
+
93
+ ## 脱敏
94
+
95
+ ```python
96
+ from iboxpay_xlog import redact_log_text, redact_log_value
97
+
98
+ redact_log_text("user 110101199003078888 paid via 6222021234567890123")
99
+ # 'user 110101******8888 paid via 622202*********0123'
100
+
101
+ redact_log_value({"id_card": "110101199003078888", "phone": "13800138000"})
102
+ # {'id_card': '110101******8888', 'phone': '13800138000'}
103
+ ```
104
+
105
+ - 身份证、银行卡保留前 6 位与后 4 位
106
+ - 11 位以 `1[3-9]` 开头的大陆手机号 **不** 脱敏
107
+
108
+ ## 与标准库 logging 协同
109
+
110
+ `configure_logging()` 默认会把根 logger 的 handler 替换为内置的 `InterceptHandler`,并:
111
+
112
+ - 将 `httpx` 调整为 `WARNING` 级别(可通过 `silenced_loggers` 覆盖)
113
+ - 把 `uvicorn`、`uvicorn.error` 桥接进 Loguru
114
+ - 禁用 `uvicorn.access`,由你自行用 `get_logger("access")` 控制访问日志
115
+
116
+ 如需关闭桥接:
117
+
118
+ ```python
119
+ configure_logging(LoggingSettings(intercept_stdlib=False))
120
+ ```
121
+
122
+ ## 自动记录请求/响应报文(伴生包)
123
+
124
+ `iboxpay-xlog` 本身只做日志框架,不绑定任何 Web 框架或 HTTP 客户端。需要“开箱即用”的请求/响应自动记录,可直接安装两个伴生包:
125
+
126
+ | 包 | 作用 |
127
+ |---|---|
128
+ | [`iboxpay-xlog-fastapi`](https://pypi.org/project/iboxpay-xlog-fastapi/) | FastAPI/Starlette `HttpLoggingMiddleware`,自动记录入站请求体、响应体、`X-Request-ID`、耗时 |
129
+ | [`iboxpay-xlog-httpx`](https://pypi.org/project/iboxpay-xlog-httpx/) | httpx 事件钩子,自动把出站 HTTP 调用写入 `remote` 日志 |
130
+
131
+ ```bash
132
+ pip install iboxpay-xlog iboxpay-xlog-fastapi iboxpay-xlog-httpx
133
+ ```
134
+
135
+ ```python
136
+ import httpx
137
+ from fastapi import FastAPI
138
+ from iboxpay_xlog import configure_logging
139
+ from iboxpay_xlog_fastapi import HttpLoggingMiddleware
140
+ from iboxpay_xlog_httpx import attach_logging
141
+
142
+ configure_logging()
143
+
144
+ app = FastAPI()
145
+ app.add_middleware(HttpLoggingMiddleware)
146
+
147
+ sms_client = attach_logging(httpx.Client(), service_id="sms-gateway")
148
+ ```
149
+
150
+ ## 测试
151
+
152
+ ```python
153
+ from iboxpay_xlog import configure_logging, get_logger
154
+ from iboxpay_xlog.testing import capture_records
155
+
156
+ configure_logging()
157
+ with capture_records() as records:
158
+ get_logger("demo").info("hi")
159
+
160
+ assert records[-1]["message"] == "hi"
161
+ ```
162
+
163
+ ## 重置 / 重新配置
164
+
165
+ ```python
166
+ from iboxpay_xlog import configure_logging, reset_logging_for_tests
167
+
168
+ reset_logging_for_tests()
169
+ configure_logging(new_settings)
170
+ ```
171
+
172
+ ## 本地开发
173
+
174
+ ```bash
175
+ pip install -e ".[dev]"
176
+ pytest
177
+ python -m build
178
+ twine check dist/*
179
+ ```
180
+
181
+ ## License
182
+
183
+ MIT
@@ -0,0 +1,58 @@
1
+ [build-system]
2
+ requires = ["setuptools>=75", "wheel"]
3
+ build-backend = "setuptools.build_meta"
4
+
5
+ [project]
6
+ name = "iboxpay-xlog"
7
+ version = "0.1.0"
8
+ description = "iboxpay 通用日志框架:基于 Loguru 的统一格式、分文件路由与脱敏能力"
9
+ readme = "README.md"
10
+ license = { text = "MIT" }
11
+ requires-python = ">=3.10"
12
+ authors = [{ name = "renruiquan" }]
13
+ keywords = ["logging", "loguru", "iboxpay", "structured-logging", "redaction"]
14
+ classifiers = [
15
+ "Development Status :: 4 - Beta",
16
+ "Intended Audience :: Developers",
17
+ "License :: OSI Approved :: MIT License",
18
+ "Operating System :: OS Independent",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.10",
21
+ "Programming Language :: Python :: 3.11",
22
+ "Programming Language :: Python :: 3.12",
23
+ "Topic :: System :: Logging",
24
+ ]
25
+ dependencies = [
26
+ "loguru>=0.7.3",
27
+ ]
28
+
29
+ [project.optional-dependencies]
30
+ dev = [
31
+ "build>=1.2.2",
32
+ "pytest>=8.3.0",
33
+ "pytest-cov>=6.0.0",
34
+ "twine>=5.1.0",
35
+ "ruff>=0.6.0",
36
+ ]
37
+
38
+ [project.urls]
39
+ Homepage = "https://pypi.org/project/iboxpay-xlog/"
40
+ Issues = "https://pypi.org/project/iboxpay-xlog/"
41
+
42
+ [tool.setuptools.packages.find]
43
+ where = ["src"]
44
+ include = ["iboxpay_xlog*"]
45
+
46
+ [tool.setuptools.package-data]
47
+ iboxpay_xlog = ["py.typed"]
48
+
49
+ [tool.pytest.ini_options]
50
+ addopts = "-ra"
51
+ testpaths = ["tests"]
52
+
53
+ [tool.ruff]
54
+ line-length = 120
55
+ target-version = "py310"
56
+
57
+ [tool.ruff.lint]
58
+ select = ["E", "F", "I", "B", "UP"]
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+
@@ -0,0 +1,65 @@
1
+ """iboxpay-xlog 公共日志框架。
2
+
3
+ 对外暴露的核心 API:
4
+
5
+ - :func:`configure_logging`:幂等初始化整个日志系统。
6
+ - :func:`get_logger`:按业务名称取得绑定后的 Loguru logger。
7
+ - :func:`reset_logging_for_tests`:清空状态以便重新配置或在测试中复用。
8
+ - :data:`logger`:底层已经 ``patch`` 默认 extra 的 Loguru logger 实例。
9
+ - :class:`LoggingSettings` / :class:`LogSink`:配置数据类。
10
+ - :func:`redact_log_text` / :func:`redact_log_value`:脱敏工具。
11
+ - :class:`InterceptHandler`:将 stdlib ``logging`` 桥接到 Loguru 的处理器。
12
+ """
13
+
14
+ from __future__ import annotations
15
+
16
+ from iboxpay_xlog.config import (
17
+ DEFAULT_DISABLED_LOGGERS,
18
+ DEFAULT_EXTRA_FIELDS,
19
+ DEFAULT_INTERCEPT_LOGGERS,
20
+ DEFAULT_LOG_FORMAT,
21
+ DEFAULT_ROTATION_MAX_BYTES,
22
+ DEFAULT_SILENCED_LOGGERS,
23
+ LoggingSettings,
24
+ LogSink,
25
+ default_log_sinks,
26
+ )
27
+ from iboxpay_xlog.intercept import InterceptHandler
28
+ from iboxpay_xlog.logger import (
29
+ configure_logging,
30
+ current_settings,
31
+ get_logger,
32
+ logger,
33
+ reset_logging_for_tests,
34
+ )
35
+ from iboxpay_xlog.redaction import (
36
+ BANK_CARD_PATTERN,
37
+ ID_CARD_PATTERN,
38
+ redact_log_text,
39
+ redact_log_value,
40
+ )
41
+
42
+ __all__ = [
43
+ "BANK_CARD_PATTERN",
44
+ "DEFAULT_DISABLED_LOGGERS",
45
+ "DEFAULT_EXTRA_FIELDS",
46
+ "DEFAULT_INTERCEPT_LOGGERS",
47
+ "DEFAULT_LOG_FORMAT",
48
+ "DEFAULT_ROTATION_MAX_BYTES",
49
+ "DEFAULT_SILENCED_LOGGERS",
50
+ "ID_CARD_PATTERN",
51
+ "InterceptHandler",
52
+ "LogSink",
53
+ "LoggingSettings",
54
+ "__version__",
55
+ "configure_logging",
56
+ "current_settings",
57
+ "default_log_sinks",
58
+ "get_logger",
59
+ "logger",
60
+ "redact_log_text",
61
+ "redact_log_value",
62
+ "reset_logging_for_tests",
63
+ ]
64
+
65
+ __version__ = "0.1.0"