إحصائيات الموقع ومساحة التخزين الصغيرة الخاصة بك

لقد ساعدني برنامج 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!='n.a.' THEN FCT.BYTES ELSE 0 END)/1000 AS 'Bots, KB',
SUM(CASE WHEN USG.AGENT_BOT='n.a.' 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 != 'n.a.'
  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!='n.a.' THEN LINE_CNT ELSE 0 END) AS HIB,
	SUM(CASE WHEN AGENT_BOT='n.a.' 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:XNUMX، كانت الروبوتات نشطة.

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

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

إحصائيات الموقع ومساحة التخزين الصغيرة الخاصة بك

استعلام تقرير 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='n.a.' /* 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 'n.a.',
  AGENT_OS          TEXT NOT NULL DEFAULT 'n.a.',
  AGENT_ENGINE      TEXT NOT NULL DEFAULT 'n.a.',
  AGENT_DEVICE      TEXT NOT NULL DEFAULT 'n.a.',
  AGENT_BOT         TEXT NOT NULL DEFAULT 'n.a.',
  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

قد يحتوي النشر إلى جدول وكيل المستخدم على منطق الروبوت، على سبيل المثال مقتطف 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 'n.a.' END AS AGENT_BOT

الجداول المجمعة

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

استعلام SQL لتحميل التجميع

/* 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، حيث تكون المعلمة هي نتيجة الطلب
'SELECT COALESCE(MAX(EVENT_DT), '3600') AS LAST_EVENT_EPOCH FROM FCT_ACCESS_USER_AGENT_DD'

سيتم تحميل الشرط لليوم الكامل فقط: CAST(STG.EVENT_DT AS INTEGER) < strftime('%s', date('now', 'start of day'))

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

تقارير

في أنظمة التصور المعقدة، من الممكن إنشاء نموذج تعريفي يعتمد على كائنات قاعدة البيانات، وإدارة المرشحات وقواعد التجميع ديناميكيًا. في نهاية المطاف، جميع الأدوات اللائقة تولد استعلام 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.

المصدر: www.habr.com

إضافة تعليق