تحليل سجلات الويب والتطبيقات على نطاق واسع
استخرج رموز الحالة وأزمنة الاستجابة وحقول العملاء من سجلات الوصول باستخدام grep وcut وawk
تحليل سجلات الويب والتطبيقات على نطاق واسع درس مجاني في Linux Command Line & Bash Scripting Mastery على CoddyKit. هذا هو الدرس 1 من أصل 4. يمكنك قراءة الدرس كاملاً أدناه مجاناً — ثم تمرن عليه مباشرة في المتصفح باستخدام محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7. هذا الدرس جزء من مسار التعلم في Linux Command Line & Bash Scripting Mastery، وتقدمك يتزامن عبر الويب وتطبيق CoddyKit. تتضمن دورة Linux Command Line & Bash Scripting Mastery 4 دروس في المجموع.
ما سجل الوصول إلى الويب؟
يكتب كل خادم HTTP — Apache وNginx وCaddy — سطراً واحداً في سجل الوصول لكل طلب. ويُعد فهم بنية هذه الأسطر أساس جميع أعمال تحليل السجلات.
يبدو سطر نموذجي بتنسيق Combined Log Format (CLF) كما يلي:
- عنوان IP للعميل — الجهة التي أجرت الطلب
- الطابع الزمني — وقت حدوثه
- سطر الطلب — الطريقة والمسار والبروتوكول
- رمز الحالة — استجابة HTTP (200 و404 و500…)
- البايتات المرسلة — حجم نص الاستجابة
- Referer — الصفحة المصدر
- User-Agent — سلسلة تعريف المتصفح أو الروبوت
مثال على سطر من /var/log/nginx/access.log:
192.168.1.10 - alice [11/Jun/2026:14:32:01 +0000] "GET /api/orders HTTP/1.1" 200 1482 "-" "curl/7.88.1"
عند العمل على نطاق واسع، تنمو هذه الملفات إلى ملايين الأسطر يومياً. والهدف من هذا الدرس هو استخراج الحقول وتصفيتها وتجميعها بكفاءة باستخدام أدوات BASH القياسية.
أخذ عينة من سجل حي باستخدام tail وgrep
قبل كتابة أي مسار معالجة، افحص السجل لفهم بنيته. يتيح لك tail مراقبة تدفق حي، بينما يضيّق grep نطاقه فوراً إلى الأسطر ذات الصلة.
الأنماط الشائعة:
tail -n 1000 access.log— آخر 1000 سطرtail -f access.log— المتابعة في الوقت الفعليtail -f access.log | grep '" 5'— أخطاء 5xx فقط أثناء وصولها
الفكرة الأساسية هي أن grep يطابق السطر بأكمله، لذلك يهم تثبيت نمط البحث. إن مطابقة ' 500 ' (مع المسافات) تمنع المطابقة غير المقصودة لمسار URL يحتوي على السلسلة 500.
#!/usr/bin/env bash
# Watch only HTTP 5xx errors arriving in real time
tail -f /var/log/nginx/access.log \
| grep --line-buffered '" 5[0-9][0-9] 'استخراج رمز الحالة باستخدام cut
يقسم cut كل سطر وفق محدِّد ويطبع الحقول المحددة. في Combined Log Format يوجد رمز الحالة في الحقل 9 عند التقسيم وفق المسافات، لكن علامات الاقتباس المحيطة بسطر الطلب تجعل العد انطلاقاً من نقطة معروفة أكثر أماناً.
تتمثل حيلة موثوقة في أن سطر الطلب يكون دائماً بين علامتي اقتباس، ولذلك يكون رمز الحالة دائماً أول قيمة بعد علامة الاقتباس الختامية لحقل الطلب. يعزل استخدام cut -d'"' -f3 كل ما بعد علامة اقتباس الطلب، ثم يختار cut -d' ' -f2 الثاني رمز الحالة.
يُعد هذا الاستخدام على مرحلتين لـ cut أسلوباً شائعاً في سجلات CLF — سريعاً ولا يعتمد على تبعيات خارجية.
#!/usr/bin/env bash
# Print only the HTTP status code from each log line
# Input format: ... "GET /path HTTP/1.1" 200 1482 ...
cut -d'"' -f3 /var/log/nginx/access.log \
| cut -d' ' -f2 \
| sort \
| uniq -c \
| sort -rnعد رموز الحالة باستخدام awk
يُعد awk أقوى من cut لأنه يستطيع تراكم الحالة عبر الأسطر. والنمط الاصطلاحي لعد التكرارات هو استخدام مصفوفة ترابطية يكون مفتاحها القيمة التي تهمك.
في CLF، يمثّل الحقل $9 (بفهرسة تبدأ من 1 وبفصل المسافات) رمز الحالة. يعالج awk كل سطر، ويزيد العداد، ثم يطبع ملخصاً مرتّباً داخل كتلة END.
لماذا نفضّل awk على cut | sort | uniq -c؟ لأن awk ينفذ ذلك في مرور واحد دون ترتيب الملف بأكمله أولاً — وهو أمر حاسم عندما يبلغ حجم السجل مئات الغيغابايت.
#!/usr/bin/env bash
# Count HTTP status codes in a single awk pass
awk '{ count[$9]++ }
END {
for (status in count)
printf "%6d %s\n", count[status], status
}' /var/log/nginx/access.log \
| sort -rnتصفية الأخطاء واستخراج عناوين IP للعملاء
من أكثر المهام التشغيلية شيوعاً تحديد عناوين IP للعملاء التي تولّد أكبر عدد من الأخطاء. ويجمع ذلك بين التصفية (أسطر الأخطاء فقط) واستخراج الحقول (عنوان IP في الحقل 1).
استراتيجية مسار المعالجة:
- استخدم
awkللتصفية وفق نطاق رمز الحالة واستخراج عنوان IP في خطوة واحدة — وتجنب تمريرةgrepمنفصلة - مرّر الناتج إلى
sort | uniq -c | sort -rn | headللحصول سريعاً على عرض لأعلى N نتائج
هذا النمط سريع بما يكفي لتشغيله على ملف سجل حجمه 10 غيغابايت في خادم واحد دون تحميل الملف إلى الذاكرة.
#!/usr/bin/env bash
# Top 10 IPs generating HTTP 4xx or 5xx errors
awk '$9 ~ /^[45][0-9][0-9]$/ { print $1 }' \
/var/log/nginx/access.log \
| sort \
| uniq -c \
| sort -rn \
| head -10تحليل زمن استجابة الطلبات من سجلات التطبيقات
تسجل خوادم التطبيقات (Rails وGunicorn وExpress مع morgan وغير ذلك) مدة الطلب غالباً. ويمكن تهيئة Nginx لإخراج $request_time كحقل إضافي في نهاية كل سطر.
مثال على تنسيق سجل مخصص في Nginx داخل nginx.conf:
log_format timed '$remote_addr - $remote_user [$time_local] "$request" $status $body_bytes_sent "$http_referer" "$http_user_agent" rt=$request_time';
بعد تسجيل زمن الاستجابة، يمكنك استخدام awk لحساب المتوسط والقيمة القصوى والتقديرات المئينية عبر ملايين الطلبات دون تحميل البيانات إلى قاعدة بيانات.
#!/usr/bin/env bash
# Compute average and max request_time from Nginx timed log
# Assumes last field is rt=<seconds> e.g. rt=0.042
awk '{
# Extract numeric value after rt=
n = split($NF, a, "=")
if (n == 2 && a[1] == "rt") {
t = a[2] + 0
sum += t
count++
if (t > max) max = t
}
}
END {
if (count > 0)
printf "Requests: %d Avg: %.4fs Max: %.4fs\n", count, sum/count, max
}' /var/log/nginx/timed_access.logإنشاء مدرج تكراري لزمن الاستجابة باستخدام awk
يخفي المتوسط الواحد زمن الاستجابة في الطرف البعيد من التوزيع. أما المدرج التكراري فيكشف التوزيع — أي ما إذا كانت معظم الطلبات سريعة وبعضها بطيئاً جداً (ذيل طويل)، أو ما إذا كان التوزيع منتظماً.
تتمثل الحيلة في وضع كل قيمة داخل نطاق مقرب باستخدام الحساب الصحيح داخل awk. يؤدي الضرب في 1000 (لتحويل الثواني إلى ميلي ثانية) ثم استخدام القسمة الصحيحة إلى إنشاء حدود واضحة للفئات.
ينتج عن ذلك مدرج تكراري نصي يمكنك قراءته مباشرة في الطرفية، وغالباً ما يكون ذلك أسرع من إرسال البيانات إلى Grafana لإجراء تحقيق سريع.
#!/usr/bin/env bash
# Latency histogram (50ms buckets) from Nginx timed log
awk '{
n = split($NF, a, "=")
if (n == 2 && a[1] == "rt") {
ms = int(a[2] * 1000) # convert to ms
bucket = int(ms / 50) * 50 # round down to 50ms boundary
hist[bucket]++
}
}
END {
for (b in hist)
printf "%6dms %d\n", b, hist[b]
}' /var/log/nginx/timed_access.log \
| sort -nاستخراج User-Agent واكتشاف الروبوتات
يحدد حقل User-Agent (الحقل 6 عند التقسيم وفق ") العملاء. وغالباً ما تلوّث برامج الزحف والكاشطات والروبوتات الضارة مقاييسك وتضخم أعداد الأخطاء. ويمنحك استبعادها صورة أوضح لحركة المستخدمين الفعليين.
توقيعات الروبوتات الشائعة: bot وcrawler وspider وcurl وpython-requests وGooglebot وBingbot.
استخدم grep -iv (عكس المطابقة مع تجاهل حالة الأحرف) لاستبعاد الروبوتات المعروفة، أو استخدم awk للتقسيم وفق " ومطابقة حقل UA مباشرة.
#!/usr/bin/env bash
# Count top 15 User-Agent strings, excluding known bots
awk -F'"' '{ print $6 }' /var/log/nginx/access.log \
| grep -iv -e 'bot' -e 'crawler' -e 'spider' -e 'curl' \
-e 'python' -e 'wget' -e 'Go-http-client' \
| sort \
| uniq -c \
| sort -rn \
| head -15تجميع حركة المرور حسب نقطة النهاية
يساعدك معرفة نقاط النهاية التي تستقبل أكبر قدر من حركة المرور — وتولّد أكبر عدد من الأخطاء — على تحديد أولويات التحسين والتخطيط للسعة. يوجد مسار الطلب داخل حقل الطلب المحاط بعلامتي اقتباس.
قسّم وفق "، وخذ الحقل 2 (سطر الطلب)، ثم استخرج الطريقة والبروتوكول لعزل المسار. وبالنسبة إلى واجهات API التي تحتوي على مَعلمات مسار مثل /users/12345، قد ترغب أيضاً في توحيد المعرّفات إلى /users/:id باستخدام sed أو نمط awk أكثر تعقيداً.
#!/usr/bin/env bash
# Top 20 requested endpoints (method + path, no query string)
awk -F'"' '{ print $2 }' /var/log/nginx/access.log \
| awk '{ print $1, $2 }' \
| sed 's|/[0-9][0-9]*\b|/:id|g' \
| sort \
| uniq -c \
| sort -rn \
| head -20ربط الأخطاء بنقاط النهاية باستخدام awk
يجمع أقوى تحليل في مرور واحد حقولاً متعددة في الوقت نفسه: نقطة النهاية ورمز الحالة وزمن الاستجابة اختيارياً. وتتيح المصفوفات الترابطية في awk، التي تستخدم قيماً مركبة كمفاتيح، تنفيذ ذلك بوضوح وسرعة.
يعدّ النمط أدناه أخطاء 5xx لكل نقطة نهاية في مرور واحد — دون ملفات مؤقتة أو عمليات ترتيب وسيطة حتى النهاية. وهذا هو الأسلوب المستخدم في سكربتات قابلية المراقبة في بيئات الإنتاج عندما تحتاج إلى إجابات خلال أقل من دقيقة على سجل كبير.
#!/usr/bin/env bash
# Count 5xx errors per endpoint path in a single pass
awk -F'"' '{
# $2 = request line e.g. "GET /api/orders HTTP/1.1"
# $0 in original space-split: $9 = status
split($0, fields, " ")
status = fields[9]
if (status ~ /^5/) {
split($2, req, " ")
path = req[2]
# Normalise numeric IDs
gsub(/\/[0-9]+/, "/:id", path)
errors[path]++
}
}
END {
for (p in errors)
printf "%6d %s\n", errors[p], p
}' /var/log/nginx/access.log \
| sort -rn \
| head -20معالجة السجلات المدورة والمضغوطة
تُدوّر السجلات يومياً في معظم الخوادم. وتُضغط الملفات الأقدم باستخدام gzip لتصبح مثل access.log.1.gz وaccess.log.2.gz وغير ذلك. ولا تستطيع الأدوات القياسية قراءتها مباشرة، لكن يوجد أسلوبان يعملان بكفاءة:
zcat— فك الضغط إلى stdout وتمرير الناتج إلى مسار المعالجةzgrep— تنفيذ grep مباشرة داخل ملفات gzip دون فكها
لتحليل أسبوع كامل من السجلات التي تضم ملفات غير مضغوطة وأخرى مضغوطة، استخدم استبدال العمليات أو ادمج الملفات باستخدام zcat. يعالج المقطع أدناه آخر 7 ملفات مدوّرة بالإضافة إلى السجل الحالي الحي، وذلك في استدعاء واحد لـ awk — دون الحاجة إلى ملفات مؤقتة.
#!/usr/bin/env bash
# Aggregate status codes across a week of rotated logs
# Handles both plain and gzip-compressed rotation files
LOG_DIR="/var/log/nginx"
{
cat "${LOG_DIR}/access.log" 2>/dev/null
zcat "${LOG_DIR}/access.log".*.gz 2>/dev/null
} | awk '
{ count[$9]++ }
END {
for (s in count)
printf "%6d %s\n", count[s], s
}' | sort -rnأي حقل في awk يحتوي على رمز حالة HTTP في Combined Log Format؟
أنت تكتب تعليمة من سطر واحد باستخدام awk لتصفية استجابات HTTP من الفئة 4xx فقط من سجل وصول Nginx قياسي بتنسيق Combined Log Format (مفصول بمسافات، مع وضع سطر الطلب بين علامتي اقتباس). ما رقم الحقل الذي يحدد رمز حالة HTTP بشكل صحيح؟
مراجعة الدرس: مسارات تحليل السجلات
في هذا الدرس أنشأت مجموعة أدوات متكاملة لتحليل سجلات الويب والتطبيقات على نطاق واسع باستخدام أدوات BASH القياسية فقط.
التقنيات الأساسية التي تناولناها:
- ابدأ بالبنية — يتميز Combined Log Format بتخطيط متوقع للحقول؛ ومعرفته تتيح لك تقسيم السجل بشكل موثوق باستخدام
cut -d'"'أو مراجع الحقول فيawk. - استخراج رموز الحالة — يحصي
awk '{ count[$9]++ }'جميع الرموز في مرور واحد؛ ولتصفية أخطاء الخادم استخدم$9 ~ /^5/. - تحليل زمن الاستجابة — حلّل الحقل المخصص
rt=باستخدامawkلحساب المتوسطات والقيم القصوى وفئات المدرج التكراري من دون أي أداة خارجية. - تحليل العملاء والروبوتات — قسّم السجل عند
"باستخدام-F'"'للوصول إلى حقل User-Agent؛ ثم مرّر الناتج عبرgrep -ivلاستبعاد الروبوتات قبل التجميع. - توحيد نقاط النهاية — استخدم
gsub(/\/[0-9]+/, "/:id")داخلawkلدمج المسارات التي تحتوي على معلمات قبل إحصائها. - السجلات المدورة — ادمج
catوzcatفي subshell لتمرير جميع ملفات الدوران إلى مسار واحد في مرور واحد.
يمكن تركيب هذه الأنماط معًا: إذ يمكنك ربط التصفية والاستخراج والتوحيد والتجميع في مسار واحد يعالج مئات الملايين من الأسطر على أجهزة عادية. أتقن هذه الأساسيات، ونادرًا ما ستحتاج إلى خدمة مخصصة لتجميع السجلات أثناء التحقيقات الفورية في الحوادث.
الأسئلة الشائعة
هل درس «تحليل سجلات الويب والتطبيقات على نطاق واسع» مجاني؟
نعم — نص درس «تحليل سجلات الويب والتطبيقات على نطاق واسع» كامل متاح مجاناً هنا على الويب. لتمرينه بشكل تفاعلي (محرر أكواد مدمج ومدرس ذكاء اصطناعي متاح 24/7) وفتح باقي دورة Linux Command Line & Bash Scripting Mastery، انتقل إلى CoddyKit PRO. تتضمن دورة Linux Command Line & Bash Scripting Mastery 4 دروس في المجموع.
ماذا ستتعلم في «تحليل سجلات الويب والتطبيقات على نطاق واسع»؟
استخرج رموز الحالة وأزمنة الاستجابة وحقول العملاء من سجلات الوصول باستخدام grep وcut وawk تتمرن على Linux Command Line & Bash Scripting Mastery مع أكواد عملية تشغلها مباشرة في المتصفح، ومدرس ذكاء اصطناعي متاح 24/7 يجيب على أسئلتك أثناء عملك.
هل أحتاج إلى خبرة سابقة لأبدأ Linux Command Line & Bash Scripting Mastery؟
لا تُشترط خبرة سابقة. Linux Command Line & Bash Scripting Mastery على CoddyKit منظم للمبتدئين حتى المتقدمين، لذا يمكنك البدء من هنا أو من البداية والتقدم بسرعتك الخاصة. هذا هو الدرس 1 من أصل 4.
كم من الوقت يستغرق درس «تحليل سجلات الويب والتطبيقات على نطاق واسع»؟
معظم دروس CoddyKit تستغرق حوالي 5–10 دقائق. كل منها موجز وتفاعلي، لذا تحرز تقدماً مستمراً وتستأنف من حيث توقفت عبر الويب والتطبيق.
هل يمكنني كتابة وتشغيل أكواد في درس Linux Command Line & Bash Scripting Mastery هذا؟
نعم. كل درس في Linux Command Line & Bash Scripting Mastery يتضمن محرر أكواد مدمج، لذا تكتب وتشغل أكواداً حقيقية مباشرة في متصفحك وتحصل على تعليقات فورية من الذكاء الاصطناعي — بدون إعداد محلي.
جميع الدروس في هذه الدورة
- تحليل سجلات الويب والتطبيقات على نطاق واسع
- متابعة السجلات والتنبيهات المتدفقة في الوقت الفعلي
- الاستعلام عن journald باستخدام journalctl داخل السكربتات
- حساب المقاييس والمدرّجات التكرارية من تدفقات السجلات