إحصائيات الموقع ومستودعك الصغير

ساعدتني أداة Webalizer وأداة Google Analytics لسنوات عديدة للحصول على فكرة عما يحدث على مواقع الويب. أفهم الآن أنها توفر القليل جدًا من المعلومات المفيدة. إن الوصول إلى ملف access.log الخاص بك ، والتعامل مع الإحصائيات بسيط للغاية ولتنفيذ الأدوات الأساسية إلى حد ما مثل sqlite و html و sql وأي لغة برمجة نصية.

مصدر بيانات Webalizer هو ملف access.log الخاص بالخادم. هذه هي الطريقة التي تبدو بها الأعمدة والأرقام ، والتي لا يتعدى إجمالي عدد الزيارات فيها فقط:

صورة

صورة

تقوم أدوات مثل Google Analytics بجمع البيانات من الصفحة المحملة بمفردها. إنها تبين لنا اثنين من المخططات والخطوط ، والتي يصعب على أساسها في كثير من الأحيان استخلاص الاستنتاجات الصحيحة. ربما كان هناك حاجة إلى مزيد من الجهد؟ لا اعرف

لذا ، ما الذي أريد أن أراه في إحصائيات زيارات الموقع؟

المستخدم والروبوت المرور


غالبًا ما يكون لحركة زيارات الموقع حد وتحتاج إلى معرفة مقدار حركة المرور المفيدة. على سبيل المثال ، مثل هذا:

صورة

طلب تقرير SQL
SELECT 1 as 'StackedArea: Traffic generated by Users and Bots', strftime('%d.%m', datetime(FCT.EVENT_DT, 'unixepoch')) AS 'Day', SUM(CASE WHEN USG.AGENT_BOT!='na' THEN FCT.BYTES ELSE 0 END)/1000 AS 'Bots, KB', SUM(CASE WHEN USG.AGENT_BOT='na' THEN FCT.BYTES ELSE 0 END)/1000 AS 'Users, KB' FROM FCT_ACCESS_USER_AGENT_DD FCT, DIM_USER_AGENT USG WHERE FCT.DIM_USER_AGENT_ID=USG.DIM_USER_AGENT_ID AND datetime(FCT.EVENT_DT, 'unixepoch') >= date('now', '-14 day') GROUP BY strftime('%d.%m', datetime(FCT.EVENT_DT, 'unixepoch')) ORDER BY FCT.EVENT_DT 


من الرسم البياني يمكنك رؤية النشاط المستمر للروبوتات. سيكون من المثير للاهتمام دراسة بالتفصيل الممثلين الأكثر نشاطا.

السير المزعجة


نقوم بتصنيف الروبوتات بناءً على معلومات وكيل المستخدم. إحصاءات إضافية عن حركة المرور اليومية ، وعدد الطلبات الناجحة وغير الناجحة يعطي فكرة جيدة عن نشاط الروبوتات.

صورة

طلب تقرير SQL
 SELECT 1 AS 'Table: Annoying Bots', MAX(USG.AGENT_BOT) AS 'Bot', ROUND(SUM(FCT.BYTES)/1000 / 14.0, 1) AS 'KB per Day', ROUND(SUM(FCT.IP_CNT) / 14.0, 1) AS 'IPs per Day', ROUND(SUM(CASE WHEN STS.STATUS_GROUP IN ('Client Error', 'Server Error') THEN FCT.REQUEST_CNT / 14.0 ELSE 0 END), 1) AS 'Error Requests per Day', ROUND(SUM(CASE WHEN STS.STATUS_GROUP IN ('Successful', 'Redirection') THEN FCT.REQUEST_CNT / 14.0 ELSE 0 END), 1) AS 'Success Requests per Day', USG.USER_AGENT_NK AS 'Agent' FROM FCT_ACCESS_USER_AGENT_DD FCT, DIM_USER_AGENT USG, DIM_HTTP_STATUS STS WHERE FCT.DIM_USER_AGENT_ID = USG.DIM_USER_AGENT_ID AND FCT.DIM_HTTP_STATUS_ID = STS.DIM_HTTP_STATUS_ID AND USG.AGENT_BOT != 'na' AND datetime(FCT.EVENT_DT, 'unixepoch') >= date('now', '-14 day') GROUP BY USG.USER_AGENT_NK ORDER BY 3 DESC LIMIT 10 


