Webalizeri utiliit ja Google Analytics tööriist on aidanud mul aastaid saada ĂŒlevaadet sellest, mis minu veebilehtedel toimub. NĂŒĂŒd mĂ”istan, et nad pakuvad vĂ€ga vĂ€he kasulikku teavet. LigipÀÀs oma access.log failile muudab statistika analĂŒĂŒsimise ÀÀrmiselt lihtsaks ning selleks piisab elementaarsetest tööriistadest, nagu sqlite, html, sql ja mĂ”ni skriptimiskeele.
Webalizeri andmeallikaks on access.log fail. serverileNii nĂ€evad vĂ€lja selle veerud ja numbrid, millest on selge vaid ĂŒldine liiklusmaht:


Sellised tööriistad nagu Google Analytics koguvad andmeid lehe laadimise ajal iseseisvalt. Need kuvavad meile paar diagrammi ja joont, mille pÔhjal on sageli raske Ôigeid jÀreldusi teha. VÔib-olla oleks pidanud rohkem vaeva nÀgema? Ei tea.
Nii et mida ma tahaksin nÀha oma veebisaidi kÀivituste statistikas?
KĂŒlastajate ja robotite liiklus.
Sageli on veebisaitide liiklus piiratud ja on oluline nÀha, kui palju kasulikku liiklust kasutatakse. NÀiteks nii:

SQL aruande pÀring.
VALI
1 as 'Stakitud ala: Kasutajate ja robotite genereeritud liiklus',
strftime('%d.%m', datetime(FCT.EVENT_DT, 'unixepoch')) AS 'PĂ€ev',
SUM(CASE WHEN USG.AGENT_BOT!='n.a.' THEN FCT.BYTES ELSE 0 END)/1000 AS 'Robotid, KB',
SUM(CASE WHEN USG.AGENT_BOT='n.a.' THEN FCT.BYTES ELSE 0 END)/1000 AS 'Kasutajad, 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_DTGraafikult on nĂ€ha pidev robotite aktiivsus. Oleks huvitav ĂŒksikasjalikult uurida aktiivseimaid esindajaid.
TĂŒĂŒtud robotid
Klassifitseerime roboteid kasutajaagendi teabe pĂ”hjal. TĂ€iendavad statistikat pĂ€evase liikluse, eduka ja ebaĂ”nnestunud pĂ€ringute arvu kohta annavad hea ĂŒlevaate robotite aktiivsusest.

SQL aruande pÀring.
VALI
1 KUIDAS 'Tabel: TĂŒĂŒtud robotid',
MAX(USG.AGENT_BOT) AS 'Robot',
ROUND(SUM(FCT.BYTES) / 1000 / 14.0, 1) AS 'KB pÀevas',
ROUND(SUM(FCT.IP_CNT) / 14.0, 1) AS 'IPs pÀevas',
ROUND(SUM(CASE WHEN STS.STATUS_GROUP IN ('Kliendi viga', 'Serveri viga') THEN FCT.REQUEST_CNT / 14.0 ELSE 0 END), 1) AS 'Vigased pÀringud pÀevas',
ROUND(SUM(CASE WHEN STS.STATUS_GROUP IN ('Edukas', 'Ămbersuunamine') THEN FCT.REQUEST_CNT / 14.0 ELSE 0 END), 1) AS 'Edu pĂ€ringud pĂ€evas',
USG.USER_AGENT_NK AS 'Agend'
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 pÀeva')
GROUP BY USG.USER_AGENT_NK
ORDER BY 3 DESC
LIMIT 10Antud juhul oli analĂŒĂŒsi tulemus otsus piirata juurdepÀÀsu veebisaidile, lisades faili robots.txt
Kasutaja-agendi: AhrefsBot
Keela: /
Kasutaja-agendi: dotbot
Keela: /
Kasutaja-agendi: bingbot
Kraapimise viivitus: 5
Esimesed kaks robotit kadusid tabelist ja MS robotid liikusid esimestelt ridadelt allapoole.
KÔige suurema aktiivsuse pÀev ja kellaaeg
Trafikus on nÀhtavad tÔusud. Nende pÔhjalikuks uurimiseks on vajalik vÀlja tuua nende esinemise aeg, samas ei ole kohustuslik kÔiki tunde ja pÀevi mÔÔtmise ajast kuvada. Nii on lihtsam vajadusel logifailis konkreetseid pÀringuid otsida.

