aury-boot 0.0.8__py3-none-any.whl → 0.0.10__py3-none-any.whl

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.
aury/boot/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.0.8'
32
- __version_tuple__ = version_tuple = (0, 0, 8)
31
+ __version__ = version = '0.0.10'
32
+ __version_tuple__ = version_tuple = (0, 0, 10)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -203,6 +203,7 @@ class FoundationApp(FastAPI):
203
203
  title: str = "Aury Service",
204
204
  version: str = "1.0.0",
205
205
  description: str | None = None,
206
+ intercept_loggers: list[str] | None = None,
206
207
  **kwargs: Any,
207
208
  ) -> None:
208
209
  """初始化应用。
@@ -212,6 +213,9 @@ class FoundationApp(FastAPI):
212
213
  title: 应用标题
213
214
  version: 应用版本
214
215
  description: 应用描述
216
+ intercept_loggers: 额外需要拦截的标准 logging logger 名称列表,
217
+ 会追加到框架默认列表 (uvicorn, sqlalchemy.engine 等)。
218
+ 也可通过配置 LOG__INTERCEPT_LOGGERS 设置。
215
219
  **kwargs: 传递给 FastAPI 的其他参数
216
220
  """
217
221
  # 加载配置
@@ -223,6 +227,11 @@ class FoundationApp(FastAPI):
223
227
  frame = sys._getframe(1)
224
228
  self._caller_module = frame.f_globals.get("__name__", "__main__")
225
229
 
230
+ # 合并 intercept_loggers:参数 + 配置
231
+ merged_intercept = list(config.log.intercept_loggers)
232
+ if intercept_loggers:
233
+ merged_intercept.extend(intercept_loggers)
234
+
226
235
  # 初始化日志(必须在其他操作之前)
227
236
  setup_logging(
228
237
  log_level=config.log.level,
@@ -232,6 +241,7 @@ class FoundationApp(FastAPI):
232
241
  retention_days=config.log.retention_days,
233
242
  enable_file_rotation=config.log.enable_file_rotation,
234
243
  enable_console=config.log.enable_console,
244
+ intercept_loggers=merged_intercept,
235
245
  )
236
246
 
237
247
  # 注册 access 日志(HTTP 请求日志)
@@ -372,6 +372,14 @@ class LogSettings(BaseModel):
372
372
  default=False,
373
373
  description="是否记录 WebSocket 消息内容(注意性能和敏感数据)"
374
374
  )
375
+ intercept_loggers: list[str] = Field(
376
+ default_factory=list,
377
+ description=(
378
+ "额外需要由 loguru 接管的标准 logging logger 名称列表。"
379
+ "框架默认已拦截 uvicorn、uvicorn.error、uvicorn.access、sqlalchemy.engine,"
380
+ "此处配置会追加到默认列表。"
381
+ ),
382
+ )
375
383
 
376
384
 
377
385
  class ServiceSettings(BaseModel):
@@ -16,3 +16,5 @@
16
16
  # LOG__ENABLE_FILE_ROTATION=true
17
17
  # 是否输出日志到控制台
18
18
  # LOG__ENABLE_CONSOLE=true
19
+ # 额外需要拦截的标准 logging logger (默认已拦截 uvicorn、sqlalchemy.engine)
20
+ # LOG__INTERCEPT_LOGGERS=["my_package", "third_party_lib"]
@@ -2,7 +2,7 @@
2
2
  # =============================================================================
3
3
  # RPC 客户端配置 (RPC_CLIENT__)
4
4
  # =============================================================================
5
- # 服务地址映射 {service_name: url}
5
+ # 服务地址映射 {{service_name: url}}
6
6
  # RPC_CLIENT__SERVICES={{"user-service": "http://localhost:8001"}}
7
7
  # 默认超时时间(秒)
8
8
  # RPC_CLIENT__DEFAULT_TIMEOUT=30
@@ -25,11 +25,15 @@ config = AppConfig()
25
25
  # - HEALTH_CHECK_PATH: 健康检查路径(默认 /api/health)
26
26
  # - HEALTH_CHECK_ENABLED: 是否启用(默认 true)
27
27
  #
28
+ # 日志拦截:
29
+ # 框架默认拦截 uvicorn/sqlalchemy.engine,可通过 intercept_loggers 追加额外的 logger
30
+ #
28
31
  app = FoundationApp(
29
32
  title="{project_name}",
30
33
  version="0.1.0",
31
34
  description="{project_name} - 基于 Aury Boot",
32
35
  config=config,
36
+ intercept_loggers=[],
33
37
  )
