Как стать автором
Обновить

Комментарии 40

Для построения графиков советую еще посмотреть на — highcharts.com гибкая и удобная штука, без флеша
Красивая штука, очень. Но сложнее в использовании, чем jquery.visualize.

Лично мне очень нравится, что оно работает прямо из таблицы, данные специально готовить не нужно.

В общем то, пост скорее про логирование посещений в modx, а построение графика — это пример вывода. Тут каждый может себе еще что-то придумать.
А почему вы используете datetime вместо timestamp?
$modx->db->query(«INSERT INTO $db (`login`, `ip`, `host`, `url`, `referer`,`browser`)
VALUES ('$login','$ip','$host', '$url','$referer','$browser')»);
попахивает sql injection
Это столбец называется `datetime`, а внутри — timestamp, смотрите запрос sql
`datetime` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,

Вот такой я загадочный, да.

Про инъекцию не понял, уточните. Все данные берутся из массива $_SERVER, как туда что-то инъектировать?
Я не мега эксперт по безопасности, поэтому, если есть возможность такой атаки — проясните, плиз, я доработаю функцию.
_SERVER['HTTP_USER_AGENT'], по-вашему, откуда берется? Аккурат из HTTP-запроса, который посылал пользователь. И он там в принципе может прислать что угодно — произвольную строку байтов, всё, кроме CR/LF.
Я его не использую. В комментарии же написано:
$browser = $_SERVER['HTTP_USER_AGENT']; // Браузер юзера. Я использую класс browscap, а вы как хотите. Для примера сойдет и так.

У меня информация о браузере берется вот таким образом:
    $br = new Browscap('/tmp');
    $browserInfo = @$browser->getBrowser();
    $browser = $browserInfo->Parent.' / '.$browserInfo->Platform;

Ну а реферер?
А реферер да, согласен. Возможность имеется.

Нужно, пожалуй, использовать urlencode().
Зато _SERVER['HTTP_REFERER'] используете в прямом виде. А его пользователь точно так же может послать совершенно произвольный. В частности, никаких проблем отослать там ' (0x27) нет.
Добавлю, что очень похожим образом подключается к ModX скрипт статистики slimstat.net/

