В этом посте я
расскажу, как при помощи hive можно вытащить
что-нибудь ценное из логов апача. Если
слова hive или веб-аналитика вам ничего
не говорят, то рекомендую прочитать мой
предыдущий пост:
В качестве справочного материала рекомендую использовать книгу Tom White "Hadoop The DefinitiveGuide", или читать про hive в wiki на сайте apache
На большинстве серверов в качестве веб-сервера используется Apache, поэтому будем анализировать именно его логи.
Обычно лог апача выглядит как нибудь так:
Если вы увидите на экране что-то типа
Здесь команда CONCAT(A,B) склеивает 2 строчки в одну, а COUNT (DISTINCT C)— считает число таких разнообразных значений в таблице.
Теперь можно, для примера,
узнать число пользователей которые
побывали на сайте с айпада. Информация
об устройстве содержится в строке
user_agent и может быть извлечена командой
"A LIKE B", как вы уже догадались, это сравнение строки A с маской B.
HiveQL поддерживает написание таких функций
тобы не превращать hiveQL запрос в нечитабельного и медлительного монстра, его можно вынести в специальную UDF функцию (user defined function). UDF функции пишутся на java, потом инициализируются в hive как новые пользовательские функции, после чего их можно использовать наравне со встроенными.
Элементарный код функции разбора юзер агента можно скачать с github:
[TODO: вставить ссылку]
Собирается она при помощи ant'а, но в начале вам может потребоваться поправить build.xml, указав правильные пути до библиотек hadoop и hivе.
Когда код собран в jar, его сначала надо будет добавить в текущую сессию hive
Функция разбора юзерагента будет называтся get_os.
В качестве справочного материала рекомендую использовать книгу Tom White "Hadoop The DefinitiveGuide", или читать про hive в wiki на сайте apache
Лог апача
Итак, исходными данными, по которым мы можем посчитать полезные нам метрики являются логи веб-серверов, которые обрабатывают наши запросы.На большинстве серверов в качестве веб-сервера используется Apache, поэтому будем анализировать именно его логи.
Обычно лог апача выглядит как нибудь так:
155.54.41.193 - - [01/May/2012:00:42:31
+0400] "GET http://news.rambler.ru/73221.html HTTP 1.0" 200
3591 - "Mozilla/5.0 (Windows; I; Windows NT 5.1; ru;
rv:1.9.2.13) Gecko/20100101 Firefox/4.0"
через пробел в него
пишутся поля
- IP
- чтото неизвестное (всегда стоит прочерк)
- имя пользователя, (если пользователь авторизуется на сервере, что крайне редко)
- дата клика
- запрос, который был сделан к серверу
- код ответа
- длина ответа
- реферрер (предыдущая станица, на который был человек)
- юзер агент (описание устройства, с которого пользователь заходил на сайт)
Такие логи содержат в
себе крайне важную информацию о том,
как пользователи посещают ресурс. Кроме
этих полей Apache может писать в лог
и другую полезную информацию, например содержимое выданных пользователю кук.
Для дальнейших экспериметов логи apache можно сгенерировать специальным python скриптом, который я выложил на github.
В качестве параметров
скрипта можно задать число пользователей
ресурса, частоту их заходов, время начала и конца
генерации логов.
Ключ «-h» выдает подробный
хелп по утилите, а вызов скрипта без
агрументов геренирует логи за май 2012
года.
Итак, поехали считать статистику!
Для начала надо создать таблицу, через которую у hive будет доступ к полям лога. Разбирать лог на поля нам прийдется при помощи регулярных выражений. Логи разложены по папкам и сейчас мы создадим таблицу по логам за один день.CREATE EXTERNAL TABLE apache_logs ( -- это команда создать таблицу. EXTERNAL означает -- что данные в ней нужны где-то еще и их не надо -- удалять удалять при удалении таблицы ip STRING, human_time STRING, url STRING, response STRING, referrer STRING, user_agent STRING ) ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.RegexSerDe' -- serde это сокращение от "serialization-deserialization" - -- алгоритм, как разбирать данные по столбцам WITH SERDEPROPERTIES ( "input.regex" = "([\\d\\.]+) - - \\[(.*?)\\] \"GET (.+?) HTTP.*?\" (\\d+?) \\d+? (\\S+?) \"(.+?)\"") -- это то регулярное выражение, которым надо разбирать -- апачовый лог. Каждая скобка в нем - содержимое очередной колонки LOCATION '/home/mezentsev/src/hive_web_analytics/logs/2012-05-01' -- путь на диске до папки в которой хранятся логи ;Чтобы проверить, что все создалось хорошо, можно вызвать простейшую команду
SELECT * FROM apache_logs LIMIT 10;
Если вы увидите на экране что-то типа
220.232.156.191 01/May/2012:09:00:13 +0400 http://news.rambler.ru... 189.244.47.170 01/May/2012:09:00:40 +0400 http://news.rambler.ru... 207.173.21.42 01/May/2012:09:01:39 +0400 http://news.rambler.ru... 207.173.21.42 01/May/2012:09:01:42 +0400 http://news.rambler.ru... ...............
то все работает нормально.
Теперь посмотрим, что же
интересного мы можем узнать про наш
сайт. Такой же простой командой как и
предыдущая мы можем посчитать число
кликов на сайте
SELECT COUNT (1) FROM apache_logs;
(у меня получилось 4551 кликов, если у вас
другое число — это нормально, так как
скрипт генерит логи пользователей
случайным образом).
Про COUNT и другие функции
можно почитать в разделе функции и операторы на wiki hive.
Узнать число разных
пользователей на сайте не так просто.
Дело в том, что чаще всего IP у пользователей
интернета выдаются динамически и вполне
легко два случайных визитеров могли
бы зайти на сайт с одним IP. Номальное
решение этой проблемы - выдавать
посетителям сайта уникальные куки,
записывать их содержимое отдельным
полем в лог и дальше считать пользователей
по ним. Другой способ - можно считать
уникальной характеристикой пару IP +
useragent, однако в реальности пользователя
можно отслеживать по ней только в течении
одной сессии, может быть одного дня:
SELECT COUNT (DISTINCT CONCAT(ip,user_agent))
FROM apache_logs;
(у меня получилось 96 посетителей)
Здесь команда CONCAT(A,B) склеивает 2 строчки в одну, а COUNT (DISTINCT C)— считает число таких разнообразных значений в таблице.
SELECT COUNT (DISTINCT CONCAT(ip,user_agent))
FROM apache_logs
WHERE user_agent LIKE "%iPad%";
(32 человека)"A LIKE B", как вы уже догадались, это сравнение строки A с маской B.
Пользовательские функции
Разбор агента пользователя может быть более сложным и требовать выполнения нестандартных функций, написанных специально для задачи.HiveQL поддерживает написание таких функций
тобы не превращать hiveQL запрос в нечитабельного и медлительного монстра, его можно вынести в специальную UDF функцию (user defined function). UDF функции пишутся на java, потом инициализируются в hive как новые пользовательские функции, после чего их можно использовать наравне со встроенными.
Элементарный код функции разбора юзер агента можно скачать с github:
[TODO: вставить ссылку]
Собирается она при помощи ant'а, но в начале вам может потребоваться поправить build.xml, указав правильные пути до библиотек hadoop и hivе.
Когда код собран в jar, его сначала надо будет добавить в текущую сессию hive
ADD JAR /home/mezentsev/..../get_os_from_user_agent.jar
-- здесь должен быть полный путь до jar файла с UDF функцией
;
CREATE TEMPORARY FUNCTION get_os AS 'GetOsFromUserAgent';
Функция разбора юзерагента будет называтся get_os.
Теперь можно увидеть,
из под каких операционных систем к нам
заходили люди
SELECT get_os (user_agent) FROM
apache_logs LIMIT 10;
И даже посчитать, сколько
человек под какой операционкой сидело:
SELECT get_os (user_agent) AS
os,
COUNT (DISTINCT CONCAT (ip,user_agent))
FROM apache_logs
GROUP BY GET_OS (user_agent);
COUNT (DISTINCT CONCAT (ip,user_agent))
FROM apache_logs
GROUP BY GET_OS (user_agent);
Комментариев нет:
Отправить комментарий