في هذه الحالة ، أسفر التحليل عن قرار بتقييد الوصول إلى الموقع عن طريق إضافة ملف robots.txt إلى الملف

User-agent: AhrefsBot
Disallow: /
User-agent: dotbot
Disallow: /
User-agent: bingbot
Crawl-delay: 5

اختفت أول روبوتين من الجدول ، وانتقلت روبوتات MS لأسفل من الخطوط الأولى.

يوم ووقت النشاط الأكثر


حركة المرور يظهر شكا. لدراستها بالتفصيل ، من الضروري تحديد وقت حدوثها ، في حين أنه ليس من الضروري عرض جميع ساعات وأيام قياس الوقت. لذلك سيكون من الأسهل العثور على استعلامات فردية في ملف السجل إذا كنت بحاجة إلى تحليل مفصل.

صورة

طلب تقرير SQL
 SELECT 1 AS 'Line: Day and Hour of Hits from Users and Bots', strftime('%d.%m-%H', datetime(EVENT_DT, 'unixepoch')) AS 'Date Time', HIB AS 'Bots, Hits', HIU AS 'Users, Hits' FROM ( SELECT EVENT_DT, SUM(CASE WHEN AGENT_BOT!='na' THEN LINE_CNT ELSE 0 END) AS HIB, SUM(CASE WHEN AGENT_BOT='na' THEN LINE_CNT ELSE 0 END) AS HIU FROM FCT_ACCESS_REQUEST_REF_HH WHERE datetime(EVENT_DT, 'unixepoch') >= date('now', '-14 day') GROUP BY EVENT_DT ORDER BY SUM(LINE_CNT) DESC LIMIT 10 ) ORDER BY EVENT_DT 


نلاحظ الساعات الأكثر نشاطًا 11 و 14 و 20 من اليوم الأول على الرسم البياني. ولكن في اليوم التالي في الساعة 13 ، كانت الروبوتات نشطة.

متوسط ​​نشاط المستخدم اليومي الأسبوعي


مع النشاط وحركة المرور برزت قليلا. كان السؤال التالي هو نشاط المستخدمين أنفسهم. بالنسبة إلى هذه الإحصاءات ، تكون فترات التجميع الكبيرة ، على سبيل المثال ، أسبوعًا ، مرغوبة.

صورة

طلب تقرير SQL
 SELECT 1 as 'Line: Average Daily User Activity by Week', strftime('%W week', datetime(FCT.EVENT_DT, 'unixepoch')) AS 'Week', ROUND(1.0*SUM(FCT.PAGE_CNT)/SUM(FCT.IP_CNT),1) AS 'Pages per IP per Day', ROUND(1.0*SUM(FCT.FILE_CNT)/SUM(FCT.IP_CNT),1) AS 'Files per IP per Day' FROM FCT_ACCESS_USER_AGENT_DD FCT, DIM_USER_AGENT USG, DIM_HTTP_STATUS HST WHERE FCT.DIM_USER_AGENT_ID=USG.DIM_USER_AGENT_ID AND FCT.DIM_HTTP_STATUS_ID = HST.DIM_HTTP_STATUS_ID AND USG.AGENT_BOT='na' /* users only */ AND HST.STATUS_GROUP IN ('Successful') /* good pages */ AND datetime(FCT.EVENT_DT, 'unixepoch') > date('now', '-3 month') GROUP BY strftime('%W week', datetime(FCT.EVENT_DT, 'unixepoch')) ORDER BY FCT.EVENT_DT 


