Browse Source

chore(logger): 优化日志目录配置支持环境变量

- start_cxx_spider.py: 将日志目录改为优先读取环境变量 CXX_LOG_DIR
- start_cxx_spider.py: 缺省使用项目根目录 logs/,并提前创建日志目录
- 其他模块中不再写死日志路径,改为从环境变量或项目根目录读取
- 避免模块级日志 sink 配置破坏入口脚本统一日志设置
- 确保日志文件名格式统一为 {YYYYMMDD}.log 便于采集端识别
- 增强日志配置灵活性以适应不同部署环境
charley 13 hours ago
parent
commit
632b5b45ff

+ 10 - 2
cxx_spider/start_cxx_spider.py

@@ -29,14 +29,22 @@ for _p in (BASE_DIR, STATS_DIR):
     if _p not in sys.path:
         sys.path.insert(0, _p)
 
-# ---- 日志:全项目唯一的 sink,所有模块的输出都汇总到根目录 logs/{日期}.log ----
+# ---- 日志:全项目唯一的 sink,所有模块的输出都汇总到 logs/{日期}.log ----
 # 各业务模块只在自己作为 __main__ 独立运行时才配 sink,被 import 时不碰全局 logger,
 # 故这里在 import 之前还是之后配置都一样,不再像从前那样靠 import 顺序决定日志去向。
+#
+# 日志目录优先取环境变量 CXX_LOG_DIR,缺省回落到项目根 logs/:
+# 服务器的日志采集只读固定目录(如容器内 /app/logs),而项目代码未必就放在该目录的上一级,
+# 故目录由部署环境指定、代码不写死;文件名固定 {time:YYYYMMDD}.log 以匹配采集端的格式要求。
+# 部署示例:CXX_LOG_DIR=/app/logs python start_cxx_spider.py
 import schedule
 from loguru import logger
 
+LOG_DIR = os.environ.get("CXX_LOG_DIR") or os.path.join(BASE_DIR, "logs")
+os.makedirs(LOG_DIR, exist_ok=True)   # 提前建目录:目录不存在或无权限时在此直接报错,而非等到首条日志才暴露
+
 logger.remove()
-logger.add(os.path.join(BASE_DIR, "logs", "{time:YYYYMMDD}.log"), encoding='utf-8', rotation="00:00",
+logger.add(os.path.join(LOG_DIR, "{time:YYYYMMDD}.log"), encoding='utf-8', rotation="00:00",
            format="[{time:YYYY-MM-DD HH:mm:ss.SSS}] {level} {message}",
            level="DEBUG", retention="7 day")
 

+ 7 - 2
cxx_spider/stats/super_vault_his_report.py

@@ -51,10 +51,15 @@ from openpyxl import Workbook
 from openpyxl.styles import Font, Alignment, PatternFill, Border, Side
 from mysql_pool import MySQLConnectionPool
 
-# 日志统一写根目录 logs/{日期}.log,由入口脚本配置(见文件末尾 __main__)。
+# 日志统一写 logs/{日期}.log,sink 由入口脚本配置(见文件末尾 __main__)。
 # 模块级绝不配置 sink:被 start_cxx_spider 等入口 import 时若在此 logger.remove()/add(),
 # 会摘掉入口已装好的 sink,并凭空创建一个随即被摘、永不写入的 0 字节日志文件。
-LOG_PATH = os.path.join(ROOT_DIR, "logs", "{time:YYYYMMDD}.log")
+#
+# 日志目录优先取环境变量 CXX_LOG_DIR,缺省回落到项目根 logs/:
+# 服务器的日志采集只读固定目录(如容器内 /app/logs),而项目代码未必就放在该目录的上一级,
+# 故目录由部署环境指定、代码不写死;文件名固定 {time:YYYYMMDD}.log 以匹配采集端的格式要求。
+LOG_DIR = os.environ.get("CXX_LOG_DIR") or os.path.join(ROOT_DIR, "logs")
+LOG_PATH = os.path.join(LOG_DIR, "{time:YYYYMMDD}.log")
 
 # 企微发送:本项目暂无 auto_send_wx_msg 模块,默认关闭;日后接入企微机器人时置 True 并放置发送模块即可
 SEND_WECHAT = False

+ 7 - 2
cxx_spider/stats/super_vault_nova_daily_report.py

@@ -61,10 +61,15 @@ from super_vault_his_report import (
     _write_anchor_table, _write_details,
 )
 
-# 日志统一写根目录 logs/{日期}.log,由入口脚本配置(见文件末尾 __main__)。
+# 日志统一写 logs/{日期}.log,sink 由入口脚本配置(见文件末尾 __main__)。
 # 模块级绝不配置 sink:被 start_cxx_spider 等入口 import 时若在此 logger.remove()/add(),
 # 会摘掉入口已装好的 sink,并凭空创建一个随即被摘、永不写入的 0 字节日志文件。
-LOG_PATH = os.path.join(ROOT_DIR, "logs", "{time:YYYYMMDD}.log")
+#
+# 日志目录优先取环境变量 CXX_LOG_DIR,缺省回落到项目根 logs/:
+# 服务器的日志采集只读固定目录(如容器内 /app/logs),而项目代码未必就放在该目录的上一级,
+# 故目录由部署环境指定、代码不写死;文件名固定 {time:YYYYMMDD}.log 以匹配采集端的格式要求。
+LOG_DIR = os.environ.get("CXX_LOG_DIR") or os.path.join(ROOT_DIR, "logs")
+LOG_PATH = os.path.join(LOG_DIR, "{time:YYYYMMDD}.log")
 
 OUT_PREFIX = "超新星已售每日报告"    # 输出文件名前缀,后缀加统计日期
 

+ 7 - 2
cxx_spider/super_vault_order_spider.py

@@ -59,10 +59,15 @@ from loguru import logger
 from tenacity import retry, stop_after_attempt, wait_fixed
 from mysql_pool import MySQLConnectionPool
 
-# 日志统一写根目录 logs/{日期}.log,由入口脚本配置(见文件末尾 __main__)。
+# 日志统一写 logs/{日期}.log,sink 由入口脚本配置(见文件末尾 __main__)。
 # 模块级绝不配置 sink:被 start_cxx_spider 等入口 import 时若在此 logger.remove()/add(),
 # 会摘掉入口已装好的 sink(或反被后续 import 的模块摘掉),日志去向变成由 import 顺序决定。
-LOG_PATH = os.path.join(ROOT_DIR, "logs", "{time:YYYYMMDD}.log")
+#
+# 日志目录优先取环境变量 CXX_LOG_DIR,缺省回落到项目根 logs/:
+# 服务器的日志采集只读固定目录(如容器内 /app/logs),而项目代码未必就放在该目录的上一级,
+# 故目录由部署环境指定、代码不写死;文件名固定 {time:YYYYMMDD}.log 以匹配采集端的格式要求。
+LOG_DIR = os.environ.get("CXX_LOG_DIR") or os.path.join(ROOT_DIR, "logs")
+LOG_PATH = os.path.join(LOG_DIR, "{time:YYYYMMDD}.log")
 
 # 接口地址
 ORDER_LIST_URL = "https://cxx.cardsvault.net/app/order/simple/list"