Add AST JSON files for new documentation and scripts

- Created JSON representation for `collect-diagnostics.sh` including nodes and edges for its structure.
- Added JSON for `ops-restarts.md` detailing various sections and their relationships.
- Introduced JSON for `server-down-oom-diagnosis.md` capturing its content and connections.
This commit is contained in:
hamed
2026-07-08 18:00:01 +03:30
parent a5460cbaa9
commit 880648cae8
11 changed files with 1017 additions and 561 deletions
+55
View File
@@ -0,0 +1,55 @@
#!/bin/sh
# ClinicPro production diagnostics — run ON THE HOST as root (or a user with docker access).
# Collects every piece of evidence needed to pin down why the service goes down
# after hours of uptime (OOM vs full disk vs Redis growth). See docs/ops-restarts.md §7.
#
# Usage: sh collect-diagnostics.sh [container-name-or-id]
set -u
C="${1:-$(docker ps --format '{{.Names}}' | grep -i -m1 clinic || true)}"
echo "=== 1. OOM evidence (kernel, last 48h) ==="
journalctl -k --since "48 hours ago" 2>/dev/null | grep -i -E "oom|killed process" | tail -20 \
|| dmesg 2>/dev/null | grep -i -E "oom|killed process" | tail -20
echo ""
echo "=== 2. Memory / swap now ==="
free -h
echo ""
echo "=== 3. Disk ==="
df -h | head -10
du -sh /var/lib/docker/containers/*/*-json.log 2>/dev/null | sort -h | tail -5
echo ""
echo "=== 4. Container state ==="
docker ps -a --format 'table {{.Names}}\t{{.Status}}'
if [ -n "$C" ]; then
docker inspect --format \
'OOMKilled={{.State.OOMKilled}} ExitCode={{.State.ExitCode}} RestartCount={{.RestartCount}} StartedAt={{.State.StartedAt}} FinishedAt={{.State.FinishedAt}}' "$C"
fi
echo ""
echo "=== 5. Live memory per container ==="
docker stats --no-stream
echo ""
echo "=== 6. php-fpm inside app container ==="
if [ -n "$C" ]; then
docker exec "$C" sh -c 'php -i 2>/dev/null | grep -E "^memory_limit"; ps -o rss,args 2>/dev/null | grep -E "php-fpm|messenger" | grep -v grep'
fi
echo ""
echo "=== 7. Redis memory ==="
R="$(docker ps --format '{{.Names}}' | grep -i -m1 redis || true)"
if [ -n "$R" ]; then
docker exec "$R" redis-cli info memory 2>/dev/null | grep -E "used_memory_human|maxmemory_human|maxmemory_policy"
docker exec "$R" redis-cli xlen messages 2>/dev/null && echo "(messages stream length above)"
fi
echo ""
echo "=== 8. Docker log driver config ==="
docker info --format '{{.LoggingDriver}}' 2>/dev/null
cat /etc/docker/daemon.json 2>/dev/null || echo "(no daemon.json — log rotation NOT configured)"
echo ""
echo "=== done — paste this whole output back for diagnosis ==="
+21 -2
View File
@@ -108,7 +108,15 @@ GET /.well-known/acme-challenge/xxxx HTTP/1.1" 404 ... "Let's Encrypt validation
الگو: workerها چند بار recycle عادی می‌شوند و بعد از چند ساعت کل سرویس down می‌شود. مظنون اول: پر شدن حافظه سرور و کشته شدن پروسه‌ها توسط OOM-killer.
### تأیید روی سرور
### تأیید روی سرور — اسکریپت آماده
فایل [`docs/collect-diagnostics.sh`](collect-diagnostics.sh) را روی **هاست** کپی و اجرا کنید (همه شواهد را یک‌جا جمع می‌کند):
```bash
scp docs/collect-diagnostics.sh root@SERVER:/tmp/ && ssh root@SERVER sh /tmp/collect-diagnostics.sh
```
یا دستورهای کلیدی به‌صورت دستی:
```bash
# آیا کانتینر با OOM کشته شده؟
@@ -124,7 +132,17 @@ docker stats --no-stream
free -h
```
اگر `OOMKilled=true` یا در journalctl خط `Out of memory: Killed process ... (php-fpm|mariadbd)` دیدید، تشخیص قطعی است.
### جدول تفسیر خروجی اسکریپت
| شاهد در خروجی | تشخیص | اقدام |
|---|---|---|
| بخش ۱: `Out of memory: Killed process ... php-fpm` | نشت حافظه fpm | فیکس‌های `pm.max_requests`/`memory_limit` این repo + redeploy کافی است |
| بخش ۱: `Killed process ... mariadbd` یا `redis` | فشار کل RAM سرور | Redis `maxmemory` + Memory Limit در Coolify + swap |
| بخش ۴: `OOMKilled=true` | سقف حافظه خود کانتینر | سقف را بالاتر ببرید یا مصرف را کم کنید |
| بخش ۳: دیسک ≥ ۹۰٪ یا `*-json.log` چند GB | دیسک پر | log rotation در `daemon.json` + پاکسازی |
| بخش ۷: `maxmemory: 0` و `used_memory` بزرگ/رشد‌کننده | Redis بی‌سقف | `maxmemory 256mb` + `maxmemory-policy volatile-lru` |
| بخش ۶: `memory_limit` هنوز `1024M` | image قدیمی در حال اجراست | Redeploy نشده — دوباره deploy کنید |
| هیچ‌کدام | فرضیه حافظه/دیسک رد شد | خروجی کامل اسکریپت + ۵۰ خط آخر لاگ قبل از down را برای تحلیل بفرستید |
### چرا این اتفاق می‌افتاد (و فیکس اعمال‌شده)
@@ -134,6 +152,7 @@ free -h
### اقدامات تکمیلی روی سرور (خارج از repo)
0. **اول Redeploy** — همه فیکس‌های این repo (php.ini، zz-pool.conf، supervisord.conf) فقط با build/deploy جدید اعمال می‌شوند؛ و در env واقعی Coolify به `MESSENGER_TRANSPORT_DSN` پارامتر `?stream_max_entries=20000` را اضافه کنید (نمونه در `.env.coolify.example`).
1. در Coolify برای resource اپ **Memory Limit** بگذارید (مثلاً 1G) تا در بدترین حالت فقط همان کانتینر ری‌استارت شود، نه کل سرور.
2. اگر سرور swap ندارد، 1-2G swap اضافه کنید: `fallocate -l 2G /swapfile && chmod 600 /swapfile && mkswap /swapfile && swapon /swapfile`.
3. اسکن‌های بات (درخواست‌های `GET /xxx.php → 404` پشت‌سرهم) توسط nginx مستقیم 404 می‌شوند و به Symfony نمی‌رسند — عامل مرگ نیستند، فقط نویز لاگ.