aury-boot 0.0.29__tar.gz → 0.0.31__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.
Files changed (220) hide show
  1. {aury_boot-0.0.29 → aury_boot-0.0.31}/PKG-INFO +14 -1
  2. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/_version.py +2 -2
  3. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/__init__.py +2 -4
  4. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/app/base.py +126 -2
  5. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/app/components.py +226 -1
  6. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/config/settings.py +201 -3
  7. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/constants/components.py +3 -0
  8. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/middleware/logging.py +45 -6
  9. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/docs.py +40 -0
  10. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/init.py +2 -0
  11. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/AGENTS.md.tpl +59 -0
  12. aury_boot-0.0.31/aury/boot/commands/templates/project/alert_rules.example.yaml.tpl +85 -0
  13. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/00-overview.md.tpl +3 -0
  14. aury_boot-0.0.31/aury/boot/commands/templates/project/aury_docs/17-alerting.md.tpl +210 -0
  15. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/messaging.tpl +21 -13
  16. aury_boot-0.0.31/aury/boot/commands/templates/project/env_templates/monitoring.tpl +63 -0
  17. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/common/logging/context.py +17 -1
  18. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/common/logging/format.py +4 -0
  19. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/__init__.py +4 -8
  20. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/channel/__init__.py +9 -8
  21. aury_boot-0.0.31/aury/boot/infrastructure/channel/backends/__init__.py +5 -0
  22. aury_boot-0.0.31/aury/boot/infrastructure/channel/backends/broadcaster.py +141 -0
  23. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/channel/base.py +11 -4
  24. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/channel/manager.py +25 -24
  25. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/database/query_tools/__init__.py +3 -5
  26. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/events/__init__.py +4 -6
  27. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/events/backends/__init__.py +2 -4
  28. aury_boot-0.0.31/aury/boot/infrastructure/events/backends/broadcaster.py +189 -0
  29. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/events/base.py +9 -4
  30. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/events/manager.py +24 -20
  31. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/monitoring/__init__.py +210 -6
  32. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/alerting/__init__.py +50 -0
  33. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/alerting/aggregator.py +193 -0
  34. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/alerting/events.py +141 -0
  35. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/alerting/manager.py +430 -0
  36. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/alerting/notifiers/__init__.py +16 -0
  37. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/alerting/notifiers/base.py +60 -0
  38. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/alerting/notifiers/feishu.py +209 -0
  39. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/alerting/notifiers/webhook.py +110 -0
  40. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/alerting/rules.py +179 -0
  41. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/health/__init__.py +231 -0
  42. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/tracing/__init__.py +55 -0
  43. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/tracing/context.py +43 -0
  44. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/tracing/logging.py +73 -0
  45. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/tracing/processor.py +357 -0
  46. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/tracing/provider.py +322 -0
  47. aury_boot-0.0.31/aury/boot/infrastructure/monitoring/tracing/tracing.py +235 -0
  48. {aury_boot-0.0.29 → aury_boot-0.0.31}/pyproject.toml +19 -1
  49. aury_boot-0.0.29/aury/boot/infrastructure/channel/backends/__init__.py +0 -9
  50. aury_boot-0.0.29/aury/boot/infrastructure/channel/backends/memory.py +0 -126
  51. aury_boot-0.0.29/aury/boot/infrastructure/channel/backends/redis.py +0 -130
  52. aury_boot-0.0.29/aury/boot/infrastructure/events/backends/memory.py +0 -86
  53. aury_boot-0.0.29/aury/boot/infrastructure/events/backends/redis.py +0 -169
  54. {aury_boot-0.0.29 → aury_boot-0.0.31}/.gitignore +0 -0
  55. {aury_boot-0.0.29 → aury_boot-0.0.31}/README.md +0 -0
  56. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/__init__.py +0 -0
  57. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/adapter/__init__.py +0 -0
  58. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/adapter/base.py +0 -0
  59. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/adapter/config.py +0 -0
  60. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/adapter/decorators.py +0 -0
  61. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/adapter/exceptions.py +0 -0
  62. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/adapter/http.py +0 -0
  63. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/app/__init__.py +0 -0
  64. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/app/middlewares.py +0 -0
  65. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/app/startup.py +0 -0
  66. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/config/__init__.py +0 -0
  67. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/config/multi_instance.py +0 -0
  68. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/constants/__init__.py +0 -0
  69. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/constants/scheduler.py +0 -0
  70. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/constants/service.py +0 -0
  71. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/errors/__init__.py +0 -0
  72. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/errors/chain.py +0 -0
  73. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/errors/codes.py +0 -0
  74. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/errors/exceptions.py +0 -0
  75. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/errors/handlers.py +0 -0
  76. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/errors/response.py +0 -0
  77. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/interfaces/__init__.py +0 -0
  78. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/interfaces/egress.py +0 -0
  79. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/interfaces/ingress.py +0 -0
  80. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/middleware/__init__.py +0 -0
  81. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/migrations/__init__.py +0 -0
  82. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/migrations/manager.py +0 -0
  83. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/migrations/setup.py +0 -0
  84. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/rpc/__init__.py +0 -0
  85. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/rpc/base.py +0 -0
  86. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/rpc/client.py +0 -0
  87. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/rpc/discovery.py +0 -0
  88. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/scheduler/__init__.py +0 -0
  89. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/scheduler/runner.py +0 -0
  90. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/application/server/__init__.py +0 -0
  91. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/__init__.py +0 -0
  92. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/add.py +0 -0
  93. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/app.py +0 -0
  94. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/config.py +0 -0
  95. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/docker.py +0 -0
  96. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/generate.py +0 -0
  97. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/migrate/__init__.py +0 -0
  98. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/migrate/app.py +0 -0
  99. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/migrate/commands.py +0 -0
  100. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/pkg.py +0 -0
  101. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/scheduler.py +0 -0
  102. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/server/__init__.py +0 -0
  103. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/server/app.py +0 -0
  104. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/generate/api.py.tpl +0 -0
  105. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/generate/model.py.tpl +0 -0
  106. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/generate/repository.py.tpl +0 -0
  107. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/generate/schema.py.tpl +0 -0
  108. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/generate/service.py.tpl +0 -0
  109. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/README.md.tpl +0 -0
  110. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/admin_console_init.py.tpl +0 -0
  111. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/01-model.md.tpl +0 -0
  112. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/02-repository.md.tpl +0 -0
  113. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/03-service.md.tpl +0 -0
  114. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/04-schema.md.tpl +0 -0
  115. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/05-api.md.tpl +0 -0
  116. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/06-exception.md.tpl +0 -0
  117. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/07-cache.md.tpl +0 -0
  118. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/08-scheduler.md.tpl +0 -0
  119. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/09-tasks.md.tpl +0 -0
  120. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/10-storage.md.tpl +0 -0
  121. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/11-logging.md.tpl +0 -0
  122. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/12-admin.md.tpl +0 -0
  123. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/13-channel.md.tpl +0 -0
  124. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/14-mq.md.tpl +0 -0
  125. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/15-events.md.tpl +0 -0
  126. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/16-adapter.md.tpl +0 -0
  127. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/aury_docs/99-cli.md.tpl +0 -0
  128. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/config.py.tpl +0 -0
  129. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/conftest.py.tpl +0 -0
  130. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/_header.tpl +0 -0
  131. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/admin.tpl +0 -0
  132. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/cache.tpl +0 -0
  133. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/database.tpl +0 -0
  134. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/log.tpl +0 -0
  135. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/rpc.tpl +0 -0
  136. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/scheduler.tpl +0 -0
  137. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/service.tpl +0 -0
  138. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/storage.tpl +0 -0
  139. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/env_templates/third_party.tpl +0 -0
  140. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/gitignore.tpl +0 -0
  141. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/main.py.tpl +0 -0
  142. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/modules/api.py.tpl +0 -0
  143. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/modules/exceptions.py.tpl +0 -0
  144. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/modules/schedules.py.tpl +0 -0
  145. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/templates/project/modules/tasks.py.tpl +0 -0
  146. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/commands/worker.py +0 -0
  147. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/common/__init__.py +0 -0
  148. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/common/exceptions/__init__.py +0 -0
  149. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/common/i18n/__init__.py +0 -0
  150. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/common/i18n/translator.py +0 -0
  151. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/common/logging/__init__.py +0 -0
  152. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/common/logging/decorators.py +0 -0
  153. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/common/logging/setup.py +0 -0
  154. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/contrib/__init__.py +0 -0
  155. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/contrib/admin_console/__init__.py +0 -0
  156. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/contrib/admin_console/auth.py +0 -0
  157. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/contrib/admin_console/discovery.py +0 -0
  158. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/contrib/admin_console/install.py +0 -0
  159. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/contrib/admin_console/utils.py +0 -0
  160. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/__init__.py +0 -0
  161. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/exceptions/__init__.py +0 -0
  162. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/models/__init__.py +0 -0
  163. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/models/base.py +0 -0
  164. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/models/mixins.py +0 -0
  165. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/models/models.py +0 -0
  166. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/pagination/__init__.py +0 -0
  167. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/repository/__init__.py +0 -0
  168. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/repository/impl.py +0 -0
  169. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/repository/interceptors.py +0 -0
  170. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/repository/interface.py +0 -0
  171. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/repository/query_builder.py +0 -0
  172. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/service/__init__.py +0 -0
  173. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/service/base.py +0 -0
  174. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/domain/transaction/__init__.py +0 -0
  175. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/cache/__init__.py +0 -0
  176. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/cache/backends.py +0 -0
  177. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/cache/base.py +0 -0
  178. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/cache/exceptions.py +0 -0
  179. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/cache/factory.py +0 -0
  180. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/cache/manager.py +0 -0
  181. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/clients/__init__.py +0 -0
  182. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/clients/rabbitmq/__init__.py +0 -0
  183. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/clients/rabbitmq/config.py +0 -0
  184. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/clients/rabbitmq/manager.py +0 -0
  185. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/clients/redis/__init__.py +0 -0
  186. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/clients/redis/config.py +0 -0
  187. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/clients/redis/manager.py +0 -0
  188. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/database/__init__.py +0 -0
  189. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/database/config.py +0 -0
  190. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/database/exceptions.py +0 -0
  191. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/database/manager.py +0 -0
  192. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/database/strategies/__init__.py +0 -0
  193. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/di/__init__.py +0 -0
  194. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/di/container.py +0 -0
  195. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/events/backends/rabbitmq.py +0 -0
  196. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/events/middleware.py +0 -0
  197. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/mq/__init__.py +0 -0
  198. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/mq/backends/__init__.py +0 -0
  199. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/mq/backends/rabbitmq.py +0 -0
  200. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/mq/backends/redis.py +0 -0
  201. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/mq/base.py +0 -0
  202. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/mq/manager.py +0 -0
  203. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/scheduler/__init__.py +0 -0
  204. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/scheduler/exceptions.py +0 -0
  205. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/scheduler/manager.py +0 -0
  206. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/storage/__init__.py +0 -0
  207. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/storage/base.py +0 -0
  208. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/storage/exceptions.py +0 -0
  209. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/storage/factory.py +0 -0
  210. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/tasks/__init__.py +0 -0
  211. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/tasks/config.py +0 -0
  212. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/tasks/constants.py +0 -0
  213. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/tasks/exceptions.py +0 -0
  214. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/infrastructure/tasks/manager.py +0 -0
  215. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/testing/__init__.py +0 -0
  216. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/testing/base.py +0 -0
  217. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/testing/client.py +0 -0
  218. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/testing/factory.py +0 -0
  219. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/toolkit/__init__.py +0 -0
  220. {aury_boot-0.0.29 → aury_boot-0.0.31}/aury/boot/toolkit/http/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aury-boot
