Сегодня в рамках рубрики "Делимся опытом" мы представляем вашему вниманию небольшую заметку Дмитрия Берга, в которой он рассказывает о визуализации данных из лог-файлов средствами сервиса plot.ly.
Автор: Дмитрий Берг
Анализ логов веб-сайтов и других похожих систем - распространенная задача. В Linux это можно сделать из консоли терминала буквально одной строчкой кода, но возвращаемый при этом массив данных только в текстовом формате не позволяет сформировать полную картину о том, что происходит на сервере. Наглядная визуализация данных гораздо лучше помогла бы увидеть динамику изменений на сайте. В этой статье приводятся примеры подобной визуализации.
Прежде чем продолжить, сделаю несколько комментариев:
- Для визуализациии я использую сервис plot.ly, и вся полученная инфографика будет экспортироваться на их платформу. Безусловно, существуют альтернативные варианты размещения и сохранения созданных графиков, но, как мне кажется, этот сервис и соответствующий R-интерфейс к нему (plotly) особенно удобны.
- Для подготовки данных я применяю пакет data.table.
- Спецификация моей системы: R - версия 3.3.2 (2016-10-31) - "Sincere Pumpkin Patch", RStudio - версия 1.0.136, ОС - Fеdora x86_64.
1. В качестве первого шага подключаем необходимые пакеты:
library("plotly") library("devtools") library("data.table") library("RCurl") library("XML")
2. Данные для воспроизведения рассматриваемого примера можно скачать по следующей ссылке: https://yadi.sk/d/TCGocq0K3ECZfH. В общем же случае, когда сервер сайта имеет адрес формата "ftp://server/hosting/", для скачивания логов можно выполнить примерно следующие команды:
url <- 'ftp://server/hosting/' # Через ftp подключаемся к серверу сайта userpwd <- "Логин:Пароль" # Вводим логин и пароль filenames <- getURL(url, userpwd = userpwd, ftp.use.epsv = TRUE, dirlistonly = TRUE) # Отправляем запрос на наличие файлов filenames # Просматриваем список найденных файлов
Далее необходимо скачать обнаруженные лог-файлы с расширением .log. Из терминала Linux или OSX это можно сделать с помощью следующих команд:
curl -u логиг:пароль -O ftp://server/hosting/access_file1.log curl -u логиг:пароль -O ftp://server/hosting/access_file2.log
3. Переходим к обработке данных. Как видите, моя стратегия заключается в том, чтобы сначала обработать каждую таблицу по отдельности, и только на заключительном этапе обьединить их в одну большую таблицу. Эта стратегия вызвана тем, что дальше при желании можно построить отдельные графики для каждой таблицы.
Сохраняем данные в таблицы:
f1 <- read.table("access.file1.log") f2 <- read.table("access.file2.log")
При необходимости, удаляем пустые столбцы (в моем случае оказалось два столбца):
В некоторых столбцах пришлось изменить формат:
Обьединяем таблицы в одну общую:
Переименуем названия столбцов на более осмысленные:
Просмотрим структуру таблицы:
На этом подготовка данных завершена. Переходим к их визуализации.
4. Создадим два графика одновременно. На левом графике мы увидим, с каких IP адресов было выполнено обращение к тем или иным внутренним ресурсам, а на правом - распределение объема данных (в байтах), переданных клиентам/посетителям сайта.
Отправляем график в свой профиль на сервисе plot.ly (вводить логин и пароль достаточно только один раз - для этого задаются соответствующие глобальные системные переменные с помощью команды Sys.setenv()):
Полученная интерактивная диаграмма выглядит следующим образом (см. также здесь):
Теперь создадим 3D график, который покажет нам, какие клиенты (посетители сайта) c уникальным IP адресом получили ответ от сервера, и каков был объем переданных данных:
Отправляем график на платформу plot.ly:
Результат выглядит так (см. также здесь):
Скачать файл с полным кодом для воспроизведения приведенных выше примеров можно из моего GitHub-репозитория.
f1$V3 <- NULL f1$V4 <- NULL
В некоторых столбцах пришлось изменить формат:
f1$V5 <- as.POSIXct(strptime("2017-01-27", "%Y-%m-%d")) f2$V5 <- as.POSIXct(strptime("2017-01-26", "%Y-%m-%d")) f1$V8 <- as.numeric(df$V8) f1$V2 <- as.character.numeric_version(df$V2)
Обьединяем таблицы в одну общую:
df <- merge(f1,f2, all = TRUE)
Переименуем названия столбцов на более осмысленные:
colnames(df) <- c('host', 'ip', 'date', 'method', 'bit', 'referer', 'useragent')
Просмотрим структуру таблицы:
str(df)
На этом подготовка данных завершена. Переходим к их визуализации.
4. Создадим два графика одновременно. На левом графике мы увидим, с каких IP адресов было выполнено обращение к тем или иным внутренним ресурсам, а на правом - распределение объема данных (в байтах), переданных клиентам/посетителям сайта.
p1 <- plot_ly(x = ~df$ip, y = ~df$referer) %>% add_markers(name = "refer/ip") p2 <- plot_ly(x = ~df$useragent, y = ~df$bit) %>% add_markers(name = ~"useragent/bit") p3 <- subplot(p1, p2)
Отправляем график в свой профиль на сервисе plot.ly (вводить логин и пароль достаточно только один раз - для этого задаются соответствующие глобальные системные переменные с помощью команды Sys.setenv()):
Sys.setenv("plotly_username" = "Логин") # Вводим логин (имя) plot.ly Sys.setenv("plotly_api_key" = "API KEY") # Вводим ключ API plot.ly plotly_POST(p3,
filename = "ip-refer-useragent-bit") # Отправляем в личный профиль на plot.ly
Полученная интерактивная диаграмма выглядит следующим образом (см. также здесь):
Теперь создадим 3D график, который покажет нам, какие клиенты (посетители сайта) c уникальным IP адресом получили ответ от сервера, и каков был объем переданных данных:
p <- plot_ly(df, x = ~ip, y = ~useragent, z = ~bit, marker = list(color = ~bit, colorscale = c('#ffc2c6', '#480607'), size = 3, showscale = TRUE)) %>% add_markers() %>% layout(scene = list(xaxis = list(title = 'IP'), yaxis = list(title = 'User Agent'), zaxis = list(title = 'Bite')), annotations = list( x = 1.13, y = 1.05, text = 'Bite', xref = 'paper', yref = 'paper', showarrow = FALSE ))
Отправляем график на платформу plot.ly:
plotly_POST(p, filename = "ip-useragent-bit")
Результат выглядит так (см. также здесь):
Скачать файл с полным кодом для воспроизведения приведенных выше примеров можно из моего GitHub-репозитория.
Если хочется рисовать похожую красоту, но чтобы корпоративные данные ни-ни, получится использовать?
Отправить комментарий