SQL aruande pÀring.
VALI
1 KUI 'Rida: Kasutajate ja robotite loendamise pÀev ja kellaaeg',
strftime('%d.%m-%H', datetime(EVENT_DT, 'unixepoch')) AS 'KuupÀev ja kellaaeg',
HIB AS 'Robotid, kĂŒlastused',
HIU AS 'Kasutajad, kĂŒlastused'
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_DTJÀlgime kÔige aktiivsemaid tunde 11, 14 ja 20 esimesel pÀeval graafikul. JÀrgmisel pÀeval oli 13. tunni jooksul aktiivsust palju robotitel.
Kasutajate keskmine pÀevane aktiivsus nÀdalate kaupa
Oleme aktiivsuse ja liikluse osas veidi selgusele jĂ”udnud. JĂ€rgmine kĂŒsimus puudutab kasutajate aktiivsust. Sellise statistika puhul on soovitatavad pikemad aggregatsiooni perioodid, nĂ€iteks nĂ€dal.

SQL aruande pÀring.
VALI
1 KUI 'Rida: Keskmine pÀevane kasutajate aktiivsus nÀdalate kaupa',
strftime('%W week', datetime(FCT.EVENT_DT, 'unixepoch')) AS 'NĂ€dal',
ROUND(1.0*SUM(FCT.PAGE_CNT)/SUM(FCT.IP_CNT),1) AS 'LehekĂŒljed IP kohta pĂ€evas',
ROUND(1.0*SUM(FCT.FILE_CNT)/SUM(FCT.IP_CNT),1) AS 'Failid IP kohta pÀevas'
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.' /* ainult kasutajad */
AND HST.STATUS_GROUP IN ('Successful') /* head lehed */
AND datetime(FCT.EVENT_DT, 'unixepoch') > date('now', '-3 month')
GROUP BY strftime('%W week', datetime(FCT.EVENT_DT, 'unixepoch'))
ORDER BY FCT.EVENT_DTNĂ€dalast statistikat vaadates avab keskmine kasutaja pĂ€evas 1,6 lehte. Ăhe kasutaja kaupa nĂ”utavate failide arv sĂ”ltub antud juhul uute failide lisamisest saidile.
KÔik pÀringud ja nende seisundid
Webalizer on alati nÀidanud konkreetseid lehekoodide numbreid ja alati on soovitud lihtsalt nÀha edukate pÀringute ja vigade arvu.

SQL aruande pÀring.
SELECT
1 as 'Rida: KÔik pÀringud oleku jÀrgi',
strftime('%d.%m', datetime(FCT.EVENT_DT, 'unixepoch')) AS 'PĂ€ev',
SUM(CASE WHEN STS.STATUS_GROUP='Successful' THEN FCT.REQUEST_CNT ELSE 0 END) AS 'Edukad',
SUM(CASE WHEN STS.STATUS_GROUP='Redirection' THEN FCT.REQUEST_CNT ELSE 0 END) AS 'Suunamine',
SUM(CASE WHEN STS.STATUS_GROUP='Client Error' THEN FCT.REQUEST_CNT ELSE 0 END) AS 'Kliendi viga',
SUM(CASE WHEN STS.STATUS_GROUP='Server Error' THEN FCT.REQUEST_CNT ELSE 0 END) AS 'Serveri viga'
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_DTAruanne kajastab pĂ€ringuid, mitte klikke (hits), erinevalt LINE_CNT mÔÔdust, mida REQUEST_CNT loetakse kui COUNT(DISTINCT STG.REQUEST_NK). EesmĂ€rk on nĂ€idata efektiivseid sĂŒndmusi, nĂ€iteks kĂŒsivad MS robotid sada korda pĂ€evas faili robots.txt ja sellisel juhul loetakse sellised kĂŒsitlused ĂŒhe korra. See aitab siluda graafiku hĂŒppeid.
Graafikust on nĂ€ha palju vigu â need on mitteeksisteerivad lehed. AnalĂŒĂŒsi tulemuseks oli suunamiste lisamine eemaldatud lehtedelt.
Vigased pÀringud
PÀringute detailsemaks uurimiseks saab kuvada pÔhjalikku statistikat.

SQL aruande pÀring.
SELECT
1 AS 'Tabel: Suurimad Vigased PĂ€ringud',
REQ.REQUEST_NK AS 'PĂ€ring',
'Viga' AS 'PĂ€ringu Staatus',
ROUND(SUM(FCT.LINE_CNT) / 14.0, 1) AS 'Löögid pÀevas',
ROUND(SUM(FCT.IP_CNT) / 14.0, 1) AS 'IP-d pÀevas',
ROUND(SUM(FCT.BYTES)/1000 / 14.0, 1) AS 'KB pÀevas'
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 ('Kliendi Viga', 'Serveri Viga')
AND datetime(FCT.EVENT_DT, 'unixepoch') >= date('now', '-14 day')
GROUP BY REQ.REQUEST_NK
ORDER BY 4 DESC
LIMIT 20Selles nimekirjas on ka kĂ”ik katsetused, nĂ€iteks pĂ€ring /wp-login.php, mille kaudu saab korrigeerida pĂ€ringute ĂŒmberkirjutamise reegleid. serveriga Saab korrigeerida serveri reaktsiooni sellistele pĂ€ringutele ja suunata need algsesse lehte.
Nii et mĂ”ned lihtsad aruanded serveri logifaili pĂ”hjal annavad piisavalt tĂ€ieliku ĂŒlevaate sellest, mis veebisaidil toimub.
Kuidas saada teavet?
SQLite andmebaasid on tÀiesti piisavad. Loome tabelid: abiteenuse ETL-protsesside logimiseks.

