Думаю, многим интересно (хотя бы из любопытства), как именно они используют свой компьютер: самые нажимаемые кнопки, пройденное мышью расстояние, среднее время работы и другую информацию. В этой статье я расскажу один из вариантов того, как можно собрать такую информацию и затем представить её в виде интерактивных графиков. Все описанные действия производились на ноутбуке с ОС Debian Wheezy
, Python 2.7.3
, R 2.15
.
Сбор данных
Всё началось с того, что этой осенью мне захотелось иметь как можно более полную статистику о моём использовании компьютера. Сказано — сделано: написал простейший кейлоггер, записывающий все нажатия и отпускания клавиш на клавиатуре, кнопок на мыши, а также все перемещения мыши. Также в голову пришла идея делать фото вебкамерой через некоторый промежуток времени, что также было реализовано.
Изначально все данные писались просто в текстовый файл, но потом решил всё-таки сделать «по хорошему» и перевёл запись всех событий в базу SQLite
. Несмотря на то, что размер её по сравнению с сжатым gzip'ом текстовым файлов больше в несколько раз (сейчас база занимает немногим больше 0.5 Гб), это всё равно относительно немного, а делать выборки из базы всё-таки удобнее. Фото с камеры по-прежнему хранятся отдельно и их общий размер сейчас составляет 2.2 Гб (около 30000 файлов).
Представление информации
Итак, с записью данных всё вроде бы решено, осталось всё это представить в виде удобных графиков и таблиц. Так как я уже достаточно давно собирался изучить язык R
, но всё как-то не было повода начать, то решил его здесь и использовать. В общем-то после других языков начать пользоваться R
было достаточно несложно, хотя некоторые непривычные вещи всё-таки есть: например большинство стандартных операторов и функций векторизированы, принят стиль именования с разделением слов точкой (вместо _ или camel case в других языках). Сначала я просто осваивался с самим языком и входящими в стандартную поставку инструментами для обработки и отображения данных (надо сказать, достаточно богатыми), затем нашёл библиотеки ggplot2
для гибкого построения графиков и plyr
для операций вида split-apply-combine над массивами данных. Также существует возможность создавать файлы с Markdown
разметкой и внедрёнными в неё вычислениями на R (с помощью knitr
), что достаточно удобно. Однако, всё это статические графики и таблицы, и для любого изменения их внешнего вида, выбора некоторого подмножества данных требуется каждый раз переписывать код, а хотелось бы чего-то более динамичного, с возможностью ставить элементы управления вроде слайдеров, кнопок и другого.
Как оказалось, недавно появился удобный способ достичь этого в R
, с очень малым количеством дополнительного кода. Наткнулся я на этот инструмент можно сказать случайно, и не пожалел. Смотрите сами: Shiny
— «Easy web applications in R». Простейший пример есть прямо на той странице, и он действительно прост в написании. Надо сказать, что Shiny
— достаточно новый продукт, разработка (судя по репозиторию) началась в июне прошлого (2012) года и активно продвигается. Каких-либо багов в нём мне не встретилось, так что думаю можно считать проект стабильным. Кстати, на том же сайте можно найти RStudio — удобную IDE для разработки на R.
Таким образом, отображение статистики я стал реализовывать с использованием Shiny
. Некоторые скрины того, что получилось на текущий момент:
Также можно просмотреть эти страницы (правда в статическом виде, т.е. элементы управления не работают) на shiny-sample.aplavin.ru.
Видно, что возможности действительно богатые, причём внешний вид страницы можно полностью менять HTML
, CSS
и JavaScript
кодом (у меня везде используется стандартный вариант). Удобно, что для работы Shiny
не требуется устанавливать никакой сервер, всё необходимое содержится в самом R-пакете.
Подробности реализации
Весь код (и кейлоггер, и визуализация) доступен на BitBucket. Сейчас у меня вызывается по крону каждую минуту файл capture
, который с вероятностью 50% делает снимок и сохраняет его (из-за того, что камера инициализируется не мгновенно, делается 20 снимков и сохраняется последний из них). Кейлоггер представлен исполняемым файлом keylogger.py
, запускаемым из inittab
'a (с использованием опции respawn
). В папке statistics
хранятся файлы keylogger.stats.R
и keylogger.stats.Rmd
, первый из которых генерирует графики просто в виде картинок, второй — в виде HTML страницы с использованием knitr
(оба, разумеется, статичные). Наконец, в папке shiny_page
содержатся файлы собственно страницы (ui.R
, server.R
) и файл compute.data.R
, который вычисляет все необходимые данные (сейчас это занимает от 30 секунд до 1 минуты, вынесено в отдельный файл чтобы не вычислять каждый раз при открытии страницы). Для удобства в той же папке есть Makefile
, который позволяет запускать приложение командой make run
.
Изначально все эти вычисления производились почти полностью запросами к базе SQLite
, но затем, сравнив производительность GROUP BY
с функциями пакета plyr
, я увидел, что SQLite
выполняет аналогичные действия намного медленнее, даже с индексами. Единственная (но важная) проблема состоит в том, что для использования этих функций необходимо загружать весь набор данных в память. Сейчас при выполнении compute.data.R
используется около 1 Гб памяти, и через некоторое время 4 Гб на моём ноутбуке будет не хватать. В таком случае думаю нужно будет вернуться опять на вычисления средствами базы данных, это хотя и значительно медленнее, но хотя бы будет работать (хотя, конечно, предложения по этому поводу приветствуются).
Заключение
В итоге можно сказать, что я разобрался с R
— действительно удобным языком для подобных вычислений, с прозрачным захватом событий X сервера, ну и конечно получил красивую статистику своего использования компьютера. У меня есть ещё несколько идей по поводу того, какие графики и таблицы ещё стоит добавить в такой «отчёт», но интересно было бы также услышать ваши варианты (если кто-то дочитал до сюда).
Автор: chersanya