تظهر إحصائيات الأسبوع أن مستخدمًا واحدًا يفتح في المتوسط ​​1.6 صفحة في اليوم. يعتمد عدد الملفات المطلوبة لكل مستخدم في هذه الحالة على إضافة ملفات جديدة إلى الموقع.

جميع الطلبات وحالتها


أظهر Webalizer دائمًا رموز صفحات محددة وأردت دائمًا رؤية عدد الطلبات والأخطاء الناجحة فقط.

صورة

طلب تقرير SQL
 SELECT 1 as 'Line: All Requests by Status', strftime('%d.%m', datetime(FCT.EVENT_DT, 'unixepoch')) AS 'Day', SUM(CASE WHEN STS.STATUS_GROUP='Successful' THEN FCT.REQUEST_CNT ELSE 0 END) AS 'Success', SUM(CASE WHEN STS.STATUS_GROUP='Redirection' THEN FCT.REQUEST_CNT ELSE 0 END) AS 'Redirect', SUM(CASE WHEN STS.STATUS_GROUP='Client Error' THEN FCT.REQUEST_CNT ELSE 0 END) AS 'Customer Error', SUM(CASE WHEN STS.STATUS_GROUP='Server Error' THEN FCT.REQUEST_CNT ELSE 0 END) AS 'Server Error' FROM FCT_ACCESS_USER_AGENT_DD FCT, DIM_HTTP_STATUS STS WHERE FCT.DIM_HTTP_STATUS_ID=STS.DIM_HTTP_STATUS_ID AND datetime(FCT.EVENT_DT, 'unixepoch') >= date('now', '-14 day') GROUP BY strftime('%d.%m', datetime(FCT.EVENT_DT, 'unixepoch')) ORDER BY FCT.EVENT_DT 


يعرض التقرير الطلبات ، وليس النقرات (الزيارات) ، بخلاف LINE_CNT ، يُعتبر المقياس REQUEST_CNT COUNT (DISTINCT STG.REQUEST_NK). الهدف من ذلك هو إظهار الأحداث الفعّالة ، على سبيل المثال ، برنامج MS bots لمئات المرات في اليوم لاستطلاع ملف robots.txt ، وفي هذه الحالة ، سيتم حساب هذه الاستطلاعات مرة واحدة. هذا يسمح لك بسلاسة القفزات على المخطط.

من الرسم البياني يمكنك رؤية العديد من الأخطاء - هذه هي صفحات غير موجودة. كانت نتيجة التحليل إضافة عمليات إعادة التوجيه من الصفحات البعيدة.

طلبات خاطئة


لمراجعة مفصلة للطلبات ، يمكنك عرض إحصائيات مفصلة.

صورة

طلب تقرير SQL
 SELECT 1 AS 'Table: Top Error Requests', REQ.REQUEST_NK AS 'Request', 'Error' AS 'Request Status', ROUND(SUM(FCT.LINE_CNT) / 14.0, 1) AS 'Hits per Day', ROUND(SUM(FCT.IP_CNT) / 14.0, 1) AS 'IPs per Day', ROUND(SUM(FCT.BYTES)/1000 / 14.0, 1) AS 'KB per Day' FROM FCT_ACCESS_REQUEST_REF_HH FCT, DIM_REQUEST_V_ACT REQ WHERE FCT.DIM_REQUEST_ID = REQ.DIM_REQUEST_ID AND FCT.STATUS_GROUP IN ('Client Error', 'Server Error') AND datetime(FCT.EVENT_DT, 'unixepoch') >= date('now', '-14 day') GROUP BY REQ.REQUEST_NK ORDER BY 4 DESC LIMIT 20 


سوف تحتوي هذه القائمة على جميع المتصلين ، على سبيل المثال ، طلب إلى /wp-login.php. من خلال ضبط قواعد إعادة كتابة طلبات الخادم ، يمكنك ضبط استجابة الخادم لهذه الطلبات وإرسالها إلى صفحة البدء.

