Add check_errors.py cron job for API error monitoring
- New check_errors.py: scans last 1 hour of logs, sends Slack @channel only on errors - Add to system crontab (every 5 min) - Update setup.sh to include check_errors.py in crontab setup Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
2c5fb53ef3
commit
24c3f033d2
68
check_errors.py
Executable file
68
check_errors.py
Executable file
@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Check API errors in the last hour and send Slack alert if any found."""
|
||||
|
||||
import os
|
||||
import sys
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
sys.path.insert(0, os.path.dirname(__file__))
|
||||
|
||||
import slack_notifier
|
||||
|
||||
|
||||
LOG_FILES = [
|
||||
"trading.log",
|
||||
"sync_cost_basis.log",
|
||||
"cron.log",
|
||||
]
|
||||
|
||||
LOOKBACK_MINUTES = 60
|
||||
|
||||
|
||||
def collect_recent_errors() -> list[str]:
|
||||
since = datetime.now() - timedelta(minutes=LOOKBACK_MINUTES)
|
||||
since_str = since.strftime("%Y-%m-%d %H:%M")
|
||||
errors = []
|
||||
|
||||
for logfile in LOG_FILES:
|
||||
path = os.path.join(os.path.dirname(__file__), logfile)
|
||||
if not os.path.exists(path):
|
||||
continue
|
||||
with open(path) as f:
|
||||
for line in f:
|
||||
if "[ERROR]" not in line:
|
||||
continue
|
||||
# Only compare lines that start with a timestamp
|
||||
if not line[:4].isdigit():
|
||||
continue
|
||||
if line[:16] >= since_str:
|
||||
errors.append(line.rstrip())
|
||||
|
||||
return errors
|
||||
|
||||
|
||||
def main():
|
||||
errors = collect_recent_errors()
|
||||
if not errors:
|
||||
return
|
||||
|
||||
# Deduplicate and limit
|
||||
unique = list(dict.fromkeys(errors))
|
||||
display = unique[:20]
|
||||
remaining = len(unique) - len(display)
|
||||
|
||||
lines = [
|
||||
"<!channel>",
|
||||
f"⚠️ *API 錯誤警報* (最近 {LOOKBACK_MINUTES} 分鐘,共 {len(unique)} 筆)",
|
||||
"",
|
||||
]
|
||||
for e in display:
|
||||
lines.append(f"• `{e[:200]}`")
|
||||
if remaining > 0:
|
||||
lines.append(f"\n...另有 {remaining} 筆錯誤")
|
||||
|
||||
slack_notifier._send({"text": "\n".join(lines)})
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
3
setup.sh
3
setup.sh
@ -118,6 +118,7 @@ echo "[6/6] Setting up crontab..."
|
||||
|
||||
CRON_MAIN="*/5 * * * * sleep 30 && cd $PROJECT_DIR && /usr/bin/python3 main.py >> cron.log 2>&1"
|
||||
CRON_SYNC="2,32 * * * * cd $PROJECT_DIR && /usr/bin/python3 sync_cost_basis.py >> sync_cost_basis_cron.log 2>&1"
|
||||
CRON_CHECK="*/5 * * * * cd $PROJECT_DIR && /usr/bin/python3 check_errors.py 2>&1"
|
||||
CRON_ENV="PATH=$HOME/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
CRON_PYPATH="PYTHONPATH=$HOME/.local/lib/python3.12/site-packages"
|
||||
|
||||
@ -136,6 +137,7 @@ $CRON_PYPATH
|
||||
|
||||
$CRON_MAIN
|
||||
$CRON_SYNC
|
||||
$CRON_CHECK
|
||||
CRONTAB
|
||||
) | crontab -
|
||||
echo " crontab installed ✓"
|
||||
@ -159,3 +161,4 @@ echo ""
|
||||
echo "Crontab 排程:"
|
||||
echo " main.py: 每 5 分鐘(延遲 30 秒)"
|
||||
echo " sync_cost_basis.py: 每小時 :02 和 :32"
|
||||
echo " check_errors.py: 每 5 分鐘(有錯才 Slack @channel)"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user