2021-10-09 17:45:34 +00:00
|
|
|
# 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.
|
2021-10-09 18:47:42 +00:00
|
|
|
retry_on(StatCollectionJob::CrontabException, wait: 1.hour, attempts: Float::INFINITY, jitter: 0)
|
2021-10-09 17:45:34 +00:00
|
|
|
|
|
|
|
COLUMNS = %i[uri].freeze
|
|
|
|
|
|
|
|
def perform(once: false)
|
2021-10-20 16:14:19 +00:00
|
|
|
Site.find_each do |site|
|
|
|
|
hostnames = [site.hostname, site.alternative_hostnames].flatten
|
|
|
|
|
|
|
|
# Usamos el primero porque luego podemos hacer un rollup recursivo
|
|
|
|
options = { interval: Stat::INTERVALS.first }
|
2021-10-09 17:45:34 +00:00
|
|
|
|
|
|
|
# Visitas por hostname
|
2021-10-20 16:14:19 +00:00
|
|
|
hostnames.each do |hostname|
|
|
|
|
AccessLog.where(host: hostname).completed_requests.non_robots.pages.group(:host).rollup('host', **options)
|
|
|
|
|
|
|
|
combined_columns(hostname, **options)
|
|
|
|
end
|
2021-10-09 17:45:34 +00:00
|
|
|
|
2021-10-20 16:14:19 +00:00
|
|
|
stats_by_site(site, **options)
|
2021-10-09 17:45:34 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
# Registrar que se hicieron todas las recolecciones
|
|
|
|
Stat.create!
|
|
|
|
|
|
|
|
raise CrontabException unless once
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
# Combinación de columnas
|
2021-10-20 16:14:19 +00:00
|
|
|
def combined_columns(hostname, **options)
|
|
|
|
where = { host: hostname }
|
|
|
|
|
2021-10-09 17:45:34 +00:00
|
|
|
COLUMNS.each do |column|
|
2021-10-20 16:14:19 +00:00
|
|
|
AccessLog.where(host: hostname).pluck(Arel.sql("distinct #{column}")).each do |value|
|
|
|
|
where[column] = value
|
|
|
|
|
|
|
|
AccessLog.where(**where).completed_requests.non_robots.group(:host, column).rollup("host|#{column}", **options)
|
|
|
|
end
|
2021-10-09 17:45:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
# Uso de recursos por cada sitio.
|
|
|
|
#
|
|
|
|
# XXX: En realidad se agrupan por el deploy_id, que siempre será el
|
|
|
|
# del DeployLocal.
|
2021-10-20 16:14:19 +00:00
|
|
|
def stats_by_site(site, **options)
|
|
|
|
site.build_stats.jekyll.group(:deploy_id).rollup('builds', **options)
|
2021-10-09 17:45:34 +00:00
|
|
|
|
2021-10-20 16:14:19 +00:00
|
|
|
site.build_stats.jekyll.group(:deploy_id).rollup('space_used', **options) do |rollup|
|
|
|
|
rollup.average(:bytes)
|
|
|
|
end
|
2021-10-09 17:45:34 +00:00
|
|
|
|
2021-10-20 16:14:19 +00:00
|
|
|
site.build_stats.jekyll.group(:deploy_id).rollup('build_time', **options) do |rollup|
|
|
|
|
rollup.average(:seconds)
|
2021-10-09 17:45:34 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
end
|