34
38
 
35
39
  # 注册 API 路由
@@ -44,11 +44,14 @@ from aury.boot.common.logging.format import (
44
44
  log_exception,
45
45
  )
46
46
  from aury.boot.common.logging.setup import (
47
+ DEFAULT_INTERCEPT_LOGGERS,
47
48
  register_log_sink,
49
+ setup_intercept,
48
50
  setup_logging,
49
51
  )
50
52
 
51
53
  __all__ = [
54
+ "DEFAULT_INTERCEPT_LOGGERS",
52
55
  "ServiceContext",
53
56
  "format_exception_java_style",
54
57
  "get_class_logger",
@@ -63,6 +66,7 @@ __all__ = [
63
66
  "register_request_context",
64
67
  "set_service_context",
65
68
  "set_trace_id",
69
+ "setup_intercept",
66
70
  "setup_logging",
67
71
  ]
68
72
 
@@ -5,6 +5,7 @@
5
5
 
6
6
  from __future__ import annotations
7
7
 
8
+ import logging
8
9
  import os
9
10
  from typing import Any
10
11
 
@@ -88,6 +89,70 @@ def register_log_sink(
88
89
  logger.debug(f"注册日志 sink: {name} (filter_key={filter_key})")
89
90
 
90
91
 
92
+ # 默认拦截的标准 logging 日志记录器
93
+ # - uvicorn: Uvicorn 服务器日志
94
+ # - uvicorn.error: Uvicorn 错误日志
95
+ # - sqlalchemy.engine: SQLAlchemy SQL 语句日志
96
+ # 注意:uvicorn.access 不拦截,因为框架有自己的 RequestLoggingMiddleware
97
+ DEFAULT_INTERCEPT_LOGGERS = [
98
+ "uvicorn",
99
+ "uvicorn.error",
100
+ "sqlalchemy.engine",
101
+ ]
102
+
103
+
104
+ class _InterceptHandler(logging.Handler):
105
+ """将标准 logging 日志转发到 loguru 的处理器。"""
106
+
107
+ def emit(self, record: logging.LogRecord) -> None:
108
+ # 获取对应的 loguru 级别
109
+ try:
110
+ level = logger.level(record.levelname).name
111
+ except ValueError:
112
+ level = record.levelno
113
+
114
+ # 查找调用者的帧深度
115
+ frame, depth = logging.currentframe(), 2
116
+ while frame and frame.f_code.co_filename == logging.__file__:
117
+ frame = frame.f_back
118
+ depth += 1
119
+
120
+ logger.opt(depth=depth, exception=record.exc_info).log(
121
+ level, record.getMessage()
122
+ )
123
+
124
+
125
+ def _setup_intercept(logger_names: list[str]) -> None:
126
+ """让 loguru 接管指定的标准 logging 日志记录器。"""
127
+ handler = _InterceptHandler()
128
+ for name in logger_names:
129
+ std_logger = logging.getLogger(name)
130
+ std_logger.handlers = [handler]
131
+ std_logger.setLevel(logging.DEBUG)
132
+ std_logger.propagate = False
133
+
134
+
135
+ def setup_intercept(logger_names: list[str] | None = None) -> None:
136
+ """拦截标准 logging 日志记录器并转发到 loguru。
137
+
138
+ 用于独立脚本/CLI 入口点(不使用 FoundationApp 时)。
139
+ FoundationApp 会自动调用此函数,无需手动调用。
140
+
141
+ Args:
142
+ logger_names: 额外需要拦截的 logger 名称列表,
143
+ 会追加到默认列表 (uvicorn, sqlalchemy.engine 等)。
144
+
145
+ 使用示例::
146
+
147
+ from aury.boot.common.logging import setup_logging, setup_intercept
148
+
149
+ setup_logging(log_level="DEBUG")
150
+ setup_intercept(["my_package", "third_party_lib"])
151
+ """
152
+ to_intercept = DEFAULT_INTERCEPT_LOGGERS + (logger_names or [])
153
+ _setup_intercept(to_intercept)
154
+
155
+
91
156
  def setup_logging(
92
157
  log_level: str = "INFO",
93
158
  log_dir: str | None = None,
@@ -97,6 +162,7 @@ def setup_logging(
97
162
  retention_days: int = 7,
98
163
  rotation_size: str = "50 MB",
99
164
  enable_console: bool = True,
165
+ intercept_loggers: list[str] | None = None,
100
166
  ) -> None:
101
167
  """设置日志配置。
102
168
 
@@ -119,6 +185,8 @@ def setup_logging(
119
185
  retention_days: 日志保留天数(默认:7 天)
120
186
  rotation_size: 单文件大小上限(默认:50 MB)
121
187
  enable_console: 是否输出到控制台
188
+ intercept_loggers: 额外需要拦截的标准 logging logger 名称列表,
189
+ 会追加到默认列表 (uvicorn, sqlalchemy.engine 等)。
122
190
  """
123
191
  log_level = log_level.upper()
124
192
  log_dir = log_dir or "logs"
@@ -205,10 +273,16 @@ def setup_logging(
205
273
  filter=lambda record, c=ctx: record["extra"].get("service") == c,
206
274
  )
207
275
 
276
+ # 拦截标准 logging 日志并转发到 loguru
277
+ to_intercept = DEFAULT_INTERCEPT_LOGGERS + (intercept_loggers or [])
278
+ _setup_intercept(to_intercept)
279
+
208
280
  logger.info(f"日志系统初始化完成 | 服务: {service_type} | 级别: {log_level} | 目录: {log_dir}")
209
281
 
210
282
 
211
283
  __all__ = [
284
+ "DEFAULT_INTERCEPT_LOGGERS",
212
285
  "register_log_sink",
286
+ "setup_intercept",
213
287
  "setup_logging",
214
288
  ]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aury-boot
3
- Version: 0.0.8
3
+ Version: 0.0.10
4
4
  Summary: Aury Boot - 基于 FastAPI 生态的企业级 API 开发框架
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: alembic>=1.17.2
@@ -1,5 +1,5 @@
1
1
  aury/boot/__init__.py,sha256=pCno-EInnpIBa1OtxNYF-JWf9j95Cd2h6vmu0xqa_-4,1791
2
- aury/boot/_version.py,sha256=j-ar4gJGiWIawqKXhvv9hGJWLfwu0tISl-0GV97B7a0,704
2
+ aury/boot/_version.py,sha256=qWM7tuFjLDSZffhqImvB3QeSymOYGxPQLtsW7Q2jQD0,706
3
3
  aury/boot/application/__init__.py,sha256=0o_XmiwFCeAu06VHggS8I1e7_nSMoRq0Hcm0fYfCywU,3071
4
4
  aury/boot/application/adapter/__init__.py,sha256=e1bcSb1bxUMfofTwiCuHBZJk5-STkMCWPF2EJXHQ7UU,3976
5
5
  aury/boot/application/adapter/base.py,sha256=Ar_66fiHPDEmV-1DKnqXKwc53p3pozG31bgTJTEUriY,15763
@@ -8,13 +8,13 @@ aury/boot/application/adapter/decorators.py,sha256=yyGu_16bWWUiO36gxCeQWgG0DN19p
8
8
  aury/boot/application/adapter/exceptions.py,sha256=Kzm-ytRxdUnSMIcWCSOHPxo4Jh_A6YbyxlOVIUs-5F4,6183
9
9
  aury/boot/application/adapter/http.py,sha256=4TADsSzdSRU63307dmmo-2U_JpVP12mwTFy66B5Ps-w,10759
10
10
  aury/boot/application/app/__init__.py,sha256=I8FfCKDuDQsGzAK6BevyfdtAwieMUVYu6qgVQzBazpE,830
11
- aury/boot/application/app/base.py,sha256=5v7wtksCCyp_QYVpxddd9xSujoVp1zX9pP6CPy4vwUE,16711
11
+ aury/boot/application/app/base.py,sha256=wBF7q_kZp5uWUeWy95oElBAsc43xJ4RZ1s6tMGIiCac,17253
12
12
  aury/boot/application/app/components.py,sha256=tt4a4ZVcRJZbvStj5W9AYf9omGqKVu0qFu5pn1q2VSU,20312
13
13
  aury/boot/application/app/middlewares.py,sha256=BXe2H14FHzJUVpQM6DZUm-zfZRXSXIi1QIZ4_3izfHw,3306
14
14
  aury/boot/application/app/startup.py,sha256=bkRT4cCzXPnTOBSNs-TLcKvFGwqBgwXeO8_gQq9Gc1s,7895
15
15
  aury/boot/application/config/__init__.py,sha256=Dd-myRSBCM18DXXsi863h0cJG5VFrI10xMRtjnvelGo,1894
16
16
  aury/boot/application/config/multi_instance.py,sha256=RXSp-xP8-bKMDEhq3SeL7T3lS8-vpRlvBEVBuZVjVK4,6475
17
- aury/boot/application/config/settings.py,sha256=n2VorLbdmiY2uKSIbZJYSrEKkUq043FpnGWaXIxhWSI,29195
17
+ aury/boot/application/config/settings.py,sha256=CckslmXl0H1XN58DKK4IBK9WqKX72nhDSIpx0dxtFPA,29544
18
18
  aury/boot/application/constants/__init__.py,sha256=DCXs13_VVaQWHqO-qpJoZwRd7HIexiirtw_nu8msTXE,340
19
19
  aury/boot/application/constants/components.py,sha256=hDRs3YxpnfIFcGaUa1DYqBRwmV2_dceOlcCXabHE3fk,1006
20
20
  aury/boot/application/constants/scheduler.py,sha256=S77FBIvHlyruvlabRWZJ2J1YAs2xWXPQI2yuGdGUDNA,471
@@ -66,7 +66,7 @@ aury/boot/commands/templates/project/admin_console_init.py.tpl,sha256=K81L14thyE
66
66
  aury/boot/commands/templates/project/config.py.tpl,sha256=ZCZHHvTOv3dm0VcJqmqkvoIEzKoBBcfne_UYnqimc7s,869
67
67
  aury/boot/commands/templates/project/conftest.py.tpl,sha256=chbETK81Hy26cWz6YZ2cFgy7HbnABzYCqeyMzgpa3eI,726
68
68
  aury/boot/commands/templates/project/gitignore.tpl,sha256=OI0nt9u2E9EC-jAMoh3gpqamsWo18uDgyPybgee_snQ,3053
69
- aury/boot/commands/templates/project/main.py.tpl,sha256=qKKgO3btMPIpPfb-iyCD4AMEYMUunhq6GJyA2QplGZI,922
69
+ aury/boot/commands/templates/project/main.py.tpl,sha256=Q61ve3o1VkNPv8wcQK7lUosne18JWYeItxoXVNNoYJM,1070
70
70
  aury/boot/commands/templates/project/aury_docs/00-overview.md.tpl,sha256=8Aept3yEAe9cVdRvkddr_oEF-lr2riPXYRzBuw_6DBA,2138
71
71
  aury/boot/commands/templates/project/aury_docs/01-model.md.tpl,sha256=1mQ3hGDxqEZjev4CD5-3dzYRFVonPNcAaStI1UBEUyM,6811
72
72
  aury/boot/commands/templates/project/aury_docs/02-repository.md.tpl,sha256=yfKPYZ7x74BEF7wFp9u3S7xKr4Ld9MqXOItGZo5NM9Q,6819
@@ -89,9 +89,9 @@ aury/boot/commands/templates/project/env_templates/_header.tpl,sha256=Pt0X_I25o1
89
89
  aury/boot/commands/templates/project/env_templates/admin.tpl,sha256=wWt3iybOpBHtuw6CkoUJ1bzEL0aNgOzKDEkMKhI2oag,2032
90
90
  aury/boot/commands/templates/project/env_templates/cache.tpl,sha256=_sK-p_FECj4mVvggNvgb4Wu0yGii0Ocz560syG7DU2c,498
91
91
  aury/boot/commands/templates/project/env_templates/database.tpl,sha256=2lWzTKt4X0SpeBBCkrDV90Di4EfoAuqYzhVsh74vTUI,907
92
- aury/boot/commands/templates/project/env_templates/log.tpl,sha256=Rw1yQ9xYvjoXHEqahDuCYzuaV2A2U9G98gmZ85k30RQ,604
92
+ aury/boot/commands/templates/project/env_templates/log.tpl,sha256=x5rkrEFJISH0gaCcr-wTCbDYtyFnlLNJpY789fqjZgc,754
93
93
  aury/boot/commands/templates/project/env_templates/messaging.tpl,sha256=ICRLGw2FtJ0bNtkHnpy0CFyILqxOfFLbfejdFLJuuo8,1719
94
- aury/boot/commands/templates/project/env_templates/rpc.tpl,sha256=Eh3UeBl5SWmvclAPt9TgVVV0pvqwr2BsuTNrY1lbgi8,1161
94
+ aury/boot/commands/templates/project/env_templates/rpc.tpl,sha256=FhweCFakawGLSs01a_BkmZo11UhWax2-VCBudHj68WA,1163
95
95
  aury/boot/commands/templates/project/env_templates/scheduler.tpl,sha256=c8Grcs1rgBB58RHlxqmDMPHQl8BnbcqNW473ctmsojU,752
96
96
  aury/boot/commands/templates/project/env_templates/service.tpl,sha256=b-a2GyRyoaunbDj_2kaSw3OFxcugscmPvUBG7w0XO8c,710
97
97
  aury/boot/commands/templates/project/env_templates/storage.tpl,sha256=x983u0Y2AFTTO2JqtPsYmYKBNGXtGCknA4iHv0k2wSA,1330
@@ -104,11 +104,11 @@ aury/boot/common/__init__.py,sha256=MhNP3c_nwx8CyDkDF6p1f4DcTZ1CZZScg66FWdbdaZI,
104
104
  aury/boot/common/exceptions/__init__.py,sha256=aS3rIXWc5qNNJbfMs_PNmBlFsyNdKUMErziNMd1yoB8,3176
105
105
  aury/boot/common/i18n/__init__.py,sha256=2cy4kteU-1YsAHkuMDTr2c5o4G33fvtYUGKtzEy1Q6c,394
106
106
  aury/boot/common/i18n/translator.py,sha256=_vEDL2SjEI1vwMNHbnJb0xErKUPLm7VmhyOuMBeCqRM,8412
107
- aury/boot/common/logging/__init__.py,sha256=lRbIZCeKavzO90Fx7FrGW1AAqAg8TX5VrDo0pWA4Af0,1661
107
+ aury/boot/common/logging/__init__.py,sha256=s6kKuAADP_mE7esZjJS5yrJwqgV24Lzn39BDv9s_HOc,1769
108
108
  aury/boot/common/logging/context.py,sha256=WHPpfqHH0HIbaSPdpESjB5kV344ygDfrdrcOmDXz1JI,3842
109
109
  aury/boot/common/logging/decorators.py,sha256=UaGMhRJdARNJ2VgCuRwaNX0DD5wIc1gAl6NDj7u8K2c,3354
110
110
  aury/boot/common/logging/format.py,sha256=V1VoZCPFAaAXy20n3WehOsZGTHuboYMHnSFGa0GxhdU,9648
111
- aury/boot/common/logging/setup.py,sha256=XPeoyFeIrsX8GbAFhBMccm_t1Zlh7_RcDl4_CqRLZtk,6864
111
+ aury/boot/common/logging/setup.py,sha256=ZPxOHJD8Fw4KxKPgsf8ZHQ2mWuXxKh4EJtXXvGY7Hgo,9422
112
112
  aury/boot/contrib/__init__.py,sha256=fyk_St9VufIx64hsobv9EsOYzb_T5FbJHxjqtPds4g8,198
113
113
  aury/boot/contrib/admin_console/__init__.py,sha256=HEesLFrtYtBFWTDrh5H3mR-4V4LRg5N4a2a1C4-Whgs,445
114
114
  aury/boot/contrib/admin_console/auth.py,sha256=_goyjZ8Clssvmy8g84svenGfBqCe9OC5pIvCjIzt42g,4706
@@ -191,7 +191,7 @@ aury/boot/testing/client.py,sha256=KOg1EemuIVsBG68G5y0DjSxZGcIQVdWQ4ASaHE3o1R0,4
191
191
  aury/boot/testing/factory.py,sha256=8GvwX9qIDu0L65gzJMlrWB0xbmJ-7zPHuwk3eECULcg,5185
192
192
  aury/boot/toolkit/__init__.py,sha256=AcyVb9fDf3CaEmJPNkWC4iGv32qCPyk4BuFKSuNiJRQ,334
193
193
  aury/boot/toolkit/http/__init__.py,sha256=zIPmpIZ9Qbqe25VmEr7jixoY2fkRbLm7NkCB9vKpg6I,11039
194
- aury_boot-0.0.8.dist-info/METADATA,sha256=aMQMBHNb0zE5c8eVaEHZSAYEdtCiCKd3Ea5VOuX5_lg,7980
195
- aury_boot-0.0.8.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
196
- aury_boot-0.0.8.dist-info/entry_points.txt,sha256=f9KXEkDIGc0BGkgBvsNx_HMz9VhDjNxu26q00jUpDwQ,49
197
- aury_boot-0.0.8.dist-info/RECORD,,
194
+ aury_boot-0.0.10.dist-info/METADATA,sha256=i5glHELenzosPJRyoJBQcn9ujPccCjMvo9BmnNAqX6E,7981
195
+ aury_boot-0.0.10.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
196
+ aury_boot-0.0.10.dist-info/entry_points.txt,sha256=f9KXEkDIGc0BGkgBvsNx_HMz9VhDjNxu26q00jUpDwQ,49
197
+ aury_boot-0.0.10.dist-info/RECORD,,