متابعة السجلات والتنبيهات المتدفقة في الوقت الفعلي
تابع تدفقات السجلات المباشرة ورشّحها لإطلاق التنبيهات لحظة ظهور أنماط الأخطاء
متابعة السجلات والتنبيهات المتدفقة في الوقت الفعلي درس مجاني في DevOps Bootcamp على CoddyKit. هذا هو الدرس 2 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في DevOps Bootcamp، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة DevOps Bootcamp 4 دروس في المجموع.
أهمية متابعة السجلات في الوقت الفعلي
في أنظمة الإنتاج، تنمو ملفات السجلات باستمرار. وانتظار الإبلاغ عن مشكلة قبل فحص السجلات يعني أن فترة التوقف قد ألحقت بك خسائر بالفعل. تتيح لك متابعة السجلات في الوقت الفعلي مراقبة الأحداث لحظة كتابتها، ما يمكّنك من الاستجابة الفورية للأعطال والأحداث الأمنية وتدهور الأداء.
- تكتب خوادم الويب سطرًا واحدًا لكل طلب، فتظهر الأخطاء فورًا
- تسجل خدمات التطبيقات آثار المكدس لحظة وقوع الاستثناء
- تسجل أنظمة المصادقة محاولات تسجيل الدخول الفاشلة في الوقت الفعلي
الأداة الأساسية في Unix لهذا الغرض هي tail -f، التي تُستخدم مع أدوات التصفية والتنبيه لتحويل تدفقات السجلات الخام إلى مؤشرات قابلة للتنفيذ.
tail -f: متابعة سجل مباشر
يبقي tail -f (المتابعة) الملف مفتوحًا ويطبع الأسطر الجديدة عند إلحاقها بالملف. وهو أبسط أدوات السجلات في الوقت الفعلي وأكثرها توفرًا على نطاق واسع.
أنماط الاستخدام الشائعة:
tail -f /var/log/syslog— متابعة سجل النظامtail -n 50 -f app.log— عرض آخر 50 سطرًا ثم متابعة الملفtail -f /var/log/nginx/access.log— متابعة طلبات nginx مباشرة
اضغط Ctrl+C للإيقاف. تظل العملية متصلة حتى تلغيها أو تُغلق الطرفية.
#!/usr/bin/env bash
# Simulate a live log and follow it
LOGFILE='/tmp/demo_app.log'
# Write a header
echo '[INFO] Application started' >> "$LOGFILE"
# In a real scenario you would run:
# tail -f "$LOGFILE"
# Below we demonstrate tail showing the last 3 lines then exit
tail -n 3 "$LOGFILE"tail -F: تجاوز دوران السجلات
تدوّر أنظمة كثيرة ملفات السجلات عند منتصف الليل أو عند بلوغها حدًا معينًا للحجم. عند حدوث ذلك، يُعاد تسمية الملف الأصلي (مثلًا app.log.1) ويُنشأ ملف app.log جديد. عند استخدام tail -f، ستستمر بصمت في قراءة الملف القديم الذي أُعيدت تسميته، وستفقد كل المخرجات الجديدة.
يحل tail -F (بحرف F كبير) هذه المشكلة عبر مراقبة اسم الملف بدلًا من واصف الملف. وعندما يختفي الملف ثم يظهر مجددًا، يعيد tail -F فتحه تلقائيًا ويواصل متابعته.
- فضّل دائمًا
tail -Fعلىtail -fفي نصوص الإنتاج - يعمل مع logrotate وnewsyslog وبرامج تشغيل سجلات Docker التي تدوّر الملفات
# Follow nginx access log, surviving log rotation
tail -F /var/log/nginx/access.log
# Follow multiple files simultaneously
tail -F /var/log/nginx/access.log /var/log/nginx/error.logتصفية التدفق باستخدام grep
تكون متابعة سجل نشط بصورته الخام أمرًا مربكًا — فقد يكتب خادم ويب نشط مئات الأسطر في الثانية. مرّر مخرجات tail -F إلى grep لعزل الأنماط التي تهمك فقط.
الخيارات الأساسية لاستخدام grep مع التدفقات:
--line-buffered— يفرغ كل سطر مطابق فورًا بدلًا من تخزينه مؤقتًا؛ وهو ضروري في المسارات، وإلا ستتأخر المخرجات أو تُفقد-i— مطابقة غير حساسة لحالة الأحرف-E— تعبير نمطي موسّع للتناوب (error|warn|crit)-v— عكس المطابقة (لاستبعاد الأسطر)
# Show only ERROR and WARN lines from a live application log
tail -F /var/log/myapp/app.log | grep --line-buffered -Ei 'error|warn|critical'
# Follow nginx and exclude health-check requests
tail -F /var/log/nginx/access.log | grep --line-buffered -v '/health'إضافة الطوابع الزمنية والسياق باستخدام awk
تفتقر أسطر السجلات أحيانًا إلى سياق يساعد في الفرز الأولي للحوادث. يمكنك إثراء التدفق في الوقت الفعلي باستخدام awk — بإضافة طابع زمني محلي أو استخراج الحقول أو إعادة تنسيق المخرجات لتسهيل قراءتها.
يعمل awk أيضًا في وضع التدفق (مع تخزين مؤقت على مستوى السطر) عند تمريره عبر مسار، ما يجعله آمنًا للاستخدام في المسارات المباشرة من دون خيارات إضافية.
# Prepend a reception timestamp to every ERROR line
tail -F /var/log/myapp/app.log | \
grep --line-buffered -i 'error' | \
awk '{ print strftime("[%Y-%m-%d %H:%M:%S]"), $0; fflush() }'
# Extract HTTP status code (field 9) and URL (field 7) from nginx combined log
tail -F /var/log/nginx/access.log | \
awk '{ print $9, $7; fflush() }' | \
grep --line-buffered '^5'إرسال التنبيهات باستخدام خطافات Slack
التصفية ليست سوى نصف المهمة — فبمجرد اكتشاف نمط خطأ، تحتاج إلى إخطار شخص ما. يتيح لك خطاف Slack الوارد إرسال رسالة إلى قناة عبر استدعاء واحد لـ curl، من دون الحاجة إلى Slack SDK أو بيانات اعتماد تتجاوز عنوان URL للخطاف.
النمط هو: صفِّ التدفق، وأرسل طلب HTTP POST لكل سطر مطابق.
#!/usr/bin/env bash
# Real-time alert: send every ERROR line to a Slack channel
LOGFILE='/var/log/myapp/app.log'
WEBHOOK_URL='https://hooks.slack.com/services/T000/B000/XXXX'
tail -F "$LOGFILE" | grep --line-buffered -i 'error' | while IFS= read -r line; do
payload=$(printf '{"text":"*[ERROR ALERT]*\n%s"}' "$line")
curl -s -o /dev/null -X POST -H 'Content-Type: application/json' \
-d "$payload" "$WEBHOOK_URL"
doneتحديد معدل التنبيهات لمنع الضوضاء
قد تولّد عاصفة السجلات آلاف أسطر الأخطاء في الدقيقة. وسيؤدي إرسال رسالة Slack واحدة لكل سطر إلى إغراق القناة والتسبب في إرهاق التنبيهات. تحتاج إلى تحديد معدل التنبيهات — أطلق التنبيه، ثم امنع الإشعارات اللاحقة خلال فترة تهدئة.
يتحقق ذلك باستخدام ملف طابع زمني بسيط: سجّل وقت إرسال آخر تنبيه، وتجاوز الإرسال إذا لم تنقضِ فترة التهدئة.
#!/usr/bin/env bash
# Alert on ERROR lines but no more than once every 60 seconds
LOGFILE='/var/log/myapp/app.log'
WEBHOOK_URL='https://hooks.slack.com/services/T000/B000/XXXX'
COOLDOWN=60
LAST_ALERT_FILE='/tmp/last_alert_ts'
tail -F "$LOGFILE" | grep --line-buffered -i 'error' | while IFS= read -r line; do
now=$(date +%s)
last=0
[ -f "$LAST_ALERT_FILE" ] && last=$(cat "$LAST_ALERT_FILE")
if (( now - last >= COOLDOWN )); then
echo "$now" > "$LAST_ALERT_FILE"
payload=$(printf '{"text":"*[ERROR ALERT]*\n%s"}' "$line")
curl -s -o /dev/null -X POST -H 'Content-Type: application/json' \
-d "$payload" "$WEBHOOK_URL"
echo "[$(date)] Alert sent: $line"
else
echo "[$(date)] Suppressed (cooldown): $line"
fi
doneحساب دفعات الأخطاء باستخدام نافذة منزلقة
قد لا يكون سطر خطأ واحد مهمًا أحيانًا — لكن 20 خطأً خلال 30 ثانية تمثل مشكلة خطيرة. يتيح لك عدّاد النافذة المنزلقة إطلاق التنبيهات فقط عند تجاوز عتبة معدل الأخطاء، ما يقلل الإنذارات الكاذبة.
تخزّن هذه التقنية الطابع الزمني لكل حدث مطابق بتنسيق epoch في ملف مؤقت، ثم تحصي الأحداث الواقعة ضمن النافذة قبل اتخاذ قرار إرسال التنبيه.
#!/usr/bin/env bash
# Alert when more than 10 errors occur within any 60-second window
LOGFILE='/var/log/myapp/app.log'
WINDOW=60
THRESHOLD=10
TS_FILE='/tmp/error_timestamps'
WEBHOOK_URL='https://hooks.slack.com/services/T000/B000/XXXX'
tail -F "$LOGFILE" | grep --line-buffered -i 'error' | while IFS= read -r line; do
now=$(date +%s)
echo "$now" >> "$TS_FILE"
# Keep only timestamps within the window
cutoff=$(( now - WINDOW ))
tmp=$(mktemp)
awk -v c="$cutoff" '$1 > c' "$TS_FILE" > "$tmp" && mv "$tmp" "$TS_FILE"
count=$(wc -l < "$TS_FILE")
if (( count > THRESHOLD )); then
msg="*[BURST ALERT]* ${count} errors in ${WINDOW}s — last: ${line}"
curl -s -o /dev/null -X POST -H 'Content-Type: application/json' \
-d "{\"text\":\"$msg\"}" "$WEBHOOK_URL"
# Clear to avoid re-alerting until next burst
> "$TS_FILE"
fi
donejournalctl -f: متابعة سجلات systemd
في أنظمة Linux الحديثة (RHEL وUbuntu 20.04+ وDebian 10+)، تكتب الخدمات إلى سجل systemd بدلًا من ملفات نصية عادية. ويُعد journalctl -f المكافئ لـ tail -F بالنسبة إلى السجل.
خيارات مفيدة:
-u myapp.service— متابعة وحدة محددة فقط-p err— التصفية حسب الأولوية (emerg وalert وcrit وerr وwarning وnotice وinfo وdebug)--since '5 min ago'— البدء من وقت نسبي-o json— إخراج JSON منظم لتحليله آليًا
# Follow only error-and-above entries for nginx
journalctl -f -u nginx.service -p err
# Stream journal as JSON and extract MESSAGE field with jq
journalctl -f -u myapp.service -o json | \
jq --unbuffered -r 'select(.PRIORITY <= "3") | .MESSAGE'multitail ومراقبة مصادر متعددة ملوّنة
عندما تحتاج إلى مراقبة عدة مصادر للسجلات في الوقت نفسه، يقسم multitail الطرفية إلى لوحات — تتابع كل منها ملفًا أو أمرًا مختلفًا — مع إمكانية تلوينها حسب النمط.
إذا لم يكن multitail مثبتًا، فثمة بديل خفيف مكتوب باستخدام Bash فقط، وهو إضافة اسم المصدر إلى بداية كل تدفق ودمج التدفقات في عرض واحد.
# multitail: watch nginx access + error + app log in split panes
# (requires: apt install multitail or brew install multitail)
multitail /var/log/nginx/access.log /var/log/nginx/error.log /var/log/myapp/app.log
# Pure-Bash alternative — merge three streams with labeled prefixes
(
tail -F /var/log/nginx/access.log | sed --unbuffered 's/^/[nginx-access] /' &
tail -F /var/log/nginx/error.log | sed --unbuffered 's/^/[nginx-error] /' &
tail -F /var/log/myapp/app.log | sed --unbuffered 's/^/[myapp] /' &
wait
)بناء خدمة تنبيهات مستقلة
بجمع كل ما تناولناه في هذا الدرس، ينبغي لخدمة التنبيهات الملائمة للإنتاج أن:
- تتابع ملف السجل بشكل موثوق باستخدام
tail -F - تصفّي الأنماط الحرجة باستخدام
grepذي التخزين المؤقت - تحدد معدل الإشعارات لتجنب إرهاق التنبيهات
- تسجل نشاطها الخاص كي تتمكن من تدقيق ما أُرسل
- تعمل كعملية في الخلفية يديرها systemd أو مشرف عمليات
النص البرمجي أدناه خدمة بسيطة لكنها مكتملة يمكنك وضعها في /usr/local/bin/ وإدارتها باستخدام systemd.
#!/usr/bin/env bash
# log_alert_daemon.sh — tail a log and fire Slack alerts with cooldown
set -euo pipefail
LOGFILE=${1:-'/var/log/myapp/app.log'}
PATTERN=${2:-'error|critical|fatal'}
WEBHOOK_URL=${SLACK_WEBHOOK_URL:?'Set SLACK_WEBHOOK_URL env var'}
COOLDOWN=${ALERT_COOLDOWN:-120}
DAEMON_LOG='/var/log/log_alert_daemon.log'
LAST_SENT_FILE='/tmp/log_alert_last_sent'
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $*" | tee -a "$DAEMON_LOG"; }
log "Starting alert daemon: watching $LOGFILE for pattern: $PATTERN"
tail -F "$LOGFILE" | grep --line-buffered -Ei "$PATTERN" | while IFS= read -r line; do
now=$(date +%s)
last=0
[ -f "$LAST_SENT_FILE" ] && last=$(cat "$LAST_SENT_FILE")
if (( now - last >= COOLDOWN )); then
echo "$now" > "$LAST_SENT_FILE"
msg=$(printf '{"text":"*[ALERT]* %s\n%s"}' "$(hostname)" "$line")
if curl -s -o /dev/null -w '%{http_code}' -X POST \
-H 'Content-Type: application/json' -d "$msg" "$WEBHOOK_URL" | grep -q '^200$'; then
log "Alert sent: $line"
else
log "Alert FAILED to send: $line"
fi
else
log "Suppressed (cooldown ${COOLDOWN}s): $line"
fi
doneاختبار المعرفة: مسارات السجلات المتدفقة
اختبر فهمك لمتابعة السجلات في الوقت الفعلي والتنبيهات المتدفقة.
يتابع مسار Bash ملف سجل ويرسل تنبيه Slack لكل سطر مطابق. أثناء عاصفة سجلات، يُكتب 3,000 سطر خطأ خلال 10 ثوانٍ. ما التغيير الوحيد الذي يمنع البرنامج بأفضل صورة من إغراق قناة Slack بـ3,000 رسالة؟
مراجعة الدرس: متابعة السجلات في الوقت الفعلي والتنبيهات المتدفقة
في هذا الدرس أنشأت مسارًا متكاملًا لمراقبة السجلات في الوقت الفعلي من المبادئ الأساسية:
- tail -F يتابع ملف السجل حسب اسمه ويتجاوز دوران السجلات — لذا فضّله دائمًا على
tail -fفي الإنتاج - grep --line-buffered يصفّي التدفق المباشر من دون إضافة تأخير؛ أضف هذا الخيار دائمًا إلى أوامر grep الممررة عبر مسار
- awk مع fflush() يثري كل سطر بالطوابع الزمنية أو الحقول المستخرجة بطريقة آمنة للتدفق
- خطافات Slack عبر curl توصل التنبيهات عبر HTTP POST واحد — من دون الحاجة إلى SDK
- ملفات التهدئة تمنع إرهاق التنبيهات أثناء عواصف السجلات من خلال فرض حد أدنى للفاصل بين الإشعارات
- عدادات النوافذ المنزلقة تكتشف دفعات الأخطاء (التنبيه القائم على المعدل) بدلًا من الاستجابة لكل سطر على حدة
- journalctl -f هو المكافئ الأصلي في systemd لـ tail -F، مع تصفية مدمجة حسب الأولوية وإخراج JSON
- يجمع نص خدمة التنبيهات المستقلة كل هذه الأنماط، ويمكن إدارة الخدمة باستخدام systemd لتحقيق موثوقية الإنتاج
تشكل هذه الأساسيات قاعدة أي مسار مخصص لمراقبة الأنظمة — من دون الحاجة إلى وكيل تابع لجهة خارجية.
الأسئلة الشائعة
هل درس «متابعة السجلات والتنبيهات المتدفقة في الوقت الفعلي» مجاني؟
نعم — نص درس «متابعة السجلات والتنبيهات المتدفقة في الوقت الفعلي» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة DevOps Bootcamp، انتقل إلى CoddyKit PRO. تتضمن دورة DevOps Bootcamp 4 دروس في المجموع.
ماذا ستتعلم في «متابعة السجلات والتنبيهات المتدفقة في الوقت الفعلي»؟
تابع تدفقات السجلات المباشرة ورشّحها لإطلاق التنبيهات لحظة ظهور أنماط الأخطاء تتمرن على DevOps Bootcamp مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ DevOps Bootcamp؟
لا تُشترط خبرة سابقة. DevOps Bootcamp على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 2 من أصل 4.
كم من الوقت يستغرق درس «متابعة السجلات والتنبيهات المتدفقة في الوقت الفعلي»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس DevOps Bootcamp هذا؟
نعم. كل درس في DevOps Bootcamp يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تحليل سجلات الويب والتطبيقات على نطاق واسع
- متابعة السجلات والتنبيهات المتدفقة في الوقت الفعلي
- الاستعلام عن journald باستخدام journalctl داخل السكربتات
- حساب المقاييس والمدرّجات التكرارية من تدفقات السجلات