لذلك ، فإن بعض التقارير البسيطة التي تستند إلى ملف سجل الخادم تقدم صورة كاملة إلى حد ما لما يحدث على الموقع.

كيف تحصل على المعلومات؟


قاعدة بيانات sqlite كافية تماما. لنقم بإنشاء جداول: مساعدة لتسجيل عمليات ETL.

صورة

الجدول المرحلة ، حيث سنكتب ملفات السجل باستخدام PHP. اثنين من الجداول الإجمالية. إنشاء جدول يومي مع إحصاءات عن وكلاء المستخدم وحالات الطلب. كل ساعة مع إحصاءات عن الطلبات ومجموعات الحالة والوكلاء. أربعة جداول للقياسات ذات الصلة.

والنتيجة هي النموذج العلائقي التالي:

نموذج البيانات
صورة

البرنامج النصي لإنشاء كائن في قاعدة بيانات sqlite:

إنشاء كائن DDL
 DROP TABLE IF EXISTS DIM_USER_AGENT; CREATE TABLE DIM_USER_AGENT ( DIM_USER_AGENT_ID INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, USER_AGENT_NK TEXT NOT NULL DEFAULT 'na', AGENT_OS TEXT NOT NULL DEFAULT 'na', AGENT_ENGINE TEXT NOT NULL DEFAULT 'na', AGENT_DEVICE TEXT NOT NULL DEFAULT 'na', AGENT_BOT TEXT NOT NULL DEFAULT 'na', UPDATE_DT INTEGER NOT NULL DEFAULT 0, UNIQUE (USER_AGENT_NK) ); INSERT INTO DIM_USER_AGENT (DIM_USER_AGENT_ID) VALUES (-1); 

مرحلة


في حالة ملف access.log ، تحتاج إلى قراءة وتحليل وكتابة جميع الطلبات إلى قاعدة البيانات. يمكن القيام بذلك إما مباشرة باستخدام لغة البرمجة النصية أو باستخدام sqlite.

تنسيق ملف السجل:

 //67.221.59.195 - - [28/Dec/2012:01:47:47 +0100] "GET /files/default.css HTTP/1.1" 200 1512 "https://project.edu/" "Mozilla/4.0" //host ident auth time method request_nk protocol status bytes ref browser $log_pattern = '/^([^ ]+) ([^ ]+) ([^ ]+) (\[[^\]]+\]) "(.*) (.*) (.*)" ([0-9\-]+) ([0-9\-]+) "(.*)" "(.*)"$/'; 

الدعاية الرئيسية


عندما تكون البيانات الأولية في قاعدة البيانات ، تحتاج إلى تسجيل مفاتيح غير موجودة في جداول القياس. ثم سيكون من الممكن بناء إشارة إلى القياسات. على سبيل المثال ، في الجدول DIM_REFERRER ، المفتاح هو مزيج من ثلاثة حقول.

استعلام نشر مفتاح SQL
 /* Propagate the referrer from access log */ INSERT INTO DIM_REFERRER (HOST_NK, PATH_NK, QUERY_NK, UPDATE_DT) SELECT CLS.HOST_NK, CLS.PATH_NK, CLS.QUERY_NK, STRFTIME('%s','now') AS UPDATE_DT FROM ( SELECT DISTINCT REFERRER_HOST AS HOST_NK, REFERRER_PATH AS PATH_NK, CASE WHEN INSTR(REFERRER_QUERY,'&sid')>0 THEN SUBSTR(REFERRER_QUERY, 1, INSTR(REFERRER_QUERY,'&sid')-1) /*  sid -   */ ELSE REFERRER_QUERY END AS QUERY_NK FROM STG_ACCESS_LOG ) CLS LEFT OUTER JOIN DIM_REFERRER TRG ON (CLS.HOST_NK = TRG.HOST_NK AND CLS.PATH_NK = TRG.PATH_NK AND CLS.QUERY_NK = TRG.QUERY_NK) WHERE TRG.DIM_REFERRER_ID IS NULL 

قد يحتوي النشر إلى جدول وكيل المستخدم على منطق bot ، على سبيل المثال ، مقتطف sql:

 CASE WHEN INSTR(LOWER(CLS.BROWSER),'yandex.com')>0 THEN 'yandex' WHEN INSTR(LOWER(CLS.BROWSER),'googlebot')>0 THEN 'google' WHEN INSTR(LOWER(CLS.BROWSER),'bingbot')>0 THEN 'microsoft' WHEN INSTR(LOWER(CLS.BROWSER),'ahrefsbot')>0 THEN 'ahrefs' WHEN INSTR(LOWER(CLS.BROWSER),'mj12bot')>0 THEN 'majestic-12' WHEN INSTR(LOWER(CLS.BROWSER),'compatible')>0 OR INSTR(LOWER(CLS.BROWSER),'http')>0 OR INSTR(LOWER(CLS.BROWSER),'libwww')>0 OR INSTR(LOWER(CLS.BROWSER),'spider')>0 OR INSTR(LOWER(CLS.BROWSER),'java')>0 OR INSTR(LOWER(CLS.BROWSER),'python')>0 OR INSTR(LOWER(CLS.BROWSER),'robot')>0 OR INSTR(LOWER(CLS.BROWSER),'curl')>0 OR INSTR(LOWER(CLS.BROWSER),'wget')>0 THEN 'other' ELSE 'na' END AS AGENT_BOT 

الجداول وحدة


أخيرًا ، سنقوم بتحميل الجداول الإجمالية ، على سبيل المثال ، يمكن تحميل جدول يومي على النحو التالي:

مزود طلب تحميل الكلي
 /* Load fact from access log */ INSERT INTO FCT_ACCESS_USER_AGENT_DD (EVENT_DT, DIM_USER_AGENT_ID, DIM_HTTP_STATUS_ID, PAGE_CNT, FILE_CNT, REQUEST_CNT, LINE_CNT, IP_CNT, BYTES) WITH STG AS ( SELECT STRFTIME( '%s', SUBSTR(TIME_NK,9,4) || '-' || CASE SUBSTR(TIME_NK,5,3) WHEN 'Jan' THEN '01' WHEN 'Feb' THEN '02' WHEN 'Mar' THEN '03' WHEN 'Apr' THEN '04' WHEN 'May' THEN '05' WHEN 'Jun' THEN '06' WHEN 'Jul' THEN '07' WHEN 'Aug' THEN '08' WHEN 'Sep' THEN '09' WHEN 'Oct' THEN '10' WHEN 'Nov' THEN '11' ELSE '12' END || '-' || SUBSTR(TIME_NK,2,2) || ' 00:00:00' ) AS EVENT_DT, BROWSER AS USER_AGENT_NK, REQUEST_NK, IP_NR, STATUS, LINE_NK, BYTES FROM STG_ACCESS_LOG ) SELECT CAST(STG.EVENT_DT AS INTEGER) AS EVENT_DT, USG.DIM_USER_AGENT_ID, HST.DIM_HTTP_STATUS_ID, COUNT(DISTINCT (CASE WHEN INSTR(STG.REQUEST_NK,'.')=0 THEN STG.REQUEST_NK END) ) AS PAGE_CNT, COUNT(DISTINCT (CASE WHEN INSTR(STG.REQUEST_NK,'.')>0 THEN STG.REQUEST_NK END) ) AS FILE_CNT, COUNT(DISTINCT STG.REQUEST_NK) AS REQUEST_CNT, COUNT(DISTINCT STG.LINE_NK) AS LINE_CNT, COUNT(DISTINCT STG.IP_NR) AS IP_CNT, SUM(BYTES) AS BYTES FROM STG, DIM_HTTP_STATUS HST, DIM_USER_AGENT USG WHERE STG.STATUS = HST.STATUS_NK AND STG.USER_AGENT_NK = USG.USER_AGENT_NK AND CAST(STG.EVENT_DT AS INTEGER) > $param_epoch_from /* load epoch date */ AND CAST(STG.EVENT_DT AS INTEGER) < strftime('%s', date('now', 'start of day')) GROUP BY STG.EVENT_DT, HST.DIM_HTTP_STATUS_ID, USG.DIM_USER_AGENT_ID 

