sutty/app/jobs/stat_collection_job.rb

77 lines
2.2 KiB
Ruby
Raw Normal View History

# 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)
COLUMNS = %i[uri].freeze
def perform(once: false)
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 }
# Visitas por hostname
hostnames.each do |hostname|
AccessLog.where(host: hostname).completed_requests.non_robots.pages.group(:host).rollup('host', **options)
combined_columns(hostname, **options)
end
stats_by_site(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(hostname, **options)
where = { host: hostname }
COLUMNS.each do |column|
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
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(site, **options)
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