sapience 0.1.1 → 0.1.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.simplecov +6 -2
- data/.travis.yml +8 -25
- data/CODE_OF_CONDUCT.md +1 -1
- data/Gemfile +5 -5
- data/README.md +146 -15
- data/Rakefile +2 -1
- data/config/default.yml +29 -0
- data/dev-entrypoint.sh +10 -0
- data/docker-compose.yml +42 -0
- data/lib/sapience/appender/datadog.rb +100 -0
- data/lib/sapience/appender/file.rb +11 -22
- data/lib/sapience/appender/sentry.rb +61 -55
- data/lib/sapience/appender/wrapper.rb +5 -4
- data/lib/sapience/base.rb +21 -13
- data/lib/sapience/config_loader.rb +66 -0
- data/lib/sapience/configuration/grape.rb +9 -0
- data/lib/sapience/configuration.rb +32 -22
- data/lib/sapience/core_ext/hash.rb +25 -0
- data/lib/sapience/core_ext/thread.rb +2 -2
- data/lib/sapience/extensions/action_cable/tagged_logger_proxy.rb +6 -0
- data/lib/sapience/extensions/action_controller/live.rb +6 -0
- data/lib/sapience/extensions/action_controller/log_subscriber.rb +127 -0
- data/lib/sapience/extensions/action_controller/log_subscriber_processing.rb +24 -0
- data/lib/sapience/extensions/action_dispatch/debug_exceptions.rb +11 -0
- data/lib/sapience/extensions/action_view/log_subscriber.rb +9 -0
- data/lib/sapience/extensions/action_view/streaming_template_renderer.rb +11 -0
- data/lib/sapience/extensions/active_job/logging.rb +14 -0
- data/lib/sapience/extensions/active_model_serializers/logging.rb +14 -0
- data/lib/sapience/extensions/active_record/log_subscriber.rb +35 -0
- data/lib/sapience/extensions/grape/middleware/logging.rb +91 -0
- data/lib/sapience/extensions/grape/timings.rb +25 -0
- data/lib/sapience/extensions/rails/rack/logger.rb +11 -0
- data/lib/sapience/extensions/rails/rack/logger_info_as_debug.rb +24 -0
- data/lib/sapience/formatters/color.rb +3 -3
- data/lib/sapience/formatters/default.rb +1 -1
- data/lib/sapience/grape.rb +25 -0
- data/lib/sapience/log.rb +8 -6
- data/lib/sapience/loggable.rb +19 -17
- data/lib/sapience/logger.rb +46 -126
- data/lib/sapience/rails.rb +65 -8
- data/lib/sapience/sapience.rb +74 -73
- data/lib/sapience/subscriber.rb +5 -1
- data/lib/sapience/version.rb +1 -1
- data/lib/sapience.rb +4 -1
- data/sapience.gemspec +7 -4
- data/test_app/Gemfile +5 -1
- data/test_app/Rakefile +5 -1
- data/test_app/app/controllers/posts_controller.rb +12 -11
- data/test_app/config/application.rb +0 -1
- data/test_app/spec/controllers/posts_controller_spec.rb +1 -1
- data/test_app/spec/fixtures/sapience.yml +14 -0
- data/test_app/spec/helpers/posts_helper_spec.rb +1 -1
- data/test_app/spec/integration/sapience_spec.rb +14 -0
- data/test_app/spec/models/post_spec.rb +1 -1
- data/test_app/spec/models/user_spec.rb +1 -1
- data/test_app/spec/rails_helper.rb +15 -0
- data/test_app/spec/requests/posts_spec.rb +1 -1
- data/test_app/spec/routing/posts_routing_spec.rb +8 -10
- data/test_app/spec/spec_helper.rb +0 -44
- metadata +76 -11
- data/lib/sapience/appender/statsd.rb +0 -68
@@ -0,0 +1,91 @@
|
|
1
|
+
require "grape/middleware/base"
|
2
|
+
|
3
|
+
module Sapience
|
4
|
+
module Extensions
|
5
|
+
module Grape
|
6
|
+
module Middleware
|
7
|
+
class Logging < ::Grape::Middleware::Base
|
8
|
+
ActiveSupport::Notifications.subscribe("sql.active_record") do |*args|
|
9
|
+
event = ActiveSupport::Notifications::Event.new(*args)
|
10
|
+
Grape::Timings.append_db_runtime(event)
|
11
|
+
end if defined?(ActiveRecord)
|
12
|
+
|
13
|
+
def initialize(app, options = {})
|
14
|
+
super
|
15
|
+
@logger = @options[:logger]
|
16
|
+
end
|
17
|
+
|
18
|
+
def before
|
19
|
+
reset_db_runtime
|
20
|
+
start_time
|
21
|
+
end
|
22
|
+
|
23
|
+
def after
|
24
|
+
stop_time
|
25
|
+
@logger.info(parameters)
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def call!(env)
|
30
|
+
super
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def response
|
36
|
+
super
|
37
|
+
rescue
|
38
|
+
nil
|
39
|
+
end
|
40
|
+
|
41
|
+
def parameters # rubocop:disable AbcSize
|
42
|
+
{
|
43
|
+
status: (response.nil? ? "fail" : response.status),
|
44
|
+
time: {
|
45
|
+
total: total_runtime,
|
46
|
+
db: db_runtime,
|
47
|
+
view: view_runtime,
|
48
|
+
},
|
49
|
+
method: request.request_method,
|
50
|
+
path: request.path,
|
51
|
+
params: request.params,
|
52
|
+
host: request.host,
|
53
|
+
ip: (request.env["HTTP_X_FORWARDED_FOR"] || request.env["REMOTE_ADDR"]),
|
54
|
+
ua: request.env["HTTP_USER_AGENT"],
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
private
|
59
|
+
|
60
|
+
def request
|
61
|
+
@request ||= ::Rack::Request.new(env)
|
62
|
+
end
|
63
|
+
|
64
|
+
def total_runtime
|
65
|
+
((stop_time - start_time) * 1000).round(2)
|
66
|
+
end
|
67
|
+
|
68
|
+
def view_runtime
|
69
|
+
total_runtime - db_runtime
|
70
|
+
end
|
71
|
+
|
72
|
+
def db_runtime
|
73
|
+
Grape::Timings.db_runtime.round(2)
|
74
|
+
end
|
75
|
+
|
76
|
+
def reset_db_runtime
|
77
|
+
Grape::Timings.reset_db_runtime
|
78
|
+
end
|
79
|
+
|
80
|
+
def start_time
|
81
|
+
@start_time ||= Time.now
|
82
|
+
end
|
83
|
+
|
84
|
+
def stop_time
|
85
|
+
@stop_time ||= Time.now
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module Sapience
|
2
|
+
module Extensions
|
3
|
+
module Grape
|
4
|
+
module Timings
|
5
|
+
extend self
|
6
|
+
|
7
|
+
def db_runtime=(value)
|
8
|
+
Thread.current[:grape_db_runtime] = value
|
9
|
+
end
|
10
|
+
|
11
|
+
def db_runtime
|
12
|
+
Thread.current[:grape_db_runtime] ||= 0
|
13
|
+
end
|
14
|
+
|
15
|
+
def reset_db_runtime
|
16
|
+
self.db_runtime = 0
|
17
|
+
end
|
18
|
+
|
19
|
+
def append_db_runtime(event)
|
20
|
+
self.db_runtime += event.duration
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
# Replace rack started message with a semantic equivalent
|
2
|
+
class Rails::Rack::Logger # rubocop:disable ClassAndModuleChildren
|
3
|
+
def started_request_message(request)
|
4
|
+
{
|
5
|
+
message: "Started",
|
6
|
+
method: request.request_method,
|
7
|
+
path: request.filtered_path,
|
8
|
+
ip: request.ip,
|
9
|
+
}
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# Drop rack Started message to debug level message
|
2
|
+
class Rails::Rack::Logger # rubocop:disable ClassAndModuleChildren
|
3
|
+
|
4
|
+
private
|
5
|
+
|
6
|
+
module Extensions
|
7
|
+
def info(*args, &block)
|
8
|
+
debug(*args, &block)
|
9
|
+
end
|
10
|
+
|
11
|
+
def info?
|
12
|
+
debug?
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def logger
|
17
|
+
@logger ||= begin
|
18
|
+
logger = Sapience["Rails"]
|
19
|
+
logger.extend(Extensions)
|
20
|
+
logger
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
# Load AwesomePrint if available
|
2
2
|
begin
|
3
3
|
require "awesome_print"
|
4
|
-
rescue LoadError
|
4
|
+
rescue LoadError # rubocop:disable Lint/HandleExceptions
|
5
5
|
end
|
6
6
|
|
7
7
|
module Sapience
|
@@ -33,7 +33,7 @@ module Sapience
|
|
33
33
|
message << "#{level_color}#{log.level_to_s}#{colors::CLEAR} [#{log.process_info}]"
|
34
34
|
|
35
35
|
# Tags
|
36
|
-
message << " " << log.tags.collect { |tag| "[#{level_color}#{tag}#{colors::CLEAR}]" }.join(" ") if log.tags && (log.tags.size > 0)
|
36
|
+
message << " " << log.tags.collect { |tag| "[#{level_color}#{tag}#{colors::CLEAR}]" }.join(" ") if log.tags && (log.tags.size > 0) # rubocop:disable LineLength
|
37
37
|
|
38
38
|
# Duration
|
39
39
|
message << " (#{colors::BOLD}#{log.duration_human}#{colors::CLEAR})" if log.duration
|
@@ -49,7 +49,7 @@ module Sapience
|
|
49
49
|
payload = log.payload
|
50
50
|
message << " -- " <<
|
51
51
|
if defined?(AwesomePrint) && payload.respond_to?(:ai)
|
52
|
-
payload.ai(@ai_options) rescue payload.inspect
|
52
|
+
payload.ai(@ai_options) rescue payload.inspect # rubocop:disable RescueModifier
|
53
53
|
else
|
54
54
|
payload.inspect
|
55
55
|
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require "sapience"
|
2
|
+
require "sapience/extensions/grape/timings"
|
3
|
+
require "sapience/extensions/grape/middleware/logging"
|
4
|
+
|
5
|
+
module Grape
|
6
|
+
class API
|
7
|
+
def self.descendants # :nodoc:
|
8
|
+
descendants = []
|
9
|
+
ObjectSpace.each_object(singleton_class) do |k|
|
10
|
+
descendants.unshift k unless k == self
|
11
|
+
end
|
12
|
+
descendants
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
module Sapience
|
18
|
+
class Grape
|
19
|
+
Sapience.configure
|
20
|
+
::Grape::API.send(:include, Sapience::Loggable)
|
21
|
+
::Grape::API.descendants.each do |api|
|
22
|
+
api.send(:use, Sapience::Extensions::Grape::Middleware::Logging, logger: Sapience[self])
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/sapience/log.rb
CHANGED
@@ -43,6 +43,8 @@ module Sapience
|
|
43
43
|
# metric_amount [Numeric]
|
44
44
|
# Used for numeric or counter metrics.
|
45
45
|
# For example, the number of inquiries or, the amount purchased etc.
|
46
|
+
|
47
|
+
# rubocop:disable LineLength
|
46
48
|
Log = Struct.new(:level, :thread_name, :name, :message, :payload, :time, :duration, :tags, :level_index, :exception, :metric, :backtrace, :metric_amount) do
|
47
49
|
MAX_EXCEPTIONS_TO_UNWRAP = 5
|
48
50
|
# Call the block for exception and any nested exception
|
@@ -84,7 +86,7 @@ module Sapience
|
|
84
86
|
# Returns nil if their is no duration
|
85
87
|
def duration_to_s
|
86
88
|
return unless duration
|
87
|
-
duration < 10.0 ? "
|
89
|
+
format((duration < 10.0 ? "%.3fms" : "%.1fms"), duration)
|
88
90
|
end
|
89
91
|
|
90
92
|
# Returns [String] the duration in human readable form
|
@@ -98,7 +100,7 @@ module Sapience
|
|
98
100
|
elsif seconds >= 60.0 # 1 minute
|
99
101
|
Time.at(seconds).strftime("%-Mm %-Ss")
|
100
102
|
elsif seconds >= 1.0 # 1 second
|
101
|
-
"
|
103
|
+
format "%.3fs", seconds
|
102
104
|
else
|
103
105
|
duration_to_s
|
104
106
|
end
|
@@ -116,7 +118,7 @@ module Sapience
|
|
116
118
|
file, line = file_name_and_line(true)
|
117
119
|
file_name = " #{file}:#{line}" if file
|
118
120
|
|
119
|
-
"#{$PROCESS_ID}
|
121
|
+
format "#{$PROCESS_ID}:%.#{thread_name_length}s#{file_name}", thread_name
|
120
122
|
end
|
121
123
|
|
122
124
|
CALLER_REGEXP = /^(.*):(\d+).*/
|
@@ -129,7 +131,7 @@ module Sapience
|
|
129
131
|
|
130
132
|
# Returns [String, String] the file_name and line_number from the backtrace supplied
|
131
133
|
# in either the backtrace or exception
|
132
|
-
def file_name_and_line(short_name = false)
|
134
|
+
def file_name_and_line(short_name = false) # rubocop:disable CyclomaticComplexity
|
133
135
|
return unless backtrace || (exception && exception.backtrace)
|
134
136
|
stack = backtrace || exception.backtrace
|
135
137
|
extract_file_and_line(stack, short_name) if stack && stack.size > 0
|
@@ -155,7 +157,7 @@ module Sapience
|
|
155
157
|
# Ruby MRI supports micro seconds
|
156
158
|
# DEPRECATED
|
157
159
|
def formatted_time
|
158
|
-
"#{time.strftime("%Y-%m-%d %H:%M:%S")}
|
160
|
+
format("#{time.strftime("%Y-%m-%d %H:%M:%S")}.%06d", time.usec)
|
159
161
|
end
|
160
162
|
|
161
163
|
# Returns [Hash] representation of this log entry
|
@@ -217,5 +219,5 @@ module Sapience
|
|
217
219
|
h
|
218
220
|
end
|
219
221
|
end
|
220
|
-
|
222
|
+
# rubocop:enable LineLength
|
221
223
|
end
|
data/lib/sapience/loggable.rb
CHANGED
@@ -2,26 +2,28 @@ module Sapience
|
|
2
2
|
# rubocop:disable TrivialAccessors
|
3
3
|
module Loggable
|
4
4
|
def self.included(base)
|
5
|
-
base.
|
6
|
-
|
7
|
-
def self.logger
|
8
|
-
@sapience ||= Sapience[self]
|
9
|
-
end
|
5
|
+
base.send(:extend, Extensions)
|
6
|
+
end
|
10
7
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
8
|
+
# Returns [Sapience::Logger] instance level logger
|
9
|
+
def logger
|
10
|
+
@logger ||= self.class.logger
|
11
|
+
end
|
15
12
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
13
|
+
# Replace instance level logger
|
14
|
+
def logger=(logger)
|
15
|
+
@logger = logger
|
16
|
+
end
|
17
|
+
|
18
|
+
module Extensions
|
19
|
+
# Returns [Sapience::Logger] class level logger
|
20
|
+
def logger
|
21
|
+
@logger ||= Sapience[self]
|
22
|
+
end
|
20
23
|
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
end
|
24
|
+
# Replace instance class level logger
|
25
|
+
def logger=(logger)
|
26
|
+
@logger = logger
|
25
27
|
end
|
26
28
|
end
|
27
29
|
end
|
data/lib/sapience/logger.rb
CHANGED
@@ -32,42 +32,45 @@ module Sapience
|
|
32
32
|
super
|
33
33
|
end
|
34
34
|
|
35
|
-
# Returns [Integer] the number of log entries that have not been written
|
36
|
-
# to the appenders
|
37
|
-
#
|
38
|
-
# When this number grows it is because the logging appender thread is not
|
39
|
-
# able to write to the appenders fast enough. Either reduce the amount of
|
40
|
-
# logging, increase the log level, reduce the number of appenders, or
|
41
|
-
# look into speeding up the appenders themselves
|
42
|
-
def self.queue_size
|
43
|
-
queue.size
|
44
|
-
end
|
45
|
-
|
46
35
|
# Flush all queued log entries disk, database, etc.
|
47
36
|
# All queued log messages are written and then each appender is flushed in turn
|
48
|
-
def self.flush
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
37
|
+
def self.flush # rubocop:disable AbcSize
|
38
|
+
return unless appender_thread
|
39
|
+
appender_thread << lambda do
|
40
|
+
Sapience.appenders.each do |appender|
|
41
|
+
begin
|
42
|
+
logger.trace "Appender thread: Flushing appender: #{appender.name}"
|
43
|
+
appender.flush
|
44
|
+
rescue StandardError => exc
|
45
|
+
logger.error "Appender thread: Failed to flush appender: #{appender.inspect}", exc
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
logger.trace "Appender thread: All appenders flushed"
|
56
50
|
end
|
57
|
-
process_request(:flush)
|
58
51
|
end
|
59
52
|
|
60
53
|
# Close all appenders and flush any outstanding messages
|
61
54
|
def self.close
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
55
|
+
return unless appender_thread
|
56
|
+
appender_thread << lambda do
|
57
|
+
Sapience.appenders.each do |appender|
|
58
|
+
begin
|
59
|
+
close_appender(appender)
|
60
|
+
rescue StandardError => exc
|
61
|
+
logger.error "Appender thread: Failed to close appender: #{appender.inspect}", exc
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
logger.trace "Appender thread: All appenders flushed"
|
69
66
|
end
|
70
|
-
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.close_appender(appender)
|
70
|
+
logger.trace "Appender thread: Closing appender: #{appender.name}"
|
71
|
+
appender.flush
|
72
|
+
appender.close
|
73
|
+
Sapience.remove_appender(appender)
|
71
74
|
end
|
72
75
|
|
73
76
|
@@lag_check_interval = 5000
|
@@ -104,25 +107,25 @@ module Sapience
|
|
104
107
|
def log(log, message = nil, progname = nil, &block)
|
105
108
|
# Compatibility with ::Logger
|
106
109
|
return add(log, message, progname, &block) unless log.is_a?(Sapience::Log)
|
107
|
-
|
110
|
+
@@appender_thread.post(log) do |log_message|
|
111
|
+
Sapience.appenders.each do |appender|
|
112
|
+
begin
|
113
|
+
appender.log(log_message)
|
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
|
108
119
|
end
|
109
120
|
|
110
|
-
|
111
|
-
|
112
|
-
@@appender_thread = nil
|
113
|
-
@@queue = Queue.new
|
114
|
-
|
115
|
-
# Queue to hold messages that need to be logged to the various appenders
|
116
|
-
def self.queue
|
117
|
-
@@queue
|
118
|
-
end
|
121
|
+
@@appender_thread = nil
|
119
122
|
|
120
123
|
# Internal logger for Sapience
|
121
124
|
# For example when an appender is not working etc..
|
122
125
|
# By default logs to STDERR
|
123
126
|
def self.logger
|
124
127
|
@@logger ||= begin
|
125
|
-
l = Sapience::Appender::File.new(STDERR, :warn)
|
128
|
+
l = Sapience::Appender::File.new(io: STDERR, level: :warn)
|
126
129
|
l.name = name
|
127
130
|
l
|
128
131
|
end
|
@@ -131,106 +134,23 @@ module Sapience
|
|
131
134
|
# Start the appender thread
|
132
135
|
def self.start_appender_thread
|
133
136
|
return false if appender_thread_active?
|
134
|
-
|
137
|
+
|
138
|
+
@@appender_thread = Concurrent::SingleThreadExecutor.new
|
135
139
|
fail "Failed to start Appender Thread" unless @@appender_thread
|
136
140
|
true
|
137
141
|
end
|
138
142
|
|
139
143
|
# Returns true if the appender_thread is active
|
140
144
|
def self.appender_thread_active?
|
141
|
-
@@appender_thread && @@appender_thread.
|
145
|
+
@@appender_thread && @@appender_thread.running?
|
142
146
|
end
|
143
147
|
|
144
148
|
# Separate appender thread responsible for reading log messages and
|
145
149
|
# calling the appenders in it's thread
|
146
150
|
# rubocop:disable BlockNesting, AssignmentInCondition, PerceivedComplexity, CyclomaticComplexity, AbcSize, LineLength, RescueException
|
147
151
|
def self.appender_thread
|
148
|
-
|
149
|
-
# Before terminating at_exit is used to flush all the appenders
|
150
|
-
#
|
151
|
-
# Should any appender fail to log or flush, the exception is logged and
|
152
|
-
# other appenders will still be called
|
153
|
-
Thread.current.name = "Sapience::AppenderThread"
|
154
|
-
logger.trace "V#{VERSION} Appender thread active"
|
155
|
-
begin
|
156
|
-
count = 0
|
157
|
-
while message = queue.pop
|
158
|
-
if message.is_a?(Log)
|
159
|
-
Sapience.appenders.each do |appender|
|
160
|
-
begin
|
161
|
-
appender.log(message)
|
162
|
-
rescue Exception => exc
|
163
|
-
logger.error "Appender thread: Failed to log to appender: #{appender.inspect}", exc
|
164
|
-
end
|
165
|
-
end
|
166
|
-
count += 1
|
167
|
-
# Check every few log messages whether this appender thread is falling behind
|
168
|
-
if count > lag_check_interval
|
169
|
-
if (diff = Time.now - message.time) > lag_threshold_s
|
170
|
-
logger.warn "Appender thread has fallen behind by #{diff} seconds with #{queue_size} messages queued up. Consider reducing the log level or changing the appenders"
|
171
|
-
end
|
172
|
-
count = 0
|
173
|
-
end
|
174
|
-
else
|
175
|
-
case message[:command]
|
176
|
-
when :flush
|
177
|
-
Sapience.appenders.each do |appender|
|
178
|
-
begin
|
179
|
-
logger.trace "Appender thread: Flushing appender: #{appender.name}"
|
180
|
-
appender.flush
|
181
|
-
rescue Exception => exc
|
182
|
-
logger.error "Appender thread: Failed to flush appender: #{appender.inspect}", exc
|
183
|
-
end
|
184
|
-
end
|
185
|
-
|
186
|
-
message[:reply_queue] << true if message[:reply_queue]
|
187
|
-
logger.trace "Appender thread: All appenders flushed"
|
188
|
-
when :close
|
189
|
-
Sapience.appenders.each do |appender|
|
190
|
-
begin
|
191
|
-
logger.trace "Appender thread: Closing appender: #{appender.name}"
|
192
|
-
appender.flush
|
193
|
-
appender.close
|
194
|
-
Sapience.remove_appender(appender)
|
195
|
-
rescue Exception => exc
|
196
|
-
logger.error "Appender thread: Failed to close appender: #{appender.inspect}", exc
|
197
|
-
end
|
198
|
-
end
|
199
|
-
|
200
|
-
message[:reply_queue] << true if message[:reply_queue]
|
201
|
-
logger.trace "Appender thread: All appenders flushed"
|
202
|
-
else
|
203
|
-
logger.warn "Appender thread: Ignoring unknown command: #{message[:command]}"
|
204
|
-
end
|
205
|
-
end
|
206
|
-
end
|
207
|
-
rescue Exception => exception
|
208
|
-
# This block may be called after the file handles have been released by Ruby
|
209
|
-
begin
|
210
|
-
logger.error "Appender thread restarting due to exception", exception
|
211
|
-
rescue Exception
|
212
|
-
nil
|
213
|
-
end
|
214
|
-
retry
|
215
|
-
ensure
|
216
|
-
@@appender_thread = nil
|
217
|
-
# This block may be called after the file handles have been released by Ruby
|
218
|
-
begin
|
219
|
-
logger.trace "Appender thread has stopped"
|
220
|
-
rescue Exception
|
221
|
-
nil
|
222
|
-
end
|
223
|
-
end
|
152
|
+
@@appender_thread
|
224
153
|
end
|
225
154
|
# rubocop:enable BlockNesting, AssignmentInCondition, PerceivedComplexity, CyclomaticComplexity, AbcSize, LineLength, RescueException
|
226
|
-
|
227
|
-
# Close all appenders and flush any outstanding messages
|
228
|
-
def self.process_request(command)
|
229
|
-
return false unless appender_thread_active?
|
230
|
-
|
231
|
-
reply_queue = Queue.new
|
232
|
-
queue << { command: command, reply_queue: reply_queue }
|
233
|
-
reply_queue.pop
|
234
|
-
end
|
235
155
|
end
|
236
156
|
end
|
data/lib/sapience/rails.rb
CHANGED
@@ -1,15 +1,72 @@
|
|
1
|
+
require "sapience"
|
2
|
+
|
1
3
|
module Sapience
|
2
4
|
class Rails < ::Rails::Engine
|
5
|
+
|
6
|
+
# Replace Rails logger initializer
|
3
7
|
::Rails::Application::Bootstrap.initializers.delete_if { |i| i.name == :initialize_logger }
|
8
|
+
|
4
9
|
initializer :initialize_logger, group: :all do
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
Sapience.configure
|
11
|
+
::Rails.logger = Sapience[::Rails]
|
12
|
+
[:active_record, :action_controller, :action_mailer, :action_view].each do |name|
|
13
|
+
ActiveSupport.on_load(name) { include Sapience::Loggable }
|
14
|
+
end
|
15
|
+
ActiveSupport.on_load(:action_cable) { self.logger = Sapience["ActionCable"] }
|
16
|
+
end
|
17
|
+
|
18
|
+
# Before any initializers run, but after the gems have been loaded
|
19
|
+
config.before_initialize do
|
20
|
+
# Replace the Mongoid Logger
|
21
|
+
Mongoid.logger = Sapience[Mongoid] if defined?(Mongoid)
|
22
|
+
Moped.logger = Sapience[Moped] if defined?(Moped)
|
23
|
+
|
24
|
+
# Replace the Resque Logger
|
25
|
+
Resque.logger = Sapience[Resque] if defined?(Resque) && Resque.respond_to?(:logger)
|
26
|
+
|
27
|
+
# Replace the Sidekiq logger
|
28
|
+
Sidekiq::Logging.logger = Sapience[Sidekiq] if defined?(Sidekiq)
|
29
|
+
|
30
|
+
# Replace the Sidetiq logger
|
31
|
+
Sidetiq.logger = Sapience[Sidetiq] if defined?(Sidetiq)
|
32
|
+
|
33
|
+
# Replace the Raven logger
|
34
|
+
# Raven::Configuration.logger = Sapience[Raven::Configuration] if defined?(Raven::Configuration)
|
35
|
+
Raven.send(:include) { Sapience::Loggable }
|
36
|
+
|
37
|
+
# Replace the Sneakers logger
|
38
|
+
Sneakers.logger = Sapience[Sneakers] if defined?(Sneakers)
|
39
|
+
|
40
|
+
# Replace the Bugsnag logger
|
41
|
+
Bugsnag.configure { |config| config.logger = Sapience[Bugsnag] } if defined?(Bugsnag)
|
42
|
+
|
43
|
+
# Set the logger for concurrent-ruby
|
44
|
+
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
|
+
end
|
64
|
+
|
65
|
+
# Before any initializers run, but after the gems have been loaded
|
66
|
+
config.after_initialize do
|
67
|
+
# Replace the Bugsnag logger
|
68
|
+
Bugsnag.configure { |config| config.logger = Sapience[Bugsnag] } if defined?(Bugsnag)
|
13
69
|
end
|
70
|
+
|
14
71
|
end
|
15
72
|
end
|