Silence Flask access logs and retain PM2 logs for 3 days.
Stop werkzeug request spam into PM2 error files, truncate oversized logs, and install daily logrotate with 3-day retention. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -9968,5 +9968,8 @@ _purge_key_monitors_if_full_margin()
|
|||||||
|
|
||||||
# 启动
|
# 启动
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
from lib.common.flask_access_log_lib import silence_werkzeug_access_log
|
||||||
|
|
||||||
|
silence_werkzeug_access_log()
|
||||||
threading.Thread(target=background_task, daemon=True).start()
|
threading.Thread(target=background_task, daemon=True).start()
|
||||||
app.run(host=HOST, port=PORT, debug=DEBUG, threaded=True)
|
app.run(host=HOST, port=PORT, debug=DEBUG, threaded=True)
|
||||||
|
|||||||
@@ -9844,5 +9844,8 @@ _purge_key_monitors_if_full_margin()
|
|||||||
|
|
||||||
# 启动
|
# 启动
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
from lib.common.flask_access_log_lib import silence_werkzeug_access_log
|
||||||
|
|
||||||
|
silence_werkzeug_access_log()
|
||||||
threading.Thread(target=background_task, daemon=True).start()
|
threading.Thread(target=background_task, daemon=True).start()
|
||||||
app.run(host=HOST, port=PORT, debug=DEBUG, threaded=True)
|
app.run(host=HOST, port=PORT, debug=DEBUG, threaded=True)
|
||||||
|
|||||||
@@ -9564,5 +9564,8 @@ _purge_key_monitors_if_full_margin()
|
|||||||
|
|
||||||
# 启动
|
# 启动
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
from lib.common.flask_access_log_lib import silence_werkzeug_access_log
|
||||||
|
|
||||||
|
silence_werkzeug_access_log()
|
||||||
threading.Thread(target=background_task, daemon=True).start()
|
threading.Thread(target=background_task, daemon=True).start()
|
||||||
app.run(host=HOST, port=PORT, debug=DEBUG, threaded=True)
|
app.run(host=HOST, port=PORT, debug=DEBUG, threaded=True)
|
||||||
|
|||||||
@@ -0,0 +1,61 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# PM2 日志策略:关灌屏后的兜底轮转 — 按天保留 3 天,单文件过大也切分.
|
||||||
|
# 用法(root):
|
||||||
|
# bash deploy/pm2_log_policy.sh
|
||||||
|
# bash deploy/pm2_log_policy.sh --clean-only
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
PM2_LOG_DIR="${PM2_LOG_DIR:-/root/.pm2/logs}"
|
||||||
|
LOGROTATE_CONF="${LOGROTATE_CONF:-/etc/logrotate.d/crypto_monitor_pm2}"
|
||||||
|
RETENTION_DAYS="${RETENTION_DAYS:-3}"
|
||||||
|
MAXSIZE="${MAXSIZE:-20M}"
|
||||||
|
CLEAN_ONLY=0
|
||||||
|
if [[ "${1:-}" == "--clean-only" ]]; then
|
||||||
|
CLEAN_ONLY=1
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ">>> PM2 log dir: ${PM2_LOG_DIR}"
|
||||||
|
if [[ ! -d "${PM2_LOG_DIR}" ]]; then
|
||||||
|
echo "目录不存在,跳过"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ">>> truncate oversized active logs (>20MB) and drop stale files older than ${RETENTION_DAYS}d"
|
||||||
|
# 当前正在写的大文件用 truncate 清空内容(copytruncate/空写兼容 PM2 仍持有 fd)
|
||||||
|
find "${PM2_LOG_DIR}" -type f -name '*.log' -size +20M -print -exec truncate -s 0 {} \;
|
||||||
|
# 过期归档/旧编号日志直接删
|
||||||
|
find "${PM2_LOG_DIR}" -type f \( -name '*.log' -o -name '*.log.gz' -o -name '*.log.[0-9]*' \) -mtime +"${RETENTION_DAYS}" -print -delete || true
|
||||||
|
|
||||||
|
if [[ "${CLEAN_ONLY}" -eq 1 ]]; then
|
||||||
|
echo ">>> --clean-only done"
|
||||||
|
du -sh "${PM2_LOG_DIR}" || true
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ">>> install logrotate: ${LOGROTATE_CONF} (daily, rotate ${RETENTION_DAYS}, maxsize ${MAXSIZE})"
|
||||||
|
cat > "${LOGROTATE_CONF}" <<EOF
|
||||||
|
${PM2_LOG_DIR}/*.log {
|
||||||
|
daily
|
||||||
|
rotate ${RETENTION_DAYS}
|
||||||
|
maxsize ${MAXSIZE}
|
||||||
|
missingok
|
||||||
|
notifempty
|
||||||
|
compress
|
||||||
|
delaycompress
|
||||||
|
copytruncate
|
||||||
|
dateext
|
||||||
|
dateformat -%Y%m%d
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
|
||||||
|
# 立即跑一次(不强制等到 cron)
|
||||||
|
if command -v logrotate >/dev/null 2>&1; then
|
||||||
|
logrotate -f "${LOGROTATE_CONF}" || true
|
||||||
|
else
|
||||||
|
echo "warn: logrotate 未安装,仅完成清理;请 apt install logrotate"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ">>> size after"
|
||||||
|
du -sh "${PM2_LOG_DIR}" || true
|
||||||
|
ls -lah "${PM2_LOG_DIR}" | head -30 || true
|
||||||
|
echo "done"
|
||||||
@@ -23,10 +23,14 @@ echo ">>> force-close policy: gate=ON, binance/okx=OFF"
|
|||||||
python3 scripts/sync_common_trading_env.py --apply-force-close-policy "${DRY[@]}"
|
python3 scripts/sync_common_trading_env.py --apply-force-close-policy "${DRY[@]}"
|
||||||
|
|
||||||
if [[ ${#DRY[@]} -gt 0 ]]; then
|
if [[ ${#DRY[@]} -gt 0 ]]; then
|
||||||
echo "(dry-run, skip pm2 restart)"
|
echo "(dry-run, skip pm2 log policy + restart)"
|
||||||
exit 0
|
exit 0
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
echo ">>> pm2 log policy (silence leftover + 3-day retain)"
|
||||||
|
sed -i 's/\r$//' deploy/pm2_log_policy.sh 2>/dev/null || true
|
||||||
|
bash deploy/pm2_log_policy.sh
|
||||||
|
|
||||||
echo ">>> pm2 restart"
|
echo ">>> pm2 restart"
|
||||||
pm2 restart crypto_gate crypto_binance crypto_okx manual-trading-hub manual-agent-gate 2>/dev/null \
|
pm2 restart crypto_gate crypto_binance crypto_okx manual-trading-hub manual-agent-gate 2>/dev/null \
|
||||||
|| pm2 restart crypto-monitor-gate crypto-monitor-binance crypto-monitor-okx manual-trading-hub 2>/dev/null \
|
|| pm2 restart crypto-monitor-gate crypto-monitor-binance crypto-monitor-okx manual-trading-hub 2>/dev/null \
|
||||||
|
|||||||
@@ -0,0 +1,16 @@
|
|||||||
|
"""关闭 Flask/Werkzeug 开发服务器 access log 刷屏(避免灌满 PM2 error 日志)."""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
def silence_werkzeug_access_log() -> None:
|
||||||
|
"""仅抑制 request access 行;WARNING/ERROR 仍可读."""
|
||||||
|
log = logging.getLogger("werkzeug")
|
||||||
|
log.setLevel(logging.WARNING)
|
||||||
|
# 部分环境会挂 StreamHandler 到 stderr;抬高阈值即可
|
||||||
|
for h in list(log.handlers):
|
||||||
|
try:
|
||||||
|
h.setLevel(logging.WARNING)
|
||||||
|
except Exception:
|
||||||
|
pass
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
"""silence_werkzeug_access_log 烟雾测试."""
|
||||||
|
import logging
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from lib.common.flask_access_log_lib import silence_werkzeug_access_log
|
||||||
|
|
||||||
|
|
||||||
|
class TestSilenceAccessLog(unittest.TestCase):
|
||||||
|
def test_sets_warning_level(self):
|
||||||
|
log = logging.getLogger("werkzeug")
|
||||||
|
log.setLevel(logging.INFO)
|
||||||
|
silence_werkzeug_access_log()
|
||||||
|
self.assertGreaterEqual(log.level, logging.WARNING)
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
unittest.main()
|
||||||
Reference in New Issue
Block a user