sapience 0.2.4 → 0.2.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.codeclimate.yml +21 -0
- data/.simplecov +19 -16
- data/.travis.yml +3 -3
- data/CHANGELOG.md +4 -0
- data/Gemfile +0 -8
- data/README.md +5 -0
- data/config/default.yml +4 -0
- data/docker-compose.yml +14 -0
- data/lib/sapience/appender/stream.rb +0 -1
- data/lib/sapience/base.rb +34 -4
- data/lib/sapience/configuration.rb +41 -20
- data/lib/sapience/core_ext/hash.rb +10 -7
- data/lib/sapience/core_ext/symbol.rb +15 -0
- data/lib/sapience/core_ext/thread.rb +1 -0
- data/lib/sapience/extensions/action_cable/tagged_logger_proxy.rb +2 -0
- data/lib/sapience/extensions/action_controller/live.rb +2 -0
- data/lib/sapience/extensions/action_controller/log_subscriber.rb +76 -121
- data/lib/sapience/extensions/action_dispatch/debug_exceptions.rb +2 -0
- data/lib/sapience/extensions/action_view/log_subscriber.rb +16 -6
- data/lib/sapience/extensions/action_view/streaming_template_renderer.rb +2 -0
- data/lib/sapience/extensions/active_job/logging.rb +1 -1
- data/lib/sapience/extensions/active_model_serializers/logging.rb +7 -2
- data/lib/sapience/extensions/active_record/log_subscriber.rb +45 -29
- data/lib/sapience/extensions/rails/rack/logger.rb +1 -0
- data/lib/sapience/extensions/rails/rack/logger_info_as_debug.rb +2 -0
- data/lib/sapience/formatters/color.rb +0 -1
- data/lib/sapience/formatters/default.rb +0 -1
- data/lib/sapience/formatters/json.rb +0 -1
- data/lib/sapience/formatters/raw.rb +0 -1
- data/lib/sapience/log.rb +54 -35
- data/lib/sapience/logger.rb +50 -71
- data/lib/sapience/rails.rb +17 -20
- data/lib/sapience/sapience.rb +23 -27
- data/lib/sapience/subscriber.rb +1 -13
- data/lib/sapience/version.rb +1 -1
- data/lib/sapience.rb +4 -3
- data/sapience.gemspec +6 -1
- data/test_app/Gemfile +7 -0
- data/test_app/Rakefile +2 -0
- data/test_app/app/models/post.rb +1 -1
- data/test_app/app/views/posts/_form.html.slim +18 -0
- data/test_app/app/views/posts/edit.html.slim +8 -0
- data/test_app/app/views/posts/index.html.slim +25 -0
- data/test_app/app/views/posts/new.html.slim +5 -0
- data/test_app/app/views/posts/show.html.slim +15 -0
- data/test_app/app/workers/test_worker.rb +17 -0
- data/test_app/bin/sneakers +10 -0
- data/test_app/config/initializers/sneakers.rb +15 -0
- data/test_app/config/sapience_example.yml +24 -0
- data/test_app/db/migrate/{20160812093621_create_posts.rb → 20160902141445_create_posts.rb} +1 -1
- data/test_app/db/schema.rb +1 -1
- data/test_app/lib/external_sneaker.rb +46 -0
- data/test_app/spec/factories/posts.rb +7 -0
- data/test_app/spec/factories/users.rb +8 -0
- data/test_app/spec/rails_helper.rb +8 -3
- data/test_app/spec/requests/posts_spec.rb +2 -1
- data/test_app/spec/views/posts/edit.html.slim_spec.rb +17 -0
- data/test_app/spec/views/posts/index.html.slim_spec.rb +17 -0
- data/test_app/spec/views/posts/new.html.slim_spec.rb +17 -0
- data/test_app/spec/views/posts/show.html.slim_spec.rb +14 -0
- data/test_app/spec/workers/test_worker_spec.rb +36 -0
- data/test_app.simplecov +19 -0
- metadata +95 -15
- data/.coveralls.yml +0 -1
- data/lib/sapience/extensions/action_controller/log_subscriber_processing.rb +0 -24
- data/test_app/app/views/posts/_form.html.erb +0 -32
- data/test_app/app/views/posts/create.html.erb +0 -2
- data/test_app/app/views/posts/destroy.html.erb +0 -2
- data/test_app/app/views/posts/edit.html.erb +0 -6
- data/test_app/app/views/posts/index.html.erb +0 -31
- data/test_app/app/views/posts/new.html.erb +0 -5
- data/test_app/app/views/posts/show.html.erb +0 -19
- data/test_app/app/views/posts/update.html.erb +0 -2
data/lib/sapience/logger.rb
CHANGED
@@ -7,31 +7,6 @@ module Sapience
|
|
7
7
|
class Logger < Base # rubocop:disable ClassLength, ClassVars
|
8
8
|
include Sapience::Concerns::Compatibility
|
9
9
|
|
10
|
-
# Returns a Logger instance
|
11
|
-
#
|
12
|
-
# Return the logger for a specific class, supports class specific log levels
|
13
|
-
# logger = Sapience::Logger.new(self)
|
14
|
-
# OR
|
15
|
-
# logger = Sapience::Logger.new('MyClass')
|
16
|
-
#
|
17
|
-
# Parameters:
|
18
|
-
# application
|
19
|
-
# A class, module or a string with the application/class name
|
20
|
-
# to be used in the logger
|
21
|
-
#
|
22
|
-
# level
|
23
|
-
# The initial log level to start with for this logger instance
|
24
|
-
# Default: Sapience.config.default_level
|
25
|
-
#
|
26
|
-
# filter [Regexp|Proc]
|
27
|
-
# RegExp: Only include log messages where the class name matches the supplied
|
28
|
-
# regular expression. All other messages will be ignored
|
29
|
-
# Proc: Only include log messages where the supplied Proc returns true
|
30
|
-
# The Proc must return true or false
|
31
|
-
def initialize(klass, level = nil, filter = nil)
|
32
|
-
super
|
33
|
-
end
|
34
|
-
|
35
10
|
# Flush all queued log entries disk, database, etc.
|
36
11
|
# All queued log messages are written and then each appender is flushed in turn
|
37
12
|
def self.flush # rubocop:disable AbcSize
|
@@ -73,51 +48,6 @@ module Sapience
|
|
73
48
|
Sapience.remove_appender(appender)
|
74
49
|
end
|
75
50
|
|
76
|
-
@@lag_check_interval = 5000
|
77
|
-
@@lag_threshold_s = 30
|
78
|
-
|
79
|
-
# Returns the check_interval which is the number of messages between checks
|
80
|
-
# to determine if the appender thread is falling behind
|
81
|
-
def self.lag_check_interval
|
82
|
-
@@lag_check_interval
|
83
|
-
end
|
84
|
-
|
85
|
-
# Set the check_interval which is the number of messages between checks
|
86
|
-
# to determine if the appender thread is falling behind
|
87
|
-
def self.lag_check_interval=(lag_check_interval)
|
88
|
-
@@lag_check_interval = lag_check_interval
|
89
|
-
end
|
90
|
-
|
91
|
-
# Returns the amount of time in seconds
|
92
|
-
# to determine if the appender thread is falling behind
|
93
|
-
def self.lag_threshold_s
|
94
|
-
@@lag_threshold_s
|
95
|
-
end
|
96
|
-
|
97
|
-
# Allow the internal logger to be overridden from its default to STDERR
|
98
|
-
# Can be replaced with another Ruby logger or Rails logger, but never to
|
99
|
-
# Sapience::Logger itself since it is for reporting problems
|
100
|
-
# while trying to log to the various appenders
|
101
|
-
def self.logger=(logger)
|
102
|
-
@@logger = logger
|
103
|
-
end
|
104
|
-
|
105
|
-
# Place log request on the queue for the Appender thread to write to each
|
106
|
-
# appender in the order that they were registered
|
107
|
-
def log(log, message = nil, progname = nil, &block)
|
108
|
-
# Compatibility with ::Logger
|
109
|
-
return add(log, message, progname, &block) unless log.is_a?(Sapience::Log)
|
110
|
-
@@appender_thread << lambda do
|
111
|
-
Sapience.appenders.each do |appender|
|
112
|
-
begin
|
113
|
-
appender.log(log)
|
114
|
-
rescue StandardError => exc
|
115
|
-
logger.error "Appender thread: Failed to log to appender: #{appender.inspect}", exc
|
116
|
-
end
|
117
|
-
end
|
118
|
-
end if @@appender_thread
|
119
|
-
end
|
120
|
-
|
121
51
|
@@appender_thread = nil
|
122
52
|
|
123
53
|
# Internal logger for Sapience
|
@@ -135,7 +65,7 @@ module Sapience
|
|
135
65
|
def self.start_appender_thread
|
136
66
|
return false if appender_thread_active?
|
137
67
|
|
138
|
-
@@appender_thread =
|
68
|
+
@@appender_thread = Sapience.log_executor_class.new
|
139
69
|
fail "Failed to start Appender Thread" unless @@appender_thread
|
140
70
|
true
|
141
71
|
end
|
@@ -151,6 +81,55 @@ module Sapience
|
|
151
81
|
def self.appender_thread
|
152
82
|
@@appender_thread
|
153
83
|
end
|
84
|
+
|
85
|
+
# Allow the internal logger to be overridden from its default to STDERR
|
86
|
+
# Can be replaced with another Ruby logger or Rails logger, but never to
|
87
|
+
# Sapience::Logger itself since it is for reporting problems
|
88
|
+
# while trying to log to the various appenders
|
89
|
+
def self.logger=(logger)
|
90
|
+
@@logger = logger
|
91
|
+
end
|
92
|
+
|
93
|
+
# Returns a Logger instance
|
94
|
+
#
|
95
|
+
# Return the logger for a specific class, supports class specific log levels
|
96
|
+
# logger = Sapience::Logger.new(self)
|
97
|
+
# OR
|
98
|
+
# logger = Sapience::Logger.new('MyClass')
|
99
|
+
#
|
100
|
+
# Parameters:
|
101
|
+
# application
|
102
|
+
# A class, module or a string with the application/class name
|
103
|
+
# to be used in the logger
|
104
|
+
#
|
105
|
+
# level
|
106
|
+
# The initial log level to start with for this logger instance
|
107
|
+
# Default: Sapience.config.default_level
|
108
|
+
#
|
109
|
+
# filter [Regexp|Proc]
|
110
|
+
# RegExp: Only include log messages where the class name matches the supplied
|
111
|
+
# regular expression. All other messages will be ignored
|
112
|
+
# Proc: Only include log messages where the supplied Proc returns true
|
113
|
+
# The Proc must return true or false
|
114
|
+
def initialize(klass, level = nil, filter = nil)
|
115
|
+
super
|
116
|
+
end
|
117
|
+
|
118
|
+
# Place log request on the queue for the Appender thread to write to each
|
119
|
+
# appender in the order that they were registered
|
120
|
+
def log(log, message = nil, progname = nil, &block)
|
121
|
+
# Compatibility with ::Logger
|
122
|
+
return add(log, message, progname, &block) unless log.is_a?(Sapience::Log)
|
123
|
+
@@appender_thread << lambda do
|
124
|
+
Sapience.appenders.each do |appender|
|
125
|
+
begin
|
126
|
+
appender.log(log)
|
127
|
+
rescue StandardError => exc
|
128
|
+
self.class.logger.error "Appender thread: Failed to log to appender: #{appender.inspect}", exc
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end if @@appender_thread
|
132
|
+
end
|
154
133
|
# rubocop:enable BlockNesting, AssignmentInCondition, PerceivedComplexity, CyclomaticComplexity, AbcSize, LineLength, RescueException
|
155
134
|
end
|
156
135
|
end
|
data/lib/sapience/rails.rb
CHANGED
@@ -1,4 +1,15 @@
|
|
1
1
|
require "sapience"
|
2
|
+
require "sapience/extensions/action_cable/tagged_logger_proxy"
|
3
|
+
require "sapience/extensions/action_controller/live"
|
4
|
+
require "sapience/extensions/action_controller/log_subscriber"
|
5
|
+
require "sapience/extensions/action_dispatch/debug_exceptions"
|
6
|
+
require "sapience/extensions/action_view/streaming_template_renderer"
|
7
|
+
require "sapience/extensions/active_job/logging"
|
8
|
+
require "sapience/extensions/active_model_serializers/logging"
|
9
|
+
require "sapience/extensions/active_record/log_subscriber"
|
10
|
+
require "sapience/extensions/rails/rack/logger"
|
11
|
+
require "sapience/extensions/rails/rack/logger_info_as_debug"
|
12
|
+
require "sapience/extensions/action_view/log_subscriber"
|
2
13
|
|
3
14
|
module Sapience
|
4
15
|
class Rails < ::Rails::Engine
|
@@ -35,38 +46,24 @@ module Sapience
|
|
35
46
|
Raven.send(:include) { Sapience::Loggable }
|
36
47
|
|
37
48
|
# Replace the Sneakers logger
|
38
|
-
Sneakers.
|
49
|
+
Sneakers.configure(log: Sapience[Sneakers]) if defined?(Sneakers)
|
39
50
|
|
40
51
|
# Replace the Bugsnag logger
|
41
52
|
Bugsnag.configure { |config| config.logger = Sapience[Bugsnag] } if defined?(Bugsnag)
|
42
53
|
|
43
54
|
# Set the logger for concurrent-ruby
|
44
55
|
Concurrent.global_logger = Sapience[Concurrent] if defined?(Concurrent)
|
45
|
-
|
46
|
-
# Rails Patches
|
47
|
-
Kernel.require "sapience/extensions/action_cable/tagged_logger_proxy" if defined?(ActionCable)
|
48
|
-
Kernel.require "sapience/extensions/action_controller/live" if defined?(ActionController::Live)
|
49
|
-
Kernel.require "sapience/extensions/action_dispatch/debug_exceptions" if defined?(ActionDispatch::DebugExceptions)
|
50
|
-
if defined?(ActionView::StreamingTemplateRenderer::Body)
|
51
|
-
Kernel.require "sapience/extensions/action_view/streaming_template_renderer"
|
52
|
-
end
|
53
|
-
Kernel.require "sapience/extensions/active_job/logging" if defined?(ActiveJob)
|
54
|
-
Kernel.require "sapience/extensions/active_model_serializers/logging" if defined?(ActiveModelSerializers)
|
55
|
-
Kernel.require "sapience/extensions/action_controller/log_subscriber" if defined?(ActionController)
|
56
|
-
Kernel.require "sapience/extensions/active_record/log_subscriber" if defined?(ActiveRecord::LogSubscriber)
|
57
|
-
Kernel.require "sapience/extensions/rails/rack/logger" if defined?(::Rails::Rack::Logger)
|
58
|
-
Kernel.require "sapience/extensions/rails/rack/logger_info_as_debug" if defined?(::Rails::Rack::Logger)
|
59
|
-
Kernel.require "sapience/extensions/action_view/log_subscriber" if defined?(ActionView::LogSubscriber)
|
60
|
-
if defined?(ActionView::LogSubscriber)
|
61
|
-
Kernel.require "sapience/extensions/action_controller/log_subscriber_processing"
|
62
|
-
end
|
63
56
|
end
|
64
57
|
|
65
58
|
# Before any initializers run, but after the gems have been loaded
|
66
59
|
config.after_initialize do
|
67
60
|
# Replace the Bugsnag logger
|
68
61
|
Bugsnag.configure { |config| config.logger = Sapience[Bugsnag] } if defined?(Bugsnag)
|
62
|
+
Sapience::Extensions::ActionController::LogSubscriber.attach_to :action_controller
|
63
|
+
# Sapience::Extensions::ActiveSupport::MailerLogSubscriber.attach_to :action_mailer
|
64
|
+
Sapience::Extensions::ActiveRecord::LogSubscriber.attach_to :active_record
|
65
|
+
Sapience::Extensions::ActionView::LogSubscriber.attach_to :action_view
|
66
|
+
# Sapience::Extensions::ActiveJob::LogSubscriber.attach_to :active_job
|
69
67
|
end
|
70
|
-
|
71
68
|
end
|
72
69
|
end
|
data/lib/sapience/sapience.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require "concurrent"
|
2
2
|
require "socket"
|
3
3
|
require "sapience/descendants"
|
4
|
+
require "English"
|
4
5
|
|
5
6
|
# Example:
|
6
7
|
#
|
@@ -19,12 +20,16 @@ require "sapience/descendants"
|
|
19
20
|
|
20
21
|
# rubocop:disable ClassVars
|
21
22
|
module Sapience
|
23
|
+
UnknownClass = Class.new(NameError)
|
22
24
|
@@configured = nil
|
23
25
|
|
24
26
|
# Logging levels in order of most detailed to most severe
|
25
27
|
LEVELS = [:trace, :debug, :info, :warn, :error, :fatal].freeze
|
26
28
|
DEFAULT_ENV = "default".freeze
|
27
29
|
|
30
|
+
# TODO: Should we really always read from file?
|
31
|
+
# What if someone wants to configure sapience with a block
|
32
|
+
# without reading the default.yml?
|
28
33
|
def self.config
|
29
34
|
@@config ||= begin
|
30
35
|
config = ConfigLoader.load_from_file
|
@@ -48,6 +53,7 @@ module Sapience
|
|
48
53
|
@@logger = nil
|
49
54
|
@@metrix = nil
|
50
55
|
@@configured = nil
|
56
|
+
clear_tags!
|
51
57
|
reset_appenders!
|
52
58
|
end
|
53
59
|
|
@@ -68,6 +74,8 @@ module Sapience
|
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
77
|
+
# TODO: Maybe when configuring with a block we should create a new config?
|
78
|
+
# See the TODO note on .config for more information
|
71
79
|
def self.configure(force: false)
|
72
80
|
yield config if block_given?
|
73
81
|
return config if configured? && force == false
|
@@ -162,7 +170,7 @@ module Sapience
|
|
162
170
|
# logger.debug("Login time", user: 'Joe', duration: 100, ip_address: '127.0.0.1')
|
163
171
|
def self.add_appender(appender, options = {}, _deprecated_level = nil, &_block)
|
164
172
|
fail ArgumentError, "options should be a hash" unless options.is_a?(Hash)
|
165
|
-
options.
|
173
|
+
options.deep_symbolize_keyz!
|
166
174
|
appender_class = constantize_symbol(appender)
|
167
175
|
validate_appender!(appender_class)
|
168
176
|
|
@@ -273,19 +281,6 @@ module Sapience
|
|
273
281
|
Thread.current[:sapience_tags].pop
|
274
282
|
end
|
275
283
|
|
276
|
-
# Add the supplied named tags to the list of tags to log for this thread whilst
|
277
|
-
# the supplied block is active.
|
278
|
-
#
|
279
|
-
# Returns result of block
|
280
|
-
#
|
281
|
-
# Example:
|
282
|
-
def self.named_tags(tag)
|
283
|
-
(Thread.current[:sapience_tags] ||= []) << tag
|
284
|
-
yield
|
285
|
-
ensure
|
286
|
-
Thread.current[:sapience_tags].pop
|
287
|
-
end
|
288
|
-
|
289
284
|
# Add the supplied tags to the list of tags to log for this thread whilst
|
290
285
|
# the supplied block is active.
|
291
286
|
# Returns result of block
|
@@ -314,6 +309,10 @@ module Sapience
|
|
314
309
|
new_tags
|
315
310
|
end
|
316
311
|
|
312
|
+
def self.clear_tags!
|
313
|
+
Thread.current[:sapience_tags] = []
|
314
|
+
end
|
315
|
+
|
317
316
|
# Remove specified number of tags from the current tag list
|
318
317
|
def self.pop_tags(quantity = 1)
|
319
318
|
t = Thread.current[:sapience_tags]
|
@@ -366,11 +365,13 @@ module Sapience
|
|
366
365
|
|
367
366
|
reset_appenders!
|
368
367
|
|
368
|
+
def self.log_executor_class
|
369
|
+
constantize_symbol(config.log_executor, "Concurrent")
|
370
|
+
end
|
371
|
+
|
369
372
|
def self.constantize_symbol(symbol, namespace = "Sapience::Appender")
|
370
|
-
|
371
|
-
constantize(
|
372
|
-
rescue NameError
|
373
|
-
raise(ArgumentError, "Could not convert symbol: #{symbol} to a class in: #{namespace}. Looking for: #{klass}")
|
373
|
+
class_name = "#{namespace}::#{symbol.camelize}"
|
374
|
+
constantize(class_name)
|
374
375
|
end
|
375
376
|
|
376
377
|
def self.constantize(class_name)
|
@@ -380,16 +381,11 @@ module Sapience
|
|
380
381
|
else
|
381
382
|
class_name.split("::").inject(Object) { |o, name| o.const_get(name) } # rubocop:disable SingleLineBlockParams
|
382
383
|
end
|
384
|
+
rescue NameError
|
385
|
+
raise UnknownClass, "Could not find class: #{class_name}."
|
383
386
|
end
|
384
387
|
|
385
|
-
|
386
|
-
|
387
|
-
string = term.to_s
|
388
|
-
string = string.sub(/^[a-z\d]*/) { |match| match.capitalize }
|
389
|
-
string.gsub!(/(?:_|(\/))([a-z\d]*)/i) do
|
390
|
-
"#{Regexp.last_match[1]}#{inflections.acronyms[Regexp.last_match[2]] || Regexp.last_match[2].capitalize}"
|
391
|
-
end
|
392
|
-
string.gsub!("/".freeze, "::".freeze)
|
393
|
-
string
|
388
|
+
def self.root
|
389
|
+
@_root ||= Gem::Specification.find_by_name("sapience").gem_dir
|
394
390
|
end
|
395
391
|
end
|
data/lib/sapience/subscriber.rb
CHANGED
@@ -105,9 +105,7 @@ module Sapience
|
|
105
105
|
# rubocop:disable CyclomaticComplexity, AbcSize, PerceivedComplexity
|
106
106
|
def extract_formatter(formatter, &block)
|
107
107
|
case
|
108
|
-
when formatter.is_a?(Symbol)
|
109
|
-
Sapience.constantize_symbol(formatter, "Sapience::Formatters").new
|
110
|
-
when formatter.is_a?(String)
|
108
|
+
when formatter.is_a?(Symbol) || formatter.is_a?(String)
|
111
109
|
Sapience.constantize_symbol(formatter, "Sapience::Formatters").new
|
112
110
|
when formatter.is_a?(Hash) && formatter.size > 0
|
113
111
|
fmt, options = formatter.first
|
@@ -123,15 +121,5 @@ module Sapience
|
|
123
121
|
end
|
124
122
|
end
|
125
123
|
# rubocop:enable CyclomaticComplexity, AbcSize, PerceivedComplexity
|
126
|
-
|
127
|
-
SUBSCRIBER_OPTIONS = [:level, :formatter, :filter, :application, :host].freeze
|
128
|
-
|
129
|
-
# Returns [Hash] the subscriber common options from the supplied Hash
|
130
|
-
def extract_subscriber_options!(options)
|
131
|
-
subscriber_options = {}
|
132
|
-
SUBSCRIBER_OPTIONS.each { |key| subscriber_options[key] = options.delete(key) if options.key?(key) }
|
133
|
-
subscriber_options
|
134
|
-
end
|
135
|
-
|
136
124
|
end
|
137
125
|
end
|
data/lib/sapience/version.rb
CHANGED
data/lib/sapience.rb
CHANGED
@@ -1,4 +1,8 @@
|
|
1
1
|
require "sapience/version"
|
2
|
+
require "sapience/ansi_colors"
|
3
|
+
require "sapience/core_ext/hash"
|
4
|
+
require "sapience/core_ext/symbol"
|
5
|
+
require "sapience/core_ext/thread"
|
2
6
|
require "sapience/sapience"
|
3
7
|
|
4
8
|
# @formatter:off
|
@@ -14,9 +18,6 @@ require "sapience/formatters/json"
|
|
14
18
|
require "sapience/config_loader"
|
15
19
|
require "sapience/configuration"
|
16
20
|
require "sapience/configuration/grape"
|
17
|
-
require "sapience/ansi_colors"
|
18
|
-
require "sapience/core_ext/hash"
|
19
|
-
require "sapience/core_ext/thread"
|
20
21
|
require "sapience/base"
|
21
22
|
require "sapience/log"
|
22
23
|
require "sapience/logger"
|
data/sapience.gemspec
CHANGED
@@ -36,7 +36,12 @@ Gem::Specification.new do |spec|
|
|
36
36
|
spec.add_development_dependency "simplecov"
|
37
37
|
spec.add_development_dependency "simplecov-json"
|
38
38
|
spec.add_development_dependency "rspec-its"
|
39
|
+
spec.add_development_dependency "pry-nav"
|
40
|
+
spec.add_development_dependency "sentry-raven"
|
41
|
+
spec.add_development_dependency "dogstatsd-ruby"
|
42
|
+
spec.add_development_dependency "rails", "~> 5.0.0.1"
|
43
|
+
spec.add_development_dependency "grape"
|
44
|
+
spec.add_development_dependency "active_model_serializers", "~> 0.10.0"
|
39
45
|
spec.add_development_dependency "codeclimate-test-reporter"
|
40
|
-
spec.add_development_dependency "coveralls"
|
41
46
|
spec.add_development_dependency "gem-release"
|
42
47
|
end
|
data/test_app/Gemfile
CHANGED
@@ -17,6 +17,9 @@ gem "puma", "~> 3.0"
|
|
17
17
|
gem "sapience", path: "../", require: "sapience/rails"
|
18
18
|
gem "sentry-raven"
|
19
19
|
gem "statsd-ruby"
|
20
|
+
gem "sneakers"
|
21
|
+
gem "slim-rails"
|
22
|
+
gem "active_model_serializers"
|
20
23
|
|
21
24
|
group :development, :test do
|
22
25
|
# Call 'byebug' anywhere in the code to stop execution and get a debugger console
|
@@ -24,6 +27,7 @@ group :development, :test do
|
|
24
27
|
# gem "pry-nav"
|
25
28
|
gem "pry-byebug"
|
26
29
|
gem "rspec-rails"
|
30
|
+
gem "factory_girl_rails"
|
27
31
|
end
|
28
32
|
|
29
33
|
group :development do
|
@@ -34,6 +38,9 @@ end
|
|
34
38
|
|
35
39
|
group :test do
|
36
40
|
gem "rspec-its"
|
41
|
+
gem "bunny-mock"
|
42
|
+
gem "rspec-wait"
|
43
|
+
gem "rails-controller-testing"
|
37
44
|
end
|
38
45
|
|
39
46
|
# Windows does not include zoneinfo files, so bundle the tzinfo-data gem
|
data/test_app/Rakefile
CHANGED
data/test_app/app/models/post.rb
CHANGED
@@ -0,0 +1,18 @@
|
|
1
|
+
= form_for @post do |f|
|
2
|
+
- if @post.errors.any?
|
3
|
+
#error_explanation
|
4
|
+
h2 = "#{pluralize(@post.errors.count, "error")} prohibited this post from being saved:"
|
5
|
+
ul
|
6
|
+
- @post.errors.full_messages.each do |message|
|
7
|
+
li = message
|
8
|
+
|
9
|
+
.field
|
10
|
+
= f.label :title
|
11
|
+
= f.text_field :title
|
12
|
+
.field
|
13
|
+
= f.label :body
|
14
|
+
= f.text_field :body
|
15
|
+
.field
|
16
|
+
= f.label :author
|
17
|
+
= f.text_field :author
|
18
|
+
.actions = f.submit
|
@@ -0,0 +1,25 @@
|
|
1
|
+
h1 Listing posts
|
2
|
+
|
3
|
+
table
|
4
|
+
thead
|
5
|
+
tr
|
6
|
+
th Title
|
7
|
+
th Body
|
8
|
+
th Author
|
9
|
+
th
|
10
|
+
th
|
11
|
+
th
|
12
|
+
|
13
|
+
tbody
|
14
|
+
- @posts.each do |post|
|
15
|
+
tr
|
16
|
+
td = post.title
|
17
|
+
td = post.body
|
18
|
+
td = post.author
|
19
|
+
td = link_to 'Show', post
|
20
|
+
td = link_to 'Edit', edit_post_path(post)
|
21
|
+
td = link_to 'Destroy', post, data: { confirm: 'Are you sure?' }, method: :delete
|
22
|
+
|
23
|
+
br
|
24
|
+
|
25
|
+
= link_to 'New Post', new_post_path
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require_relative "../../../spec/support/file_helper"
|
2
|
+
|
3
|
+
class TestWorker
|
4
|
+
QUEUE_NAME = :sneakers_queue
|
5
|
+
ROUTING_KEY = :sneakers_routing_key
|
6
|
+
VERIFICATION_FILE = "tmp/sneakers.verified".freeze
|
7
|
+
|
8
|
+
include Sneakers::Worker
|
9
|
+
include FileHelper
|
10
|
+
|
11
|
+
from_queue QUEUE_NAME, routing_key: ROUTING_KEY
|
12
|
+
|
13
|
+
def work(_message)
|
14
|
+
create_file(VERIFICATION_FILE)
|
15
|
+
ack!
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "bundler/setup"
|
3
|
+
require "serverengine"
|
4
|
+
require "sneakers"
|
5
|
+
require "sneakers/runner"
|
6
|
+
require_relative "../app/workers/test_worker"
|
7
|
+
require_relative "../config/initializers/sneakers"
|
8
|
+
|
9
|
+
runner = Sneakers::Runner.new([TestWorker])
|
10
|
+
runner.run
|
@@ -0,0 +1,15 @@
|
|
1
|
+
require "serverengine"
|
2
|
+
require "sneakers"
|
3
|
+
|
4
|
+
p ENV.fetch("AMQP") { "amqp://guest:guest@localhost:5672" }
|
5
|
+
|
6
|
+
Sneakers.configure(
|
7
|
+
amqp: ENV.fetch("AMQP") { "amqp://guest:guest@localhost:5672" },
|
8
|
+
exchange_type: :direct,
|
9
|
+
log: Sapience[Sneakers], # Log file
|
10
|
+
exchange: "sapience", # AMQP exchange
|
11
|
+
durable: false, # Is queue durable?
|
12
|
+
ack: true, # Must we acknowledge?
|
13
|
+
metrics: Sapience.metrix,
|
14
|
+
)
|
15
|
+
Sapience.logger.level = Logger::DEBUG
|
@@ -0,0 +1,24 @@
|
|
1
|
+
---
|
2
|
+
default:
|
3
|
+
log_level: error
|
4
|
+
appenders:
|
5
|
+
- stream:
|
6
|
+
file_name: log/error.log
|
7
|
+
formatter: default
|
8
|
+
|
9
|
+
development:
|
10
|
+
log_level: debug
|
11
|
+
appenders:
|
12
|
+
- stream:
|
13
|
+
io: STDOUT
|
14
|
+
formatter: color
|
15
|
+
- stream:
|
16
|
+
file_name: log/development.log
|
17
|
+
formatter: color
|
18
|
+
|
19
|
+
test:
|
20
|
+
log_level: fatal
|
21
|
+
appenders:
|
22
|
+
- stream:
|
23
|
+
file_name: log/fatal.log
|
24
|
+
formatter: json
|
data/test_app/db/schema.rb
CHANGED
@@ -10,7 +10,7 @@
|
|
10
10
|
#
|
11
11
|
# It's strongly recommended that you check this file into your version control system.
|
12
12
|
|
13
|
-
ActiveRecord::Schema.define(version:
|
13
|
+
ActiveRecord::Schema.define(version: 20160902141445) do
|
14
14
|
|
15
15
|
create_table "posts", force: :cascade do |t|
|
16
16
|
t.string "title"
|
@@ -0,0 +1,46 @@
|
|
1
|
+
require "timeout"
|
2
|
+
|
3
|
+
class ExternalSneaker
|
4
|
+
attr_accessor :worker_pid, :start_command
|
5
|
+
|
6
|
+
def initialize(start_command)
|
7
|
+
fail ArgumentError, "start_command was expected" if start_command.nil?
|
8
|
+
|
9
|
+
self.start_command = start_command
|
10
|
+
end
|
11
|
+
|
12
|
+
def start
|
13
|
+
puts "Trying to start #{start_command}..."
|
14
|
+
self.worker_pid = fork do
|
15
|
+
start_child
|
16
|
+
end
|
17
|
+
|
18
|
+
at_exit do
|
19
|
+
stop_child
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def start_child
|
26
|
+
exec({ "RAILS_ENV" => Rails.env, "WORKERS" => "TestWorker" }, start_command)
|
27
|
+
end
|
28
|
+
|
29
|
+
def stop_child # rubocop:disable AbcSize
|
30
|
+
puts "Trying to stop #{start_command}, pid: #{worker_pid}"
|
31
|
+
|
32
|
+
# send TERM and wait for exit
|
33
|
+
Process.kill("TERM", worker_pid)
|
34
|
+
|
35
|
+
begin
|
36
|
+
Timeout.timeout(10) do
|
37
|
+
Process.waitpid(worker_pid)
|
38
|
+
puts "Process #{start_command} stopped successfully"
|
39
|
+
end
|
40
|
+
rescue Timeout::Error
|
41
|
+
# Kill process if could not exit in 10 seconds
|
42
|
+
puts "Sending KILL signal to #{start_command}, pid: #{worker_pid}"
|
43
|
+
Process.kill("KILL", worker_pid)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|