recopilar estadisticas de generación de sitios

This commit is contained in:
f 2019-07-25 21:07:53 -03:00
parent c282870db6
commit 25160186d8
No known key found for this signature in database
GPG key ID: 2AE5A13E321F953D
8 changed files with 105 additions and 7 deletions

6
app/models/build_stat.rb Normal file
View file

@ -0,0 +1,6 @@
# frozen_string_literal: true
# Recolecta estadísticas durante la generación del sitio
class BuildStat < ApplicationRecord
belongs_to :deploy
end

View file

@ -9,6 +9,7 @@ require 'open3'
# :attributes`.
class Deploy < ApplicationRecord
belongs_to :site
has_many :build_stats
def deploy
raise NotImplementedError
@ -18,16 +19,47 @@ class Deploy < ApplicationRecord
raise NotImplementedError
end
# Corre un comando y devuelve true si terminó correctamente
def run(cmd)
r = 1
def size
raise NotImplementedError
end
def time_start
@start = Time.now
end
def time_stop
@stop = Time.now
end
def time_spent_in_seconds
(@stop - @start).round(3)
end
# Corre un comando y devuelve true si terminó correctamente
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/AbcSize
def run(cmd)
# XXX: prestar atención a la concurrencia de sqlite3, se podría
# enviar los datos directamente a una API para que se manejen desde
# el proceso principal de rails y evitar problemas.
stat = build_stats.build action: cmd.split('-', 2).first.tr(' ', '_')
r = nil
time_start
Dir.chdir(site.path) do
Open3.popen2(env, cmd, unsetenv_others: true) do |_, _o, t|
Open3.popen2e(env, cmd, unsetenv_others: true) do |_, o, t|
r = t.value
stat.log = o.read
end
end
time_stop
r.exited?
stat.seconds = time_spent_in_seconds
stat.bytes = size
stat.save
r.try :exited?
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize
end

View file

@ -24,10 +24,21 @@ class DeployLocal < Deploy
1
end
# Obtener el tamaño de todos los archivos y directorios (los
# directorios son archivos :)
def size
paths = [destination, File.join(destination, '**', '**')]
Dir.glob(paths).map do |file|
File.size file
end.inject(:+)
end
private
# Un entorno que solo tiene lo que necesitamos
def env
# XXX: This doesn't support Windows paths :B
paths = [File.dirname(`which bundle`), '/usr/bin']
{ 'PATH' => paths.join(':'), 'JEKYLL_ENV' => 'production' }

View file

@ -12,8 +12,10 @@ class DeployZip < Deploy
# Una vez que el sitio está generado, tomar todos los archivos y
# y generar un zip accesible públicamente.
#
# TODO: Recolectar estadísticas y enviarlas a la base de datos
# rubocop:disable Metrics/MethodLength
# rubocop:disable Metrics/AbcSize
def deploy
time_start
Dir.chdir(destination) do
Zip::File.open(path, Zip::File::CREATE) do |z|
Dir.glob('./**/**').each do |f|
@ -21,9 +23,24 @@ class DeployZip < Deploy
end
end
end
time_stop
build_stats.create action: 'zip',
seconds: time_spent_in_seconds,
bytes: size
File.exist? path
end
# rubocop:enable Metrics/MethodLength
# rubocop:enable Metrics/AbcSize
def limit
1
end
def size
File.size path
end
private

View file

@ -0,0 +1,14 @@
# frozen_string_literal: true
class CreateBuildStats < ActiveRecord::Migration[5.2]
def change
create_table :build_stats do |t|
t.timestamps
t.belongs_to :deploy, index: true
t.integer :bytes
t.float :seconds
t.string :action, null: false
t.text :log
end
end
end

View file

@ -12,7 +12,18 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20_190_723_220_002) do
ActiveRecord::Schema.define(version: 20_190_725_185_427) do
create_table 'build_stats', force: :cascade do |t|
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false
t.integer 'deploy_id'
t.integer 'bytes'
t.float 'seconds'
t.string 'action', null: false
t.text 'log'
t.index ['deploy_id'], name: 'index_build_stats_on_deploy_id'
end
create_table 'deploys', force: :cascade do |t|
t.datetime 'created_at', null: false
t.datetime 'updated_at', null: false

View file

@ -6,6 +6,10 @@ class DeployZipTest < ActiveSupport::TestCase
assert deploy_local.deploy
assert File.directory?(deploy_local.destination)
assert_equal 3, deploy_local.build_stats.count
assert deploy_local.build_stats.map(&:bytes).compact.inject(:+).positive?
assert deploy_local.build_stats.map(&:seconds).compact.inject(:+).positive?
assert deploy_local.destroy
assert_not File.directory?(deploy_local.destination)

View file

@ -15,6 +15,9 @@ class DeployLocalTest < ActiveSupport::TestCase
assert File.file?(deploy.path)
assert_equal 'application/zip',
`file --mime-type "#{escaped_path}"`.split(' ').last
assert_equal 1, deploy.build_stats.count
assert deploy.build_stats.map(&:bytes).inject(:+).positive?
assert deploy.build_stats.map(&:seconds).inject(:+).positive?
local.destroy
end