3
- Version: 0.0.29
3
+ Version: 0.0.31
4
4
  Summary: Aury Boot - 基于 FastAPI 生态的企业级 API 开发框架
5
5
  Requires-Python: >=3.13
6
6
  Requires-Dist: alembic>=1.17.2
@@ -42,6 +42,14 @@ Requires-Dist: mkdocs-material>=9.7.0; extra == 'docs'
42
42
  Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
43
43
  Provides-Extra: mysql
44
44
  Requires-Dist: aiomysql>=0.3.2; extra == 'mysql'
45
+ Provides-Extra: otel
46
+ Requires-Dist: opentelemetry-api>=1.25.0; extra == 'otel'
47
+ Requires-Dist: opentelemetry-instrumentation-fastapi>=0.46b0; extra == 'otel'
48
+ Requires-Dist: opentelemetry-instrumentation-httpx>=0.46b0; extra == 'otel'
49
+ Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.46b0; extra == 'otel'
50
+ Requires-Dist: opentelemetry-sdk>=1.25.0; extra == 'otel'
51
+ Provides-Extra: otel-exporter
52
+ Requires-Dist: opentelemetry-exporter-otlp>=1.25.0; extra == 'otel-exporter'
45
53
  Provides-Extra: postgres
46
54
  Requires-Dist: asyncpg>=0.31.0; extra == 'postgres'
