سجلّات الخادم: من نصّ إلى جدول
السلوك الحقيقي مكتوبٌ في السجلّات؛ كيف نحوّله من نصٍّ خام إلى جدول؟ ⏱ نحو 45 دقيقة.
- تدرك قيمة سجلّات الخادم للسلوك.
- تقطّع السجلّ المنتظم بـ
split. - تستخرج الحقول من السجلّ المعقّد بـ
Regexوstr.extract. - تحوّل الأعمدة الرقمية وتكتشف الأخطاء.
١كنزٌ في السجلّات
كل خادم ويب يكتب سجلًّا: سطرٌ لكل طلب فيه عنوان الزائر، والفعل، والمسار، ورمز الحالة، والزمن. هذه أثمن بيانات السلوك، لكنها نصّ خام لا جدول. مهمّتنا تحويلها إلى DataFrame.
٢التقطيع البسيط بـ split
حين تكون الحقول مفصولة بمسافات منتظمة، يكفي split لكل سطر:
log = """192.168.1.10 - GET /home 200 120192.168.1.11 - GET /products 200 340192.168.1.10 - POST /cart 201 90192.168.1.12 - GET /missing 404 20192.168.1.11 - GET /checkout 200 510"""rows = []for line in log.strip().split("\n"): ip, _, method, path, status, ms = line.split() rows.append({"ip": ip, "method": method, "path": path, "status": int(status), "ms": int(ms)}) import pandas as pddf = pd.DataFrame(rows)print(df)print("متوسط الزمن:", df["ms"].mean(), "مللي")
٣التعابير النمطية للسجلّات المعقّدة
السجلّات الحقيقية غير منتظمة (أقواس، اقتباسات). عندها نستخدم التعبير النمطي Regex لاستخراج الحقول بدقّة. وstr.extract يطبّقه على عمودٍ كامل دفعةً:
log = """192.168.1.10 - GET /home 200 120192.168.1.11 - GET /products 200 340192.168.1.10 - POST /cart 201 90192.168.1.12 - GET /missing 404 20192.168.1.11 - GET /checkout 200 510"""import pandas as pds = pd.Series(log.strip().split("\n")) # نمط: IP ... method path status mspat = r"(?P<ip>\S+) - (?P<method>\w+) (?P<path>\S+) (?P<status>\d+) (?P<ms>\d+)"df = s.str.extract(pat)df["status"] = df["status"].astype(int)df["ms"] = df["ms"].astype(int) print(df[["method", "path", "status"]])print("طلبات فاشلة (>=400):", int((df["status"] >= 400).sum()))
المجموعات المسمّاة (?P<name>...) تصير أسماء أعمدة تلقائيًّا. هذا أمتن تقطيعٍ للسجلّات.
توقّع وتحقّق
لتقطيع سطرٍ منتظم بمسافات:
لاستخراج حقول من نصّ غير منتظم:
str.extract مع مجموعات مسمّاة ينتج:
رمز 404 يعني:
الخلاصة
- سجلّ الخادم سطرٌ لكل طلب: أثمن بيانات السلوك، لكنه نصّ خام.
- المنتظم يُقطَّع بـ
split؛ والمعقّد يُستخرَج بتعبيرٍ نمطي. str.extractمع مجموعات مسمّاة يبني أعمدة الجدول مباشرة.- حوّل
statusوmsلأرقام، وراقب4xx/5xxلاكتشاف المشاكل.
تحدٍّ برمجي: حلّل سجلًّا
متقدمحوّل السجلّ إلى جدول، واطبع عدد الطلبات الفاشلة (status ≥ 400)، وأبطأ مسار (الأعلى ms).
- قطّع كل سطر إلى حقوله وابنِ DataFrame بأعمدة رقمية.
- اطبع عدد الطلبات ≥ 400، ثم المسار الأبطأ.
ابدأ من هذا الكود، واضغط ▶ شغّل هنا لتكتب حلّك وتجرّبه مباشرة:
log = """10.0.0.1 - GET /home 200 12010.0.0.2 - GET /api 500 80010.0.0.1 - GET /x 404 3010.0.0.3 - POST /pay 200 650"""import pandas as pd# ابنِ الجدول ثم اطبع عدد الفاشلة (>=400) وأبطأ مسار
💡 تلميح 1
ip, _, method, path, status, ms = line.split().💡 تلميح 2
df.loc[df["ms"].idxmax(), "path"].حاول بنفسك أولًا؛ للمسألة أكثر من حلّ صحيح.
log = """10.0.0.1 - GET /home 200 12010.0.0.2 - GET /api 500 80010.0.0.1 - GET /x 404 3010.0.0.3 - POST /pay 200 650"""import pandas as pdrows = []for line in log.strip().split("\n"): ip, _, method, path, status, ms = line.split() rows.append({"path": path, "status": int(status), "ms": int(ms)})df = pd.DataFrame(rows)print(int((df["status"] >= 400).sum()))print(df.loc[df["ms"].idxmax(), "path"])