تسمح لك قاعدة بيانات sqlite بكتابة استعلامات معقدة. مع يحتوي على إعداد البيانات والمفاتيح. الاستعلام الرئيسي يجمع كل الإشارات إلى الأبعاد.

لن يسمح الشرط بتحميل المجموعة النصية مرة أخرى: CAST (STG.EVENT_DT AS INTEGER)> $ param_epoch_from ، حيث المعلمة هي نتيجة الطلب
"حدد التتابع (MAX (EVENT_DT) ، \ '3600 \') AS LAST_EVENT_EPOCH من FCT_ACCESS_USER_AGENT_DD"

سيتم تحميل الشرط فقط طوال اليوم: CAST (STG.EVENT_DT AS INTEGER) <وقت العمل ('٪ s' ، التاريخ ('الآن' ، 'بداية اليوم'))

يتم عد الصفحات أو الملفات بطريقة بدائية ، من خلال البحث عن نقطة.

تقارير


في أنظمة التصور المعقدة ، من الممكن إنشاء نموذج تعريف يستند إلى كائنات قاعدة البيانات وإدارة عوامل التصفية وقواعد التجميع ديناميكيًا. في النهاية ، تولد جميع الأدوات اللائقة استعلام SQL.

في هذا المثال ، سنقوم بإنشاء استعلامات SQL جاهزة وحفظها كطريقة عرض في قاعدة البيانات - هذه هي التقارير.

تصور


Bluff: تم استخدام الرسوم البيانية الجميلة في JavaScript كأداة للتصور.

لهذا ، كان من الضروري استخدام PHP لتجاوز جميع التقارير وإنشاء ملف html مع الجداول.

 $sqls = array( 'SELECT * FROM RPT_ACCESS_USER_VS_BOT', 'SELECT * FROM RPT_ACCESS_ANNOYING_BOT', 'SELECT * FROM RPT_ACCESS_TOP_HOUR_HIT', 'SELECT * FROM RPT_ACCESS_USER_ACTIVE', 'SELECT * FROM RPT_ACCESS_REQUEST_STATUS', 'SELECT * FROM RPT_ACCESS_TOP_REQUEST_PAGE', 'SELECT * FROM RPT_ACCESS_TOP_REQUEST_REFERRER', 'SELECT * FROM RPT_ACCESS_NEW_REQUEST', 'SELECT * FROM RPT_ACCESS_TOP_REQUEST_SUCCESS', 'SELECT * FROM RPT_ACCESS_TOP_REQUEST_ERROR' ); 

الأداة ببساطة تصور الجداول النتيجة.

استنتاج


باستخدام تحليل الويب كمثال ، تصف المقالة الآليات اللازمة لبناء مستودعات البيانات. كما يتضح من النتائج ، فإن أبسط الأدوات كافية للتحليل المتعمق وتصور البيانات.

في المستقبل ، باستخدام مثال وحدة التخزين هذه ، سنحاول تنفيذ هياكل مثل التغيير السريع للقياسات والبيانات الرئيسية ومستويات التجميع وتكامل البيانات من مصادر مختلفة.

أيضًا ، سنلقي نظرة فاحصة على أبسط أداة لإدارة عملية ETL استنادًا إلى جدول واحد.

دعنا نعود إلى موضوع قياس جودة البيانات وأتمتة هذه العملية.

سنقوم بدراسة مشاكل البيئة التقنية وصيانة مستودعات البيانات ، والتي نقوم بتنفيذ خادم تخزين به موارد قليلة ، على سبيل المثال ، استنادًا إلى Raspberry Pi.

Source: https://habr.com/ru/post/ar462337/


All Articles