Подсчет статистики загрузок в Google Analytics

  • Tutorial

Продолжая тему использования связки Nginx + Lua решил поделиться небольшой инструкцией подсчета загрузки статических данных и учетом всего этого в Google Analytics.

Будем считать что связка nginx-lua уже настроена и у нас имеется имя счетчика. Если нет, то в сети есть множество инструкций, также есть готовые сборки ( openresty.org ).
Для учета нам понадобиться скрипт, который будет отправлять данные в GA. Писать свой не хотелось и на просторах Github-a был найден пример: github.com/wstucco/ssga.lua Данный скрипт имеет один метод track, который принимает обязательным параметром имя счетчика, так же могут быть переданы имя хоста и путь, которые нужно передать. После его срабатывания, на панели статистики в реальном времени увидим наш переданный путь.
Учитывать загрузки можно двумя способами:
  • учитывать по пути загружаемого файла;
  • учитывать через события.

Первый вариант удобен когда нет смысла разделения файлов по категориям/группам, либо когда это сделать возможности нет, но вести статистику хочется. Второй вариант подходит для случая, когда есть строгая структура файлов, к примеру: раздел-категория-тип.
Рассмотри оба.

Простой учет пути

Самый простой путь, не требующий никаких особых манипуляций и подготовки. Поэтому приведу лишь конечную часть конфига nginx.

resolver  8.8.8.8;
access_by_lua '    
     local ssga = require( "ssga" )
     ssga.track({ua = "UA-25XXXXXX-1")
';

Перезагружаем и любуемся побежавшими записями в GA.

Учет через события

Данный способ требует определиться с тем, как будем квалифицировать скачиваемые файлы. В терминах GA нам нужно выделить 3 сущности: категория, действие, метка. В своем случае для этого использовал имена папок, тогда конечный URL загружаемого файла имел вид: dl.domain.name/category/action/label/filename.ext
Так же необходимо было научить имеющийся скрипт передавать данную информацию в GA. После небольших модификаций была получена расширенная версия скрипта ( github.com/fuCtor/ssga.lua ).
В итоге имеем следующую конфигурацию:

server {
  listen 80;
  server_name dl.domain.name;

  root /var/www/public;
  error_page 502 /502.html;

  location / {

    add_header Cache-Control public;
    expires  max;

    resolver 8.8.8.8;

    access_by_lua '
        opt = {}
        index  = 0
        for value in string.gmatch(ngx.var.uri ,"%w+") do
         opt [index] = value
         index = index + 1
        end
        local ssga = require( "ssga" )
        ssga.event({ua = "UA-25XXXXXX-1", domain = "dl.domain.name", category = opt[0], action = opt[1], label = opt[2], value = 1})
    ';
    }
}

Сохраняем перезагружаем. Теперь можем вести статистику по загрузкам в удобной форме, делать различные срезы.

Производительность

Проверять будем как быстро отработает именно наш счетчик, поэтому выполним HEAD запросы, тело нас не интересует.

Concurrency Level:      30
Time taken for tests:   3.223 seconds
Complete requests:      1000
Failed requests:        0
Write errors:           0
Total transferred:      348000 bytes
HTML transferred:       0 bytes
Requests per second:    310.26 [#/sec] (mean)
Time per request:       96.694 [ms] (mean)
Time per request:       3.223 [ms] (mean, across all concurrent requests)
Transfer rate:          105.44 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.1      0       1
Processing:    94   95   0.6     95      99
Waiting:       94   95   0.6     95      99
Total:         94   95   0.6     95      99


Concurrency Level:      30
Time taken for tests:   0.048 seconds
Complete requests:      200
Failed requests:        0
Write errors:           0
Total transferred:      69600 bytes
HTML transferred:       0 bytes
Requests per second:    4166.58 [#/sec] (mean)
Time per request:       7.200 [ms] (mean)
Time per request:       0.240 [ms] (mean, across all concurrent requests)
Transfer rate:          1415.99 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    0   0.3      0       1
Processing:     6    6   0.8      6       9
Waiting:        6    6   0.8      6       9
Total:          6    7   0.9      6      10



Изображение в шапке взято отсюда.
Поделиться публикацией
Похожие публикации
AdBlock похитил этот баннер, но баннеры не зубы — отрастут

Подробнее
Реклама
Комментарии 11
  • 0
    Алексей, hitrate измеряли продакшеном или использовали для тестирования какие-либо утилиты?
    • 0
      Если вы про то сколько сможет обработать на статике, то сейчас замерил, с данным конфигом, вышло следующее:

      #ab -i -n1000 -c10…
      Requests per second: 13.70 [#/sec] (mean)
      Time per request: 729.779 [ms] (mean)
      Time per request: 72.978 [ms] (mean, across all concurrent requests)

      (каждый заход был учтен корректно)

      Да не много, но это если отправлять на каждый чих, можно использовать shared_dict и накапливать хиты там, потом отправлять. При этом в последний параметр ставить не 1, а количество накопленных. Тогда можно уменьшить количество обращений к GA и повысить hitrate.
      • 0
        Омг, ваша картинка меня сбила и мой вопрос был не по адресу. Прошу прощения!
        • 0
          Бывает =) Заменил, чтобы не сбивала.
        • 0
          Сделал новые замеры, с соседней виртуалки. До этого делал с локальной машины. Добавил их в конец статьи.
      • 0
        Отличная штука, спасибо.
        А запрос к GA асинхронный?
        • +1
          Если я правильно понял документацию, то сокеты не блокирующие, но синхронные. То есть, текущее соединение ждет результата, но другие не блокируются. Хотя судя по цифрам как-то не понятно

          ngx.socket.tcp
          Creates and returns a TCP or stream-oriented unix domain socket object (also known as one type of the «cosocket» objects).

          tcpsock:send
          Sends data without blocking on the current TCP or Unix Domain Socket connection.
          This method is a synchronous operation that will not return until all the data has been flushed into the system socket send buffer or an error occurs.
          • 0
            Все верно. Сокеты — non-blocking & synchronous
            Если хочется асинхронных запросов, то можно сделать
            ngx.location.capture, где все и обрабатывать.
            Здесь уже будет асинхронно. Добавить shared_dict и будет наверное еще быстрее.
            • +1
              Не, Тёма, location.capture — он такой же, как сокеты: синхронный и неблокирующий; Lua будет ждать, пока capture не вернёт ответ.

              Но всегда можно перед ssga.event() засунуть ngx.eof(): это отцепит клиента, а сервер продолжит спокойно отсылать запрос в фоне. Ну или в локации, на которую уйдёт location.capture, первой строкой выполнить ngx.eof(), тогда capture выполнится мгновенно.
          • 0
            -не обновил страницу. удалил-
          • 0
            Прошу прощения за лёгкий оффтоп, но как же прекрасно, что на хабре есть столько людей разделяющих мой интерес к NgX+mod_lua :D
            // а может кто-нибудь из вас ещё и resty-template (с прочими resty-*) использует? :)

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.