Etapi tabel, kuhu kirjutame logifailid PHP abil. Kaks tabelit kogujatest. Loome pĂ€evase tabeli statistika jaoks kasutajagentide ja pĂ€ringute staatuste kohta. Tunnistiku tabel statistika jaoks pĂ€ringute, staatuste rĂŒhmade ja agentide kohta. Neli vastava mÔÔtmise tabelit.
Tulemuseks sai jÀrgmine relatsiooniline mudel:
Andmemudel
Skript objekti loomiseks sqlite andmebaasis:
DDL objekti loomine
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);Etapp
Access.log faili korral on vajalik lugeda, analĂŒĂŒsida ja kirjutada andmebaasi kĂ”ik pĂ€ringud. Seda saab teha kas otse skriptikeele vahenditega vĂ”i kasutades sqlite vahendeid.
Logifaili formaat:
//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-]+) "(.*)" "(.*)"$/';
Aste vÔtmete levik
Kui toorandmed on andmebaasis, tuleb kirjutada mÔÔtmetabelitesse vÔtmed, mida seal ei ole. See vÔimaldab linkide loomist mÔÔtmetele. NÀiteks DIM_REFERRER tabelis on vÔtme kombinatsioon kolmest vÀljast.
VÔtmete propagatsiooni SQL pÀring
/* 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 NULLKasutajaliideste tabelisse propagatsioon vÔib sisaldada robotite loogikat, nÀiteks SQL lÔik:
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_BOTAgnemid tabelid
LÔpuks laadime agnemid tabelid, nÀiteks pÀevakava tabel vÔib laadida jÀrgmiselt:
Agnemi laadimise SQL pÀring
/* 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_IDSQLite andmebaas vÔimaldab kirjutada keerukaid pÀringuid. WITH sisaldab andmete ja vÔtmete ettevalmistamist. Peamine pÀring kogub kÔik lingid mÔÔtmete juurde.
Tingimus ei luba ajalugu uuesti laadida: CAST(STG.EVENT_DT AS INTEGER) > $param_epoch_from, kus parametriks on pÀringu tulemus
âSELECT COALESCE(MAX(EVENT_DT), â3600â) AS LAST_EVENT_EPOCH FROM FCT_ACCESS_USER_AGENT_DDâ
Tingimus laadib ainult tĂ€ispĂ€eva: CAST(STG.EVENT_DT AS INTEGER) < strftime(â%sâ, date(ânowâ, âstart of dayâ))
LehekĂŒlgede vĂ”i failide loendamine toimub primitiivsel viisil, otsides punkti.
Aruanded
Kompaktsetes visualiseerimissĂŒsteemides on vĂ”imalus luua meta-mudel andmebaasi objektide pĂ”hjal, hallata dĂŒnaamiliselt filtreid ja koosseisureegleid. LĂ”ppkokkuvĂ”ttes genereerivad kĂ”ik korralikud tööriistad SQL-pĂ€ringut.
Selles nĂ€ites loome juba valmis SQL pĂ€ringud ja salvestame need vaade kujul andmebaasi â need ongi aruanded.
Visualiseerimine
Visualiseerimise tööriistana kasutati Bluff: Beautiful graphs in JavaScript
Selleks oli vajalik PHP abil kÔigist aruannetest lÀbi kÀia ja genereerida html-fail lauadega.
$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'
);Tööriist visualiseerib lihtsalt tulemuste tabeleid.
KokkuvÔte
VeebianalĂŒĂŒsi nĂ€ite pĂ”hjal kirjeldab artikkel andmehoidlate ehitamiseks vajalikke mehhanisme. Nagu nĂ€ha tulemustest, on sĂŒgav analĂŒĂŒs ja andmete visualiseerimine vĂ”imalik isegi kĂ”ige lihtsamate tööriistadega.
Edasi minnes ĂŒritame selle andmehoidla nĂ€itel rakendada selliseid struktuure nagu aeglaselt muutuvaid mÔÔtmeid, metaandmeid, kogumistasemeid ning andmete integreerimist erinevatest allikatest.
KĂ€sitleme ka lihtsaimat ETL protsesside haldamise tööriista, mis pĂ”hineb ĂŒhel tabelil.
Naaseme andquality mÔÔtmise ja selle protsessi automatiseerimise teema juurde.
Uurime andmehoidlate tehnilise keskkonna ja hoolduse probleeme, milleks loome minimaalsete ressurssidega andmehoidla serveri, nÀiteks Raspberry Pi baasil.
Allikas: habr.com