В обоих случаях хорошо бы придумать систему архивирования логов с разбивкой по месяцам хотя бы, потому как при средней посещаемости, скажем, 300 хостов\сутки и ~10 просмотров на хост, через год работы таблица раздувается до неудобных размеров и начинает тормозить, во всяком случае на обычном хостинге.
Я просто чищу кроном старые записи. Когда делал складывание squid`ом логов — делал по месяцам. Но там реально, очень много записей было.
Зачем используете varchar для хранения адреса? С ним работать неудобно — если будете подключать другие таблицы (геолокейшн, например) — всплывет проблема конвертирования адреса
Эм… не думал об этом.

Если потребуется, можно разбить ip при выборке: $arr = explode('.', $ip);

Или и вовсе прогнать изменить структуру БД и забить туда старые ip заново простым скриптом за несколько минут.

Правда, пока ни разу не требовалось.
ip2long() и дело в шляпе.
зачем всё это? google analitics не устраивает?
Может пригодиться для интранет сервисов
поддерживаю, как раз нужно было для интранет проекта. Теперь и писать не нужно.
Ну, я же в самом начале сказал, что хочтелось сделать свою статистику.

Гугл — это прекрасно, но надо же иногда и без него обходиться?
«Посетителями» вы, насколько я понимаю, называете уникальные IP?
Да. Все оформление задается в двух чанках — можете переименовать, как вам больше нравится.
Просто есть некие соглашения и определения, с которыми большинство согласилось раз и навсегда — когда вы начинаете использовать слова не по назначению (примерно сродни тому, как девочки-из-бухгалтерии с важным видом называют системный блок «процессором») — вас в худшем случае могут понять неправильно, в лучшем — догадаются и поймут, но впечатление уже будет подпорчено.

В случае веб-аналитики определенным «законодателем» определений и понятия является WAA. Термин «посетители» они определяют хоть и не очень четко, но всё-таки не как «только IP».
Окей, не спорю.

Вы как часто работодателю читаете лекции и объясняете, чем отличается «уникальный ip» от «посетителя», а также «запрос страницы» от «просмотра»?

Просто любопытно.
Не работодателю, скорее, а клиентам. Я лично крайне редко, а вот поддержка — по несколько десятков раз в день отвечает на подобные вопросы.
Ну вот. Небольшая сделка с собственной грамотностью может избавить от таких заморочек.
Вступление напомнило: «Я мать-одиночка и поэтому банкам не доверяю...»
эм, почему не допилить уже существующую систему регистрации посещений?

ЗЫ ее, кстати, всегда советуют отключать, сразу… ибо нагрузка на бд
А ее нету.
Она была в Etomite, а в ModX Evolution 1.0.4 есть только тырчик в настройках, который Предоставляет данные для плагина аналитики, например, флажок, определяющий, учитывать ли просмотры конкретного ресурса.

Видимо, это и есть работа события OnLogPageHit, которое использует плагин.
А самого плагина я не нашел.
Скажу честно, не сильно-то и искал, но все же.
Подход, при котором программист все нужные шишки хочет набить самостоятельно, достоин уважения (лишь бы заказчикам такой код не отправлял).
Основные проблемы вам уже указали:
1. Разрастание таблицы с логом
2. Нагрузка на сервер при росте посещаемости будет расти нелинейно
3. Излишнее доверие к пользовательским данным может выйти боком
4. Вы считаете хосты, а не посетителей

Направление движения пока что могут быть таковы:
1. Партишенинг таблицы по дате (почитайте, например, здесь)
2. Буфер для инсертов (лучше сразу в мемкеше, но на первое время сгодится и файл)
3. Плейсхолдеры или mysql_real_escape_string должны стать привычкой
4. Куки с уникальными айди

… ну а там и решение использовать зарекомендовавшие себя сервисы типа Google Analytics не за горами.
Спасибо за советы, почитаю на досуге.

Пока могу только сказать, что моим требованиям данный плагин соответствует полностью.
В начале топика вроде не было заяв, что мой способ — лучший, так? Ну и на нем хорошо видно, как можно использовать плагины в modx, что тоже плюс.

Не зря же топик в блоге modx.

Согласен. Если график сверху — реальный, то нет смысла серьезно усложнять систему. Сделайте экранирование запросов и обдумайте, стоит ли сделать партиционирование (чтобы не приходилось этот лог чистить, как вы описывали в комментарии выше). Остальное — так, на будущее.
График реальный. Сайт переживает хаброэффект )

С ноября в базе ~20000 записей, весят 3,5мб. Нагрузка совсем небольшая, при моих посещениях.
Сайт служит в основном полигоном для обработки навыков + домашняя страничка себе и друзьям.

Но на будущее я сегодня многое узнал, особенно от вас, спасибо!

wiki.modxcms.com/index.php/API:getUserData

Вместо вашего $_SERVER[] можно кой-что взять оттуда, так «правильнее»
Очень радует MODx на главной
Кстати да, забыл про эту полезную функцию. Спасибо за подсказку!

Ip, браузер и ОС можно брать оттуда, надо только посмотреть что будет выдавать.

Потому что, например, при авторизации через weblogin юзеру в сессию пишется браузер и ip, а без авторизации — нет. Надо посмотреть, всегда ли getUserData корректно данные выдает, может, тоже от чего зависит.

Ну и опять же, если брать из $_SERVER — будет полюбому быстрее.
Да, видимо под новый год модераторы все отдыхают, раз такой быдлокод пропускают в мой RSS ридер.

> $referer = urlencode($_SERVER['HTTP_REFERER']);
> $host = `nslookup "$ip" | grep 'name =' | awk '{print $4}'`;
> 10 2 * * * * user wget localhost/secret_page.html (крон завалит вас почтой)
> $login = $_SESSION['webShortname']; (лог ошибок растет со скоростью 1 Мб в день)
> $date2 .= ''.strftime($dateFormat, strtotime($v)).''; (ага, шаблоны не нужны)

Еще заметил, что в ModX видимо до сих пор принято вставлять переменные прямиком в SQL запросы. Ребята, этот код — пример, как делать *не надо*. Даже не думайте им пользоваться. Мне даже сказать больше нечего. Ну и INSERT делать на каждого визитора, это конечно, сильно.
Простите что вклиниваюсь, читал тут перед сном размеренно комментарии к статьям но споткнулся об это:
> Ну и INSERT делать на каждого визитора, это конечно, сильно
Ммм, я не понял что вы имеете в виду. Предлагаете сначала писать посещения в файл например а потом кумулятивно по крону делать обновление в БД? Или как, мне правда интересно, я не хитрю =)
1) В примере топикстартера проще всего по крону парсить логи веб-сервера — он сам туда сложит все, что надо, правда имени залогиненного юзера там не будет.
2) Да, можно в какой-нибудь кеш сваливать (что диск-то напрягать зря) данные, а потом по крону пачками их вынимать, группировать и вставлять 1 транзакцией.
3) Можно поставить внешнюю статистику.

Конечно, при 30000 запросов в день инсерт БД не сломает, но все равно, это решение плохое, для применения на более-менее средних серверах.
1. Можно. Но мне приятно видеть все в реальном времени, а не обновления раз в час.
2. Ну я даже не знаю, зачем жалеть HDD виртуального хостинга. Да и вообще, при генерации страницы делается куча разных запросов, одним больше, одним меньше — кому какая разница?
3. Можно. Liveinternet хотя бы есть. Цифры от моих отличаются. Опять же, имя юзера оно не соберет.

Вы думаете, у всех пользователей modx больше 30к посещений в день? К сожалению — нифига.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории