# frozen_string_literal: true # Genera resúmenes de información para poder mostrar estadísticas y se # corre regularmente a sí misma. class StatCollectionJob < ApplicationJob class CrontabException < StandardError; end # Descartar y notificar si pasó algo más. # # XXX: En realidad deberíamos seguir reintentando? discard_on(Exception) do |_, error| ExceptionNotifier.notify_exception error end # Correr indefinidamente una vez por hora. # # XXX: El orden importa, si el descarte viene después, nunca se va a # reintentar. retry_on(StatCollectionJob::CrontabException, wait: 1.hour, attempts: Float::INFINITY, jitter: 0) COLUMNS = %i[uri].freeze def perform(once: false) Stat::INTERVALS.each do |interval| options = { interval: interval } # Visitas por hostname AccessLog.completed_requests.non_robots.pages.group(:host).rollup('host', **options) combined_columns(**options) stats_by_site(**options) end # Registrar que se hicieron todas las recolecciones Stat.create! raise CrontabException unless once end private # Combinación de columnas def combined_columns(**options) COLUMNS.each do |column| AccessLog.completed_requests.non_robots.group(:host, column).rollup("host|#{column}", **options) end end # Uso de recursos por cada sitio. # # XXX: En realidad se agrupan por el deploy_id, que siempre será el # del DeployLocal. def stats_by_site(**options) Site.find_each do |site| site.build_stats.jekyll.group(:deploy_id).rollup('builds', **options) site.build_stats.jekyll.group(:deploy_id).rollup('space_used', **options) do |rollup| rollup.average(:bytes) end site.build_stats.jekyll.group(:deploy_id).rollup('build_time', **options) do |rollup| rollup.average(:seconds) end end end end