47
55
  Provides-Extra: rabbitmq
@@ -52,6 +60,11 @@ Requires-Dist: apscheduler>=3.11.1; extra == 'recommended'
52
60
  Requires-Dist: asyncpg>=0.31.0; extra == 'recommended'
53
61
  Requires-Dist: aury-sdk-storage[aws]>=0.0.1; extra == 'recommended'
54
62
  Requires-Dist: dramatiq>=1.18.0; extra == 'recommended'
63
+ Requires-Dist: opentelemetry-api>=1.25.0; extra == 'recommended'
64
+ Requires-Dist: opentelemetry-instrumentation-fastapi>=0.46b0; extra == 'recommended'
65
+ Requires-Dist: opentelemetry-instrumentation-httpx>=0.46b0; extra == 'recommended'
66
+ Requires-Dist: opentelemetry-instrumentation-sqlalchemy>=0.46b0; extra == 'recommended'
67
+ Requires-Dist: opentelemetry-sdk>=1.25.0; extra == 'recommended'
55
68
  Requires-Dist: redis>=7.1.0; extra == 'recommended'
56
69
  Provides-Extra: redis
57
70
  Requires-Dist: redis>=7.1.0; extra == 'redis'
@@ -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.29'
32
- __version_tuple__ = version_tuple = (0, 0, 29)
31
+ __version__ = version = '0.0.31'
32
+ __version_tuple__ = version_tuple = (0, 0, 31)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -24,6 +24,7 @@ from aury.boot.domain.transaction import (
24
24
  # 依赖注入容器(从 infrastructure 导入)
25
25
  from aury.boot.infrastructure.di import Container, Lifetime, Scope, ServiceDescriptor
26
26
  from aury.boot.infrastructure.events import (
27
+ BroadcasterEventBus,
27
28
  Event,
28
29
  EventBackend,
29
30
  EventBusManager,
@@ -31,9 +32,7 @@ from aury.boot.infrastructure.events import (
31
32
  EventType,
32
33
  IEventBus,
33
34
  # 后端实现
34
- MemoryEventBus,
35
35
  RabbitMQEventBus,
36
- RedisEventBus,
37
36
  )
38
37
 
39
38
  from . import interfaces, rpc
@@ -108,14 +107,13 @@ __all__ = [
108
107
  "IEventBus",
109
108
  "Lifetime",
110
109
  "LogSettings",
111
- "MemoryEventBus",
110
+ "BroadcasterEventBus",
112
111
  "Middleware",
113
112
  "MiddlewareName",
114
113
  "MigrationComponent",
115
114
  # 迁移
116
115
  "MigrationManager",
117
116
  "RabbitMQEventBus",
118
- "RedisEventBus",
119
117
  "RequestLoggingMiddleware",
120
118
  "SchedulerComponent",
121
119
  "SchedulerMode",
@@ -83,6 +83,78 @@ class Middleware(ABC):
83
83
  pass
84
84
 
85
85
 
86
+ # TODO: 未来考虑合并 Middleware/Plugin/Component 为统一的 Extension 概念:
87
+ # class Extension:
88
+ # def build_middleware(self, config) -> StarletteMiddleware | None # 可选:app 创建前
89
+ # def install(self, app, config) -> None # 可选:app 创建后
90
+ # async def setup(self, app, config) -> None # 可选:lifespan 启动
91
+ # async def teardown(self, app) -> None # 可选:lifespan 关闭
92
+ # 这样一个扩展可以同时实现多个 hook,适用于 OTEL、认证等复杂场景。
93
+
94
+
95
+ class Plugin(ABC):
96
+ """应用插件基类。
97
+
98
+ 用于需要 app 实例的扩展,如 OpenTelemetry instrument、Admin Console 挂载等。
99
+ 插件在 app 创建后、lifespan 之前同步执行。
100
+
101
+ 生命周期:
102
+ 1. ``install()`` - 在 app 创建后同步调用,可以访问 app 实例。
103
+
104
+ 与 Middleware 的区别:
105
+ - Middleware: 在 app 创建前构建,返回 Starlette Middleware
106
+ - Plugin: 在 app 创建后执行,可以操作 app 实例
107
+
108
+ 与 Component 的区别:
109
+ - Component: 在 lifespan 里异步执行,用于基础设施初始化
110
+ - Plugin: 在 lifespan 前同步执行,用于 app 扩展
111
+
112
+ 使用示例:
113
+ class TelemetryPlugin(Plugin):
114
+ name = "telemetry"
115
+ enabled = True
116
+
117
+ def install(self, app: FoundationApp, config: BaseConfig) -> None:
118
+ FastAPIInstrumentor.instrument_app(app)
119
+ """
120
+
121
+ name: str = "plugin"
122
+ enabled: bool = True
123
+
124
+ def can_enable(self, config: BaseConfig) -> bool:
125
+ """是否可以启用此插件。
126
+
127
+ 子类可以重写此方法以实现条件化启用。
128
+
129
+ Args:
130
+ config: 应用配置
131
+
132
+ Returns:
133
+ 是否启用
134
+ """
135
+ return self.enabled
136
+
137
+ @abstractmethod
138
+ def install(self, app: FoundationApp, config: BaseConfig) -> None:
139
+ """安装插件(同步,在 app 创建后、lifespan 之前调用)。
140
+
141
+ Args:
142
+ app: 应用实例
143
+ config: 应用配置
144
+ """
145
+ pass
146
+
147
+ def uninstall(self, app: FoundationApp) -> None:
148
+ """卸载插件(可选,在 lifespan 关闭时调用)。
149
+
150
+ 用于清理资源。默认不做任何操作。
151
+
152
+ Args:
153
+ app: 应用实例
154
+ """
155
+ pass
156
+
157
+
86
158
  class Component(ABC):
87
159
  """基础设施组件基类。
88
160
 
@@ -195,6 +267,9 @@ class FoundationApp(FastAPI):
195
267
  # 默认中间件列表(子类可以覆盖)
196
268
  middlewares: ClassVar[list[type[Middleware] | Middleware]] = []
197
269
 
270
+ # 默认插件列表(子类可以覆盖)
271
+ plugins: ClassVar[list[type[Plugin] | Plugin]] = []
272
+
198
273
  # 默认组件列表(子类可以覆盖)
199
274
  components: ClassVar[list[type[Component] | Component]] = []
200
275
 
@@ -249,8 +324,9 @@ class FoundationApp(FastAPI):
249
324
  # 注册 access 日志(HTTP 请求日志)
250
325
  register_log_sink("access", filter_key="access")
251
326
 
252
- # 初始化中间件和组件管理
327
+ # 初始化中间件、插件和组件管理
253
328
  self._middlewares: dict[str, Middleware] = {}
329
+ self._plugins: dict[str, Plugin] = {}
254
330
  self._components: dict[str, Component] = {}
255
331
  self._lifecycle_listeners: dict[str, list[Callable]] = {}
256
332
 
@@ -263,9 +339,12 @@ class FoundationApp(FastAPI):
263
339
  yield
264
340
  # 关闭
265
341
  await self._on_shutdown()
342
+ # 卸载插件
343
+ self._uninstall_plugins()
266
344
 
267
- # 收集中间件和组件实例并过滤
345
+ # 收集中间件、插件和组件实例并过滤
268
346
  self._collect_middlewares()
347
+ self._collect_plugins()
269
348
  self._collect_components()
270
349
 
271
350
  # 构建中间件实例列表,传给 FastAPI
@@ -281,6 +360,9 @@ class FoundationApp(FastAPI):
281
360
  **kwargs,
282
361
  )
283
362
 
363
+ # 安装插件(app 创建后、lifespan 之前)
364
+ self._install_plugins()
365
+
284
366
  # 异常处理:显式注册以覆盖 FastAPI/Starlette 默认处理器,确保统一响应格式
285
367
  self.add_exception_handler(RequestValidationError, global_exception_handler) # 422 参数校验
286
368
  self.add_exception_handler(HTTPException, global_exception_handler) # 4xx/5xx HTTP 异常
@@ -306,6 +388,22 @@ class FoundationApp(FastAPI):
306
388
  self._middlewares[middleware.name] = middleware
307
389
  logger.debug(f"中间件已收集: {middleware.name}")
308
390
 
391
+ def _collect_plugins(self) -> None:
392
+ """收集并实例化所有插件。
393
+
394
+ 这一步在 super().__init__() 之前执行,只做实例化和过滤。
395
+ """
396
+ for item in self.plugins:
397
+ # 支持类或实例
398
+ if isinstance(item, type):
399
+ plugin = item()
400
+ else:
401
+ plugin = item
402
+
403
+ if plugin.can_enable(self._config):
404
+ self._plugins[plugin.name] = plugin
405
+ logger.debug(f"插件已收集: {plugin.name}")
406
+
309
407
  def _collect_components(self) -> None:
310
408
  """收集并实例化所有组件。
311
409
 
@@ -323,6 +421,32 @@ class FoundationApp(FastAPI):
323
421
  self._components[component.name] = component
324
422
  logger.debug(f"组件已收集: {component.name}")
325
423
 
424
+ def _install_plugins(self) -> None:
425
+ """安装所有插件。
426
+
427
+ 在 super().__init__() 之后、lifespan 之前同步调用。
428
+ 此时 app 已创建,插件可以访问 app 实例。
429
+ """
430
+ for plugin in self._plugins.values():
431
+ try:
432
+ plugin.install(self, self._config)
433
+ logger.info(f"插件已安装: {plugin.name}")
434
+ except Exception as e:
435
+ logger.warning(f"插件安装失败 ({plugin.name}): {e}")
436
+
437
+ def _uninstall_plugins(self) -> None:
438
+ """卸载所有插件。
439
+
440
+ 在 lifespan 关闭后同步调用。
441
+ """
442
+ # 反序卸载
443
+ for plugin in reversed(list(self._plugins.values())):
444
+ try:
445
+ plugin.uninstall(self)
446
+ logger.debug(f"插件已卸载: {plugin.name}")
447
+ except Exception as e:
448
+ logger.warning(f"插件卸载失败 ({plugin.name}): {e}")
449
+
326
450
  def _build_middlewares(self) -> list[StarletteMiddleware]:
327
451
  """构建所有中间件实例。
328
452
 
@@ -9,7 +9,7 @@ import importlib
9
9
  import pkgutil
10
10
  from typing import ClassVar
11
11
 
12
- from aury.boot.application.app.base import Component, FoundationApp
12
+ from aury.boot.application.app.base import Component, FoundationApp, Plugin
13
13
  from aury.boot.application.config import BaseConfig
14
14
  from aury.boot.application.constants import ComponentName, ServiceType
15
15
  from aury.boot.application.migrations import MigrationManager
@@ -18,6 +18,17 @@ from aury.boot.infrastructure.cache import CacheManager
18
18
  from aury.boot.infrastructure.channel import ChannelManager
19
19
  from aury.boot.infrastructure.database import DatabaseManager
20
20
  from aury.boot.infrastructure.events import EventBusManager
21
+ from aury.boot.infrastructure.monitoring.alerting import (
22
+ AlertEventType,
23
+ AlertManager,
24
+ AlertSeverity,
25
+ emit_alert,
26
+ )
27
+ from aury.boot.infrastructure.monitoring.tracing import (
28
+ TelemetryConfig,
29
+ TelemetryProvider,
30
+ setup_otel_logging,
31
+ )
21
32
  from aury.boot.infrastructure.mq import MQManager
22
33
  from aury.boot.infrastructure.scheduler import SchedulerManager
23
34
  from aury.boot.infrastructure.storage import StorageManager
@@ -48,9 +59,26 @@ class DatabaseComponent(Component):
48
59
  pool_timeout=config.database.pool_timeout,
49
60
  pool_recycle=config.database.pool_recycle,
50
61
  )
62
+ # 在 engine 创建后进行 OTEL instrumentation
63
+ self._instrument_engine(db_manager, config)
51
64
  except Exception as e:
52
65
  logger.error(f"数据库初始化失败: {e}")
53
66
  raise
67
+
68
+ def _instrument_engine(self, db_manager: DatabaseManager, config: BaseConfig) -> None:
69
+ """对数据库引擎进行 OTEL instrumentation。"""
70
+ if not config.telemetry.enabled:
71
+ return
72
+
73
+ try:
74
+ from opentelemetry.instrumentation.sqlalchemy import SQLAlchemyInstrumentor
75
+ # async engine 需要使用 sync_engine
76
+ SQLAlchemyInstrumentor().instrument(engine=db_manager.engine.sync_engine)
77
+ logger.debug("SQLAlchemy engine instrumentation 已启用")
78
+ except ImportError:
79
+ logger.debug("SQLAlchemy instrumentation 未安装,跳过")
80
+ except Exception as e:
81
+ logger.warning(f"SQLAlchemy engine instrumentation 失败: {e}")
54
82
 
55
83
  async def teardown(self, app: FoundationApp) -> None:
56
84
  """关闭数据库。"""
@@ -549,6 +577,195 @@ class ChannelComponent(Component):
549
577
  logger.warning(f"通道 [{name}] 关闭失败: {e}")
550
578
 
551
579
 
580
+ class TelemetryPlugin(Plugin):
581
+ """OpenTelemetry 插件。
582
+
583
+ 在 app 创建后同步执行,负责:
584
+ - 初始化 TracerProvider
585
+ - 对 FastAPI app 进行 instrumentation
586
+ - 配置 AlertingSpanProcessor 检测慢请求/异常(告警配置从 ALERT__ 读取)
587
+
588
+ 配置方式(环境变量):
589
+ TELEMETRY__ENABLED=true
590
+ TELEMETRY__TRACES_ENDPOINT=http://jaeger:4317 # 可选
591
+ TELEMETRY__LOGS_ENDPOINT=http://loki:3100 # 可选
592
+ TELEMETRY__METRICS_ENDPOINT=http://prometheus:9090 # 可选
593
+
594
+ # 告警相关配置从 ALERT__ 读取
595
+ ALERT__ENABLED=true
596
+ ALERT__SLOW_REQUEST_THRESHOLD=1.0
597
+ ALERT__SLOW_SQL_THRESHOLD=0.5
598
+ ALERT__ALERT_ON_SLOW_REQUEST=true
599
+ ALERT__ALERT_ON_SLOW_SQL=true
600
+ ALERT__ALERT_ON_ERROR=true
601
+ """
602
+
603
+ name = "telemetry"
604
+ enabled = True
605
+
606
+ def can_enable(self, config: BaseConfig) -> bool:
607
+ """仅当 TELEMETRY__ENABLED=true 时启用。"""
608
+ return self.enabled and config.telemetry.enabled
609
+
610
+ def install(self, app: FoundationApp, config: BaseConfig) -> None:
611
+ """初始化 OpenTelemetry 并对 app 进行 instrumentation。"""
612
+ try:
613
+ # 创建告警回调(调用 alerting 模块,自动应用定制化规则)
614
+ alert_callback = self._create_alert_callback() if config.alert.enabled else None
615
+
616
+ telemetry_config = TelemetryConfig(
617
+ service_name=config.service.name,
618
+ service_version=config.service.version,
619
+ environment=config.service.environment,
620
+ instrument_fastapi=config.telemetry.instrument_fastapi,
621
+ instrument_sqlalchemy=config.telemetry.instrument_sqlalchemy,
622
+ instrument_httpx=config.telemetry.instrument_httpx,
623
+ # 告警配置全部从 AlertSettings 读取
624
+ alert_enabled=config.alert.enabled,
625
+ slow_request_threshold=config.alert.slow_request_threshold,
626
+ slow_sql_threshold=config.alert.slow_sql_threshold,
627
+ alert_on_slow_request=config.alert.alert_on_slow_request,
628
+ alert_on_slow_sql=config.alert.alert_on_slow_sql,
629
+ alert_on_error=config.alert.alert_on_error,
630
+ alert_callback=alert_callback,
631
+ slow_request_exclude_paths=config.alert.slow_request_exclude_paths,
632
+ traces_endpoint=config.telemetry.traces_endpoint,
633
+ traces_headers=config.telemetry.traces_headers,
634
+ logs_endpoint=config.telemetry.logs_endpoint,
635
+ logs_headers=config.telemetry.logs_headers,
636
+ metrics_endpoint=config.telemetry.metrics_endpoint,
637
+ metrics_headers=config.telemetry.metrics_headers,
638
+ sampling_rate=config.telemetry.sampling_rate,
639
+ )
640
+
641
+ # 创建并初始化 TelemetryProvider
642
+ provider = TelemetryProvider(telemetry_config)
643
+ success = provider.initialize()
644
+
645
+ if success:
646
+ # 保存到 app.state 以便 shutdown 时使用
647
+ app.state.telemetry_provider = provider
648
+
649
+ # 对已创建的 FastAPI app 进行 instrumentation
650
+ provider.instrument_fastapi_app(app)
651
+
652
+ # 配置 OTLP 日志导出(可选)
653
+ if config.telemetry.logs_endpoint:
654
+ self._setup_otlp_logging(
655
+ config.telemetry.logs_endpoint,
656
+ config.telemetry.logs_headers,
657
+ )
658
+ else:
659
+ logger.warning("OpenTelemetry 初始化失败(非关键)")
660
+
661
+ except ImportError as e:
662
+ logger.warning(f"OpenTelemetry 未安装,跳过初始化: {e}")
663
+ except Exception as e:
664
+ logger.warning(f"OpenTelemetry 初始化失败(非关键): {e}")
665
+
666
+ def _create_alert_callback(self):
667
+ """创建告警回调函数。
668
+
669
+ 回调会调用 alerting 模块的 emit_alert,自动应用 YAML 定制化规则。
670
+ """
671
+ # 事件类型映射
672
+ type_mapping = {
673
+ "slow_request": AlertEventType.SLOW_REQUEST,
674
+ "slow_sql": AlertEventType.SLOW_SQL,
675
+ "exception": AlertEventType.EXCEPTION,
676
+ "custom": AlertEventType.CUSTOM,
677
+ }
678
+
679
+ # 严重级别映射
680
+ severity_mapping = {
681
+ "info": AlertSeverity.INFO,
682
+ "warning": AlertSeverity.WARNING,
683
+ "error": AlertSeverity.ERROR,
684
+ "critical": AlertSeverity.CRITICAL,
685
+ }
686
+
687
+ async def callback(event_type: str, message: str, **metadata):
688
+ try:
689
+ alert_event_type = type_mapping.get(event_type, AlertEventType.CUSTOM)
690
+ severity_str = metadata.pop("severity", "warning")
691
+ severity = severity_mapping.get(severity_str, AlertSeverity.WARNING)
692
+
693
+ await emit_alert(
694
+ alert_event_type,
695
+ message,
696
+ severity=severity,
697
+ **metadata,
698
+ )
699
+ except Exception as e:
700
+ logger.debug(f"发送告警失败: {e}")
701
+
702
+ return callback
703
+
704
+ def _setup_otlp_logging(
705
+ self,
706
+ endpoint: str,
707
+ headers: dict[str, str] | None = None,
708
+ ) -> None:
709
+ """配置 OTLP 日志导出。"""
710
+ try:
711
+ setup_otel_logging(endpoint=endpoint, headers=headers)
712
+ except Exception as e:
713
+ logger.warning(f"OTLP 日志导出配置失败: {e}")
714
+
715
+ def uninstall(self, app: FoundationApp) -> None:
716
+ """关闭 OpenTelemetry。"""
717
+ try:
718
+ provider = getattr(app.state, "telemetry_provider", None)
719
+ if provider:
720
+ provider.shutdown()
721
+ logger.info("OpenTelemetry 已关闭")
722
+ except Exception as e:
723
+ logger.warning(f"OpenTelemetry 关闭失败: {e}")
724
+
725
+
726
+ class AlertComponent(Component):
727
+ """告警系统组件。
728
+
729
+ 在 lifespan 启动时异步初始化 AlertManager。
730
+ """
731
+
732
+ name = "alert"
733
+ enabled = True
734
+ depends_on: ClassVar[list[str]] = []
735
+
736
+ def can_enable(self, config: BaseConfig) -> bool:
737
+ """仅当 ALERT__ENABLED=true 时启用。"""
738
+ return self.enabled and config.alert.enabled
739
+
740
+ async def setup(self, app: FoundationApp, config: BaseConfig) -> None:
741
+ """初始化告警管理器。"""
742
+ try:
743
+ alert_manager = AlertManager.get_instance()
744
+ if not alert_manager.is_initialized:
745
+ await alert_manager.initialize(
746
+ enabled=config.alert.enabled,
747
+ service_name=config.service.name,
748
+ rules_file=config.alert.rules_file,
749
+ defaults={
750
+ "slow_request_threshold": config.alert.slow_request_threshold,
751
+ "slow_sql_threshold": config.alert.slow_sql_threshold,
752
+ "aggregate_window": config.alert.aggregate_window,
753
+ "slow_request_aggregate": config.alert.slow_request_aggregate,
754
+ "slow_sql_aggregate": config.alert.slow_sql_aggregate,
755
+ "exception_aggregate": config.alert.exception_aggregate,
756
+ "suppress_seconds": config.alert.suppress_seconds,
757
+ "slow_request_exclude_paths": config.alert.slow_request_exclude_paths,
758
+ },
759
+ notifiers=config.alert.get_notifiers(),
760
+ )
761
+ except Exception as e:
762
+ logger.warning(f"告警管理器初始化失败(非关键): {e}")
763
+
764
+ async def teardown(self, app: FoundationApp) -> None:
765
+ """无需清理。"""
766
+ pass
767
+
768
+
552
769
  class EventBusComponent(Component):
553
770
  """事件总线组件。
554
771
 
@@ -590,8 +807,14 @@ class EventBusComponent(Component):
590
807
  logger.warning(f"事件总线 [{name}] 关闭失败: {e}")
591
808
 
592
809
 
810
+ # 设置默认插件
811
+ FoundationApp.plugins = [
812
+ TelemetryPlugin, # app 创建后立即 instrument
813
+ ]
814
+
593
815
  # 设置默认组件
594
816
  FoundationApp.components = [
817
+ AlertComponent, # 最先初始化告警管理器
595
818
  DatabaseComponent,
596
819
  MigrationComponent,
597
820
  AdminConsoleComponent,
@@ -607,6 +830,7 @@ FoundationApp.components = [
607
830
 
608
831
  __all__ = [
609
832
  "AdminConsoleComponent",
833
+ "AlertComponent",
610
834
  "CacheComponent",
611
835
  "ChannelComponent",
612
836
  "DatabaseComponent",
@@ -616,5 +840,6 @@ __all__ = [
616
840
  "SchedulerComponent",
617
841
  "StorageComponent",
618
842
  "TaskComponent",
843
+ "TelemetryPlugin",
619
844
  ]
620
845