active_job_log 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.coveralls.yml +1 -0
- data/.gitignore +9 -0
- data/.hound.yml +4 -0
- data/.rspec +3 -0
- data/.rubocop.yml +1038 -0
- data/.ruby-version +1 -0
- data/.travis.yml +15 -0
- data/CHANGELOG.md +7 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +215 -0
- data/Guardfile +15 -0
- data/LICENSE.txt +21 -0
- data/README.md +143 -0
- data/Rakefile +10 -0
- data/active_job_log.gemspec +32 -0
- data/app/assets/config/active_job_log_manifest.js +2 -0
- data/app/assets/images/active_job_log/.keep +0 -0
- data/app/assets/javascripts/active_job_log/application.js +13 -0
- data/app/assets/stylesheets/active_job_log/application.css +15 -0
- data/app/controllers/active_job_log/application_controller.rb +5 -0
- data/app/helpers/active_job_log/application_helper.rb +4 -0
- data/app/jobs/active_job_log/application_job.rb +4 -0
- data/app/mailers/active_job_log/application_mailer.rb +6 -0
- data/app/models/active_job_log/application_record.rb +5 -0
- data/app/models/active_job_log/job.rb +68 -0
- data/app/views/layouts/active_job_log/application.html.erb +14 -0
- data/bin/rails +14 -0
- data/config/routes.rb +2 -0
- data/db/migrate/20180511184635_create_active_job_log_jobs.rb +22 -0
- data/lib/active_job_log.rb +26 -0
- data/lib/active_job_log/engine.rb +14 -0
- data/lib/active_job_log/log_ext.rb +43 -0
- data/lib/active_job_log/version.rb +3 -0
- data/lib/generators/active_job_log/install/USAGE +5 -0
- data/lib/generators/active_job_log/install/install_generator.rb +19 -0
- data/lib/generators/active_job_log/install/templates/initializer.rb +2 -0
- data/lib/tasks/active_job_log_tasks.rake +4 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/config/manifest.js +5 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/javascripts/cable.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
- data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
- data/spec/dummy/app/controllers/application_controller.rb +3 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/jobs/application_job.rb +2 -0
- data/spec/dummy/app/mailers/application_mailer.rb +4 -0
- data/spec/dummy/app/models/application_record.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
- data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +38 -0
- data/spec/dummy/bin/update +29 -0
- data/spec/dummy/bin/yarn +11 -0
- data/spec/dummy/config.ru +5 -0
- data/spec/dummy/config/application.rb +27 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/cable.yml +10 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +54 -0
- data/spec/dummy/config/environments/production.rb +91 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
- data/spec/dummy/config/initializers/assets.rb +14 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +33 -0
- data/spec/dummy/config/puma.rb +56 -0
- data/spec/dummy/config/routes.rb +3 -0
- data/spec/dummy/config/secrets.yml +32 -0
- data/spec/dummy/config/spring.rb +6 -0
- data/spec/dummy/db/schema.rb +33 -0
- data/spec/dummy/package.json +5 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
- data/spec/dummy/public/apple-touch-icon.png +0 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/spec/assets/image.png +0 -0
- data/spec/dummy/spec/assets/video.mp4 +0 -0
- data/spec/dummy/spec/support/test_helpers.rb +5 -0
- data/spec/factories/active_job_log_jobs.rb +7 -0
- data/spec/lib/active_job_log/log_ext_spec.rb +84 -0
- data/spec/models/active_job_log/job_spec.rb +187 -0
- data/spec/rails_helper.rb +48 -0
- data/spec/spec_helper.rb +9 -0
- metadata +328 -0
@@ -0,0 +1,32 @@
|
|
1
|
+
$:.push File.expand_path("../lib", __FILE__)
|
2
|
+
|
3
|
+
# Maintain your gem"s version:
|
4
|
+
require "active_job_log/version"
|
5
|
+
|
6
|
+
# Describe your gem and declare its dependencies:
|
7
|
+
Gem::Specification.new do |s|
|
8
|
+
s.name = "active_job_log"
|
9
|
+
s.version = ActiveJobLog::VERSION
|
10
|
+
s.authors = ["Platanus", "Leandro Segovia"]
|
11
|
+
s.email = ["rubygems@platan.us", "ldlsegovia@gmail.com"]
|
12
|
+
s.homepage = "https://github.com/platanus/active_job_log"
|
13
|
+
s.summary = "Rails engine to keep jobs history"
|
14
|
+
s.description = "Rails engine to register jobs history, adding: job state, error feedback, duration, etc."
|
15
|
+
s.license = "MIT"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split($/).reject { |fn| fn.start_with? "spec" }
|
18
|
+
s.bindir = "exe"
|
19
|
+
s.executables = s.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
20
|
+
s.test_files = Dir["spec/**/*"]
|
21
|
+
|
22
|
+
s.add_dependency "rails", ">= 4.2.0"
|
23
|
+
s.add_dependency "enumerize", ">= 1.0"
|
24
|
+
|
25
|
+
s.add_development_dependency "pry"
|
26
|
+
s.add_development_dependency "pry-rails"
|
27
|
+
s.add_development_dependency "sqlite3"
|
28
|
+
s.add_development_dependency "rspec-rails"
|
29
|
+
s.add_development_dependency "guard-rspec"
|
30
|
+
s.add_development_dependency "factory_bot_rails"
|
31
|
+
s.add_development_dependency "coveralls"
|
32
|
+
end
|
File without changes
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|
@@ -0,0 +1,68 @@
|
|
1
|
+
module ActiveJobLog
|
2
|
+
class Job < ApplicationRecord
|
3
|
+
extend Enumerize
|
4
|
+
|
5
|
+
STATUSES = %i{queued pending finished failed}
|
6
|
+
|
7
|
+
validates :job_id, presence: true
|
8
|
+
|
9
|
+
enumerize :status, in: STATUSES, scope: true
|
10
|
+
|
11
|
+
serialize :params, Array
|
12
|
+
serialize :stack_trace, Array
|
13
|
+
|
14
|
+
before_save :set_queued_duration
|
15
|
+
before_save :set_execution_duration
|
16
|
+
before_save :set_total_duration
|
17
|
+
|
18
|
+
def self.update_job!(job_id, status, params = {})
|
19
|
+
params.merge!(status_to_params(status))
|
20
|
+
job = Job.find_or_create_by(job_id: job_id)
|
21
|
+
job.update_attributes!(params)
|
22
|
+
job
|
23
|
+
end
|
24
|
+
|
25
|
+
class << self
|
26
|
+
private
|
27
|
+
|
28
|
+
def status_to_params(status)
|
29
|
+
time_attr = infer_duration_attr_from_status(status)
|
30
|
+
{
|
31
|
+
time_attr => DateTime.current,
|
32
|
+
status: status
|
33
|
+
}
|
34
|
+
end
|
35
|
+
|
36
|
+
def infer_duration_attr_from_status(status)
|
37
|
+
case status
|
38
|
+
when :queued
|
39
|
+
:queued_at
|
40
|
+
when :pending
|
41
|
+
:started_at
|
42
|
+
when :finished, :failed
|
43
|
+
:ended_at
|
44
|
+
else
|
45
|
+
fail "invalid status"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
private
|
51
|
+
|
52
|
+
def set_queued_duration
|
53
|
+
return if queued_at.blank? || started_at.blank?
|
54
|
+
self.queued_duration = (started_at.to_f - queued_at.to_f).to_i
|
55
|
+
end
|
56
|
+
|
57
|
+
def set_execution_duration
|
58
|
+
return if started_at.blank? || ended_at.blank?
|
59
|
+
self.execution_duration = (ended_at.to_f - started_at.to_f).to_i
|
60
|
+
end
|
61
|
+
|
62
|
+
def set_total_duration
|
63
|
+
from = queued_at || started_at
|
64
|
+
return if from.blank? || ended_at.blank?
|
65
|
+
self.total_duration = (ended_at.to_f - from.to_f).to_i
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>Active job log</title>
|
5
|
+
<%= stylesheet_link_tag "active_job_log/application", media: "all" %>
|
6
|
+
<%= javascript_include_tag "active_job_log/application" %>
|
7
|
+
<%= csrf_meta_tags %>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
|
11
|
+
<%= yield %>
|
12
|
+
|
13
|
+
</body>
|
14
|
+
</html>
|
data/bin/rails
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails gems
|
3
|
+
# installed from the root of your application.
|
4
|
+
|
5
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
6
|
+
ENGINE_PATH = File.expand_path('../../lib/active_job_log/engine', __FILE__)
|
7
|
+
APP_PATH = File.expand_path('../../spec/dummy/config/application', __FILE__)
|
8
|
+
|
9
|
+
# Set up gems listed in the Gemfile.
|
10
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
11
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
12
|
+
|
13
|
+
require 'rails/all'
|
14
|
+
require 'rails/engine/commands'
|
data/config/routes.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
class CreateActiveJobLogJobs < ActiveRecord::Migration[5.2]
|
2
|
+
def change
|
3
|
+
create_table :active_job_log_jobs do |t|
|
4
|
+
t.string :job_id, index: true
|
5
|
+
t.text :params
|
6
|
+
t.string :status
|
7
|
+
t.string :job_class
|
8
|
+
t.string :error
|
9
|
+
t.text :stack_trace
|
10
|
+
t.datetime :queued_at
|
11
|
+
t.datetime :started_at
|
12
|
+
t.datetime :ended_at
|
13
|
+
t.integer :queued_duration
|
14
|
+
t.integer :execution_duration
|
15
|
+
t.integer :total_duration
|
16
|
+
t.integer :executions
|
17
|
+
t.string :queue_name
|
18
|
+
|
19
|
+
t.timestamps
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require "active_job_log/engine"
|
2
|
+
require "enumerize"
|
3
|
+
|
4
|
+
module ActiveJobLog
|
5
|
+
extend self
|
6
|
+
|
7
|
+
# You can add, in this module, your own configuration options as in the example below...
|
8
|
+
#
|
9
|
+
# attr_writer :my_option
|
10
|
+
#
|
11
|
+
# def my_option
|
12
|
+
# return "Default Value" unless @my_option
|
13
|
+
# @my_option
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# Then, you can customize the default behaviour (typically in a Rails initializer) like this:
|
17
|
+
#
|
18
|
+
# ActiveJobLog.setup do |config|
|
19
|
+
# config.root_url = "Another value"
|
20
|
+
# end
|
21
|
+
|
22
|
+
def setup
|
23
|
+
yield self
|
24
|
+
require "active_job_log"
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
module ActiveJobLog
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
isolate_namespace ActiveJobLog
|
4
|
+
|
5
|
+
config.generators do |g|
|
6
|
+
g.test_framework :rspec, fixture: false
|
7
|
+
g.fixture_replacement :factory_bot, dir: "spec/factories"
|
8
|
+
end
|
9
|
+
|
10
|
+
initializer "initialize" do
|
11
|
+
require_relative "./log_ext"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
module ActiveJobLog
|
2
|
+
module LogExt
|
3
|
+
extend ActiveSupport::Concern
|
4
|
+
|
5
|
+
included do
|
6
|
+
before_enqueue { |job| enqueue_job(job) }
|
7
|
+
before_perform { |job| execute_job(job) }
|
8
|
+
after_perform { |job| finish_job(job) }
|
9
|
+
|
10
|
+
rescue_from(Exception) do |exception|
|
11
|
+
fail_job(exception)
|
12
|
+
raise exception
|
13
|
+
end
|
14
|
+
|
15
|
+
def enqueue_job(job)
|
16
|
+
Job.update_job!(job.job_id, :queued, init_params(job))
|
17
|
+
end
|
18
|
+
|
19
|
+
def execute_job(job)
|
20
|
+
Job.update_job!(job.job_id, :pending, init_params(job))
|
21
|
+
end
|
22
|
+
|
23
|
+
def finish_job(job)
|
24
|
+
Job.update_job!(job.job_id, :finished)
|
25
|
+
end
|
26
|
+
|
27
|
+
def fail_job(exception)
|
28
|
+
Job.update_job!(job_id, :failed, error: exception.message, stack_trace: exception.backtrace)
|
29
|
+
end
|
30
|
+
|
31
|
+
def init_params(job)
|
32
|
+
{
|
33
|
+
job_class: self.class.name,
|
34
|
+
params: job.arguments,
|
35
|
+
executions: job.try(:executions),
|
36
|
+
queue_name: job.queue_name
|
37
|
+
}
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
ActiveJob::Base.send(:include, ActiveJobLog::LogExt)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class ActiveJobLog::InstallGenerator < Rails::Generators::Base
|
2
|
+
source_root File.expand_path('../templates', __FILE__)
|
3
|
+
|
4
|
+
def create_initializer
|
5
|
+
template "initializer.rb", "config/initializers/active_job_log.rb"
|
6
|
+
end
|
7
|
+
|
8
|
+
def mount_routes
|
9
|
+
line = "Rails.application.routes.draw do\n"
|
10
|
+
inject_into_file "config/routes.rb", after: line do <<-"HERE".gsub(/^ {4}/, '')
|
11
|
+
mount ActiveJobLog::Engine => "/active_job_log"
|
12
|
+
HERE
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def copy_engine_migrations
|
17
|
+
rake "railties:install:migrations"
|
18
|
+
end
|
19
|
+
end
|
data/spec/dummy/Rakefile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
2
|
+
// listed below.
|
3
|
+
//
|
4
|
+
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
5
|
+
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
|
6
|
+
//
|
7
|
+
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
8
|
+
// compiled file. JavaScript code in this file should be added after the last require_* statement.
|
9
|
+
//
|
10
|
+
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
|
11
|
+
// about supported directives.
|
12
|
+
//
|
13
|
+
//= require_tree .
|
@@ -0,0 +1,13 @@
|
|
1
|
+
// Action Cable provides the framework to deal with WebSockets in Rails.
|
2
|
+
// You can generate new channels where WebSocket features live using the `rails generate channel` command.
|
3
|
+
//
|
4
|
+
//= require action_cable
|
5
|
+
//= require_self
|
6
|
+
//= require_tree ./channels
|
7
|
+
|
8
|
+
(function() {
|
9
|
+
this.App || (this.App = {});
|
10
|
+
|
11
|
+
App.cable = ActionCable.createConsumer();
|
12
|
+
|
13
|
+
}).call(this);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
/*
|
2
|
+
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
3
|
+
* listed below.
|
4
|
+
*
|
5
|
+
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
6
|
+
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
|
7
|
+
*
|
8
|
+
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
|
9
|
+
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
|
10
|
+
* files in this directory. Styles in this file should be added after the last require_* statement.
|
11
|
+
* It is generally better to create a new file per style scope.
|
12
|
+
*
|
13
|
+
*= require_tree .
|
14
|
+
*= require_self
|
15
|
+
*/
|