smtp: CLI 标准化补完(--host/--log-level/--instance + log_client 级别过滤)

- argparse 新增 --host(别名 --addr)、--log-level、--instance
- --log-level 经 logs.set_log_level() 真正订阅日志过滤
- log_client.py: 新增 _LOG_LEVELS/set_log_level()/_normalize_level() + push() 级别过滤
- 启动日志打印 instance/log-level 及配置来源说明
- services.yaml: smtp 声明 --instance 和 --log-level
- 注: SMTP 账号走 .env/ENV(密码不进 CLI),与全项目约定一致
This commit is contained in:
qing committed 2026-08-10 12:05:46 +08:00
1 parent d0ee948339
commit 9fc3542771
3 files changed
+39 -2

No files matched your search

+1 -1
View File
@@ -57,7 +57,7 @@ services:
# --- 邮件服务 --- # --- 邮件服务 ---
- name: smtp - name: smtp
cmd: bash /opt/micro_servers/smtp/_run.sh cmd: bash /opt/micro_servers/smtp/_run.sh
args: [] args: ["--instance", "smtp", "--log-level", "info"]
depends_on: [] depends_on: []
sleep_before: 2 sleep_before: 2
+26
View File
@@ -38,6 +38,29 @@ _FLUSH_INTERVAL = 2.0 # 超时 2 秒强制 flush
_TIMEOUT = 5 # socket 超时(秒) _TIMEOUT = 5 # socket 超时(秒)
_QUEUE_MAXSIZE = 10000 # 队列上限,防止后台线程异常时内存无限增长;满则丢弃最旧条目 _QUEUE_MAXSIZE = 10000 # 队列上限,防止后台线程异常时内存无限增长;满则丢弃最旧条目
# ── 日志级别过滤 ──
_LOG_LEVELS = {
"debug": 0, "info": 1, "warn": 2, "warning": 2,
"error": 3, "critical": 4,
}
_LOG_LEVEL_THRESHOLD = _LOG_LEVELS["info"] # 默认 info
def _normalize_level(level):
"""归一化级别名:大写转小写,warning→warn。"""
lv = (level or "info").lower()
if lv == "warning":
lv = "warn"
return lv
def set_log_level(level):
"""设置日志过滤阈值(低于该级别的日志将被丢弃)。"""
global _LOG_LEVEL_THRESHOLD
lv = _normalize_level(level)
if lv in _LOG_LEVELS:
_LOG_LEVEL_THRESHOLD = _LOG_LEVELS[lv]
def _safe_json(obj): def _safe_json(obj):
"""安全序列化 extra 字段,不可序列化对象转为 repr 字符串,保证不抛异常。""" """安全序列化 extra 字段,不可序列化对象转为 repr 字符串,保证不抛异常。"""
@@ -77,6 +100,9 @@ class LogClient:
队列满时静默丢弃最旧条目再放入新条目,保证不阻塞业务线程、不导致 OOM。 队列满时静默丢弃最旧条目再放入新条目,保证不阻塞业务线程、不导致 OOM。
""" """
# 级别过滤:低于当前阈值的日志直接丢弃(不进队列)
if _LOG_LEVELS.get(_normalize_level(level), 0) < _LOG_LEVEL_THRESHOLD:
return
entry = { entry = {
'ts': _now_iso(), # 入队时即生成时间戳,反映真实事件时间 'ts': _now_iso(), # 入队时即生成时间戳,反映真实事件时间
'service': service, 'service': service,
+12 -1
View File
@@ -303,12 +303,23 @@ if __name__ == "__main__":
import argparse import argparse
parser = argparse.ArgumentParser(description="smtp — pymsg 邮箱验证码服务") parser = argparse.ArgumentParser(description="smtp — pymsg 邮箱验证码服务")
parser.add_argument("--addr", default="127.0.0.1", help="监听地址") parser.add_argument("--addr", "--host", dest="addr", default="127.0.0.1",
help="监听地址(--host 与 --addr 等价)")
parser.add_argument("--port", type=int, default=8008, help="监听端口") parser.add_argument("--port", type=int, default=8008, help="监听端口")
parser.add_argument("--workers", type=int, default=4, parser.add_argument("--workers", type=int, default=4,
help="回调并发线程数(0=同步串行模式)") help="回调并发线程数(0=同步串行模式)")
parser.add_argument("--log-level", default="info",
choices=["debug", "info", "warn", "error"],
help="日志级别(默认 info)")
parser.add_argument("--instance", default="smtp",
help="实例名(注册中心用,默认 smtp)")
args = parser.parse_args() args = parser.parse_args()
# 应用日志级别过滤(低于阈值的日志不进队列)
logs.set_log_level(args.log_level)
print(f"[smtp] instance={args.instance} log-level={args.log_level}")
print(f"[smtp] 配置来源: .env / ENV > 默认值(SMTP 账号不通过 CLI 传递)")
server = SmtpServer(args.addr, args.port, workers=args.workers) server = SmtpServer(args.addr, args.port, workers=args.workers)
try: try:
server.start() server.start()