logging_config.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. """应用日志配置 —— 按功能模块分文件输出,带轮转防爆盘"""
  2. import logging
  3. import logging.config
  4. import os
  5. from pathlib import Path
  6. PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
  7. LOG_DIR = PROJECT_ROOT / "logs"
  8. def _log(name: str) -> str:
  9. return str(LOG_DIR / f"{name}.log")
  10. LOGGING_CONFIG: dict = {
  11. "version": 1,
  12. "disable_existing_loggers": False,
  13. "formatters": {
  14. "default": {
  15. "format": "%(asctime)s | %(levelname)-5s | %(name)s | %(message)s",
  16. "datefmt": "%Y-%m-%d %H:%M:%S",
  17. },
  18. "brief": {
  19. "format": "%(asctime)s | %(levelname)-5s | %(message)s",
  20. "datefmt": "%H:%M:%S",
  21. },
  22. },
  23. "handlers": {
  24. # ── 按功能分文件 ──
  25. "handler_article": {
  26. "class": "logging.handlers.RotatingFileHandler",
  27. "filename": _log("handler_article"),
  28. "maxBytes": 10 * 1024 * 1024,
  29. "backupCount": 3,
  30. "formatter": "default",
  31. "encoding": "utf-8",
  32. },
  33. "handler_account": {
  34. "class": "logging.handlers.RotatingFileHandler",
  35. "filename": _log("handler_account"),
  36. "maxBytes": 10 * 1024 * 1024,
  37. "backupCount": 3,
  38. "formatter": "default",
  39. "encoding": "utf-8",
  40. },
  41. "handler_enqueue": {
  42. "class": "logging.handlers.RotatingFileHandler",
  43. "filename": _log("handler_enqueue"),
  44. "maxBytes": 10 * 1024 * 1024,
  45. "backupCount": 3,
  46. "formatter": "default",
  47. "encoding": "utf-8",
  48. },
  49. "domain_supply": {
  50. "class": "logging.handlers.RotatingFileHandler",
  51. "filename": _log("domain_content_supply"),
  52. "maxBytes": 10 * 1024 * 1024,
  53. "backupCount": 3,
  54. "formatter": "default",
  55. "encoding": "utf-8",
  56. },
  57. "domain_enqueue": {
  58. "class": "logging.handlers.RotatingFileHandler",
  59. "filename": _log("domain_enqueue_task"),
  60. "maxBytes": 10 * 1024 * 1024,
  61. "backupCount": 3,
  62. "formatter": "default",
  63. "encoding": "utf-8",
  64. },
  65. "infra": {
  66. "class": "logging.handlers.RotatingFileHandler",
  67. "filename": _log("infra"),
  68. "maxBytes": 10 * 1024 * 1024,
  69. "backupCount": 3,
  70. "formatter": "default",
  71. "encoding": "utf-8",
  72. },
  73. "server": {
  74. "class": "logging.handlers.RotatingFileHandler",
  75. "filename": _log("server"),
  76. "maxBytes": 10 * 1024 * 1024,
  77. "backupCount": 3,
  78. "formatter": "default",
  79. "encoding": "utf-8",
  80. },
  81. # ── 控制台(开发时保留)──
  82. "console": {
  83. "class": "logging.StreamHandler",
  84. "formatter": "brief",
  85. },
  86. },
  87. "loggers": {
  88. # handler — 按业务功能分 3 组
  89. "src.handlers.article_search": {
  90. "handlers": ["handler_article", "console"],
  91. "level": "INFO",
  92. "propagate": False,
  93. },
  94. "src.handlers.article_fetch_detail": {
  95. "handlers": ["handler_article", "console"],
  96. "level": "INFO",
  97. "propagate": False,
  98. },
  99. "src.handlers.account_fetch": {
  100. "handlers": ["handler_account", "console"],
  101. "level": "INFO",
  102. "propagate": False,
  103. },
  104. "src.handlers.account_article_fetch": {
  105. "handlers": ["handler_account", "console"],
  106. "level": "INFO",
  107. "propagate": False,
  108. },
  109. "src.handlers.account_article_update": {
  110. "handlers": ["handler_account", "console"],
  111. "level": "INFO",
  112. "propagate": False,
  113. },
  114. "src.handlers.demand_enqueue": {
  115. "handlers": ["handler_enqueue", "console"],
  116. "level": "INFO",
  117. "propagate": False,
  118. },
  119. # domain
  120. "src.domains.content_supply": {
  121. "handlers": ["domain_supply", "console"],
  122. "level": "INFO",
  123. "propagate": False,
  124. },
  125. "src.domains.demand_enqueue_task": {
  126. "handlers": ["domain_enqueue", "console"],
  127. "level": "INFO",
  128. "propagate": False,
  129. },
  130. # infra
  131. "src.infra": {
  132. "handlers": ["infra", "console"],
  133. "level": "INFO",
  134. "propagate": False,
  135. },
  136. # server
  137. "src.server": {
  138. "handlers": ["server", "console"],
  139. "level": "INFO",
  140. "propagate": False,
  141. },
  142. },
  143. # root — 兜底,未匹配的日志走这里
  144. "root": {
  145. "handlers": ["console"],
  146. "level": "WARNING",
  147. },
  148. }
  149. def setup_logging() -> None:
  150. """初始化应用日志配置,自动创建 logs/ 目录"""
  151. os.makedirs(LOG_DIR, exist_ok=True)
  152. logging.config.dictConfig(LOGGING_CONFIG)