timberio 1.0.0.beta1 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -2
- data/.rspec +2 -0
- data/.yardopts +6 -0
- data/Appraisals +4 -0
- data/Gemfile +9 -1
- data/LICENSE.md +15 -0
- data/README.md +170 -8
- data/circle.yml +11 -8
- data/lib/timber/config.rb +11 -18
- data/lib/timber/context.rb +9 -68
- data/lib/timber/contexts/custom.rb +27 -0
- data/lib/timber/contexts/http.rb +28 -0
- data/lib/timber/contexts/organization.rb +24 -22
- data/lib/timber/contexts/user.rb +25 -28
- data/lib/timber/contexts.rb +7 -20
- data/lib/timber/current_context.rb +26 -41
- data/lib/timber/event.rb +13 -0
- data/lib/timber/events/controller_call.rb +40 -0
- data/lib/timber/events/custom.rb +42 -0
- data/lib/timber/events/exception.rb +35 -0
- data/lib/timber/events/http_request.rb +50 -0
- data/lib/timber/events/http_response.rb +36 -0
- data/lib/timber/events/sql_query.rb +26 -0
- data/lib/timber/events/template_render.rb +26 -0
- data/lib/timber/events.rb +37 -0
- data/lib/timber/frameworks/rails.rb +3 -14
- data/lib/timber/frameworks.rb +8 -10
- data/lib/timber/log_devices/http.rb +72 -13
- data/lib/timber/log_devices.rb +8 -4
- data/lib/timber/log_entry.rb +59 -0
- data/lib/timber/logger.rb +136 -13
- data/lib/timber/probe.rb +6 -4
- data/lib/timber/probes/action_controller_log_subscriber/log_subscriber.rb +64 -0
- data/lib/timber/probes/action_controller_log_subscriber.rb +20 -0
- data/lib/timber/probes/action_dispatch_debug_exceptions.rb +59 -35
- data/lib/timber/probes/action_view_log_subscriber/log_subscriber.rb +62 -0
- data/lib/timber/probes/action_view_log_subscriber.rb +20 -0
- data/lib/timber/probes/active_record_log_subscriber/log_subscriber.rb +72 -0
- data/lib/timber/probes/active_record_log_subscriber.rb +20 -0
- data/lib/timber/probes/rack_http_context.rb +51 -0
- data/lib/timber/probes/rails_rack_logger.rb +76 -0
- data/lib/timber/probes.rb +13 -16
- data/lib/timber/util/active_support_log_subscriber.rb +33 -0
- data/lib/timber/util/hash.rb +14 -0
- data/lib/timber/util.rb +8 -0
- data/lib/timber/version.rb +2 -2
- data/lib/timber.rb +6 -11
- data/spec/spec_helper.rb +7 -4
- data/spec/support/rails.rb +9 -5
- data/spec/support/timber.rb +1 -20
- data/spec/timber/events_spec.rb +55 -0
- data/spec/timber/log_devices/http_spec.rb +62 -0
- data/spec/timber/logger_spec.rb +68 -0
- data/spec/timber/probes/action_controller_log_subscriber_spec.rb +70 -0
- data/spec/timber/probes/action_dispatch_debug_exceptions_spec.rb +24 -18
- data/spec/timber/probes/action_view_log_subscriber_spec.rb +61 -0
- data/spec/timber/probes/active_record_log_subscriber_spec.rb +49 -0
- data/spec/timber/probes/rack_http_context_spec.rb +54 -0
- data/spec/timber/probes/rails_rack_logger_spec.rb +46 -0
- data/timberio.gemspec +2 -0
- metadata +62 -123
- data/.codeclimate.yml +0 -34
- data/LICENSE +0 -38
- data/Rakefile +0 -4
- data/TODO +0 -4
- data/benchmark/README.md +0 -26
- data/benchmark/rails_request.rb +0 -68
- data/benchmark/support/rails.rb +0 -69
- data/docs/installation/rails_on_heroku.md +0 -31
- data/docs/installation/rails_over_http.md +0 -22
- data/gemfiles/rails_3.0.X.gemfile +0 -25
- data/gemfiles/rails_3.1.X.gemfile +0 -25
- data/gemfiles/rails_3.2.X.gemfile +0 -25
- data/gemfiles/rails_4.0.X.gemfile +0 -26
- data/gemfiles/rails_4.1.X.gemfile +0 -26
- data/gemfiles/rails_4.2.X.gemfile +0 -26
- data/gemfiles/rails_5.0.X.gemfile +0 -26
- data/gemfiles/rails_edge.gemfile +0 -27
- data/lib/timber/api_settings.rb +0 -17
- data/lib/timber/bootstrap.rb +0 -45
- data/lib/timber/context_snapshot.rb +0 -64
- data/lib/timber/contexts/dynamic_values.rb +0 -59
- data/lib/timber/contexts/exception.rb +0 -40
- data/lib/timber/contexts/http_request.rb +0 -22
- data/lib/timber/contexts/http_requests/action_controller_specific.rb +0 -48
- data/lib/timber/contexts/http_requests/rack/params.rb +0 -26
- data/lib/timber/contexts/http_requests/rack.rb +0 -105
- data/lib/timber/contexts/http_response.rb +0 -19
- data/lib/timber/contexts/http_responses/action_controller.rb +0 -76
- data/lib/timber/contexts/logger.rb +0 -33
- data/lib/timber/contexts/organizations/action_controller.rb +0 -34
- data/lib/timber/contexts/server.rb +0 -21
- data/lib/timber/contexts/servers/heroku_specific.rb +0 -48
- data/lib/timber/contexts/sql_queries/active_record.rb +0 -30
- data/lib/timber/contexts/sql_queries/active_record_specific/binds.rb +0 -37
- data/lib/timber/contexts/sql_queries/active_record_specific.rb +0 -59
- data/lib/timber/contexts/sql_query.rb +0 -18
- data/lib/timber/contexts/template_render.rb +0 -17
- data/lib/timber/contexts/template_renders/action_view.rb +0 -29
- data/lib/timber/contexts/template_renders/action_view_specific.rb +0 -51
- data/lib/timber/contexts/users/action_controller.rb +0 -34
- data/lib/timber/current_line_indexes.rb +0 -35
- data/lib/timber/internal_logger.rb +0 -35
- data/lib/timber/log_device.rb +0 -40
- data/lib/timber/log_devices/heroku_logplex/hybrid_formatter.rb +0 -14
- data/lib/timber/log_devices/heroku_logplex.rb +0 -14
- data/lib/timber/log_devices/http/log_pile.rb +0 -86
- data/lib/timber/log_devices/http/log_truck/delivery.rb +0 -116
- data/lib/timber/log_devices/http/log_truck.rb +0 -87
- data/lib/timber/log_devices/io/formatter.rb +0 -46
- data/lib/timber/log_devices/io/hybrid_formatter.rb +0 -41
- data/lib/timber/log_devices/io/hybrid_hidden_formatter.rb +0 -36
- data/lib/timber/log_devices/io/json_formatter.rb +0 -11
- data/lib/timber/log_devices/io/logfmt_formatter.rb +0 -11
- data/lib/timber/log_devices/io.rb +0 -41
- data/lib/timber/log_line.rb +0 -33
- data/lib/timber/macros/compactor.rb +0 -16
- data/lib/timber/macros/date_formatter.rb +0 -9
- data/lib/timber/macros/deep_merger.rb +0 -11
- data/lib/timber/macros/logfmt_encoder.rb +0 -77
- data/lib/timber/macros.rb +0 -4
- data/lib/timber/patterns/delegated_singleton.rb +0 -21
- data/lib/timber/patterns/to_json.rb +0 -22
- data/lib/timber/patterns/to_logfmt.rb +0 -9
- data/lib/timber/patterns.rb +0 -3
- data/lib/timber/probes/action_controller_base.rb +0 -31
- data/lib/timber/probes/active_support_log_subscriber/action_controller.rb +0 -15
- data/lib/timber/probes/active_support_log_subscriber/action_view.rb +0 -26
- data/lib/timber/probes/active_support_log_subscriber/active_record.rb +0 -13
- data/lib/timber/probes/active_support_log_subscriber.rb +0 -62
- data/lib/timber/probes/heroku.rb +0 -30
- data/lib/timber/probes/logger.rb +0 -31
- data/lib/timber/probes/rack.rb +0 -36
- data/lib/timber/probes/server.rb +0 -18
- data/spec/timber/bootstrap_spec.rb +0 -31
- data/spec/timber/context_snapshot_spec.rb +0 -10
- data/spec/timber/context_spec.rb +0 -4
- data/spec/timber/contexts/exception_spec.rb +0 -34
- data/spec/timber/contexts/organizations/action_controller_spec.rb +0 -49
- data/spec/timber/contexts/users/action_controller_spec.rb +0 -65
- data/spec/timber/current_line_indexes_spec.rb +0 -40
- data/spec/timber/frameworks/rails_spec.rb +0 -9
- data/spec/timber/log_devices/heroku_logplex_spec.rb +0 -45
- data/spec/timber/log_devices/http/log_truck/delivery_spec.rb +0 -66
- data/spec/timber/log_devices/http/log_truck_spec.rb +0 -65
- data/spec/timber/log_devices/io/hybrid_hidden_formatter_spec.rb +0 -28
- data/spec/timber/log_line_spec.rb +0 -49
- data/spec/timber/macros/compactor_spec.rb +0 -19
- data/spec/timber/macros/logfmt_encoder_spec.rb +0 -89
- data/spec/timber/patterns/to_json_spec.rb +0 -40
- data/spec/timber/probes/action_controller_base_spec.rb +0 -43
- data/spec/timber/probes/action_controller_log_subscriber/action_controller_spec.rb +0 -35
- data/spec/timber/probes/action_controller_log_subscriber/action_view_spec.rb +0 -44
- data/spec/timber/probes/action_controller_log_subscriber/active_record_spec.rb +0 -26
- data/spec/timber/probes/logger_spec.rb +0 -20
- data/spec/timber/probes/rack_spec.rb +0 -26
@@ -1,77 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Macros
|
3
|
-
# Encodes a hash into a simple logfmt string.
|
4
|
-
#
|
5
|
-
# A couple of important points:
|
6
|
-
#
|
7
|
-
# 1. This module is designed to be fast, as it is executed inline with
|
8
|
-
# each log line.
|
9
|
-
# 2. It makes assumptions about the hash structure, and is designed
|
10
|
-
# specifically for Timber. We can reduce the edge cases and improve
|
11
|
-
# performance drastically.
|
12
|
-
class LogfmtEncoder
|
13
|
-
ARRAY_DELIMITER = ",".freeze
|
14
|
-
ARRAY_END = "]".freeze
|
15
|
-
ARRAY_START = "[".freeze
|
16
|
-
ESCAPE = "\\".freeze
|
17
|
-
KEY_DELIMITER = ".".freeze
|
18
|
-
KEY_VALUE_DELIMITER = "=".freeze
|
19
|
-
PAIR_DELIMITER = " ".freeze
|
20
|
-
STRING_WRAPPER = "\"".freeze
|
21
|
-
SPECIAL_KEY_CHARACTERS = [KEY_DELIMITER, PAIR_DELIMITER].freeze
|
22
|
-
SPECIAL_VALUE_CHARACTERS = [ARRAY_DELIMITER, ARRAY_END, ARRAY_START, ESCAPE, PAIR_DELIMITER, STRING_WRAPPER].freeze
|
23
|
-
|
24
|
-
def self.encode(hash, ancestors = [])
|
25
|
-
if !hash.is_a?(Hash)
|
26
|
-
raise ArgumentError.new("hash must be a Hash")
|
27
|
-
end
|
28
|
-
items = hash.collect do |key, value|
|
29
|
-
keys = ancestors + [key]
|
30
|
-
if value.is_a?(Hash)
|
31
|
-
encode(value, keys)
|
32
|
-
else
|
33
|
-
"#{encode_keys(keys)}#{KEY_VALUE_DELIMITER}#{encode_value(value)}"
|
34
|
-
end
|
35
|
-
end.flatten
|
36
|
-
join(*items)
|
37
|
-
end
|
38
|
-
|
39
|
-
def self.join(*items)
|
40
|
-
items.join(PAIR_DELIMITER)
|
41
|
-
end
|
42
|
-
|
43
|
-
private
|
44
|
-
def self.encode_keys(keys)
|
45
|
-
keys.collect { |key| encode_key(key) }.join(KEY_DELIMITER)
|
46
|
-
end
|
47
|
-
|
48
|
-
def self.encode_key(key)
|
49
|
-
key = key.to_s
|
50
|
-
if SPECIAL_KEY_CHARACTERS.any? { |c| key.include?(c) }
|
51
|
-
escape(key)
|
52
|
-
else
|
53
|
-
key
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
def self.encode_value(value)
|
58
|
-
if value.is_a?(Array)
|
59
|
-
values = value.collect { |v| encode_value(v) }.join(ARRAY_DELIMITER)
|
60
|
-
"#{ARRAY_START}#{values}#{ARRAY_END}"
|
61
|
-
elsif value.is_a?(String) && SPECIAL_VALUE_CHARACTERS.any? { |c| value.include?(c) }
|
62
|
-
escape(value)
|
63
|
-
else
|
64
|
-
value
|
65
|
-
end
|
66
|
-
end
|
67
|
-
|
68
|
-
def self.escape(value)
|
69
|
-
# Simple gsub that is better for performance, we do not need to handle
|
70
|
-
# all of the edgecases that to_json handled. #to_json is also much slower.
|
71
|
-
new_value = value.gsub(STRING_WRAPPER, "#{ESCAPE}#{STRING_WRAPPER}")
|
72
|
-
new_value.gsub!(ESCAPE, "#{ESCAPE}#{ESCAPE}")
|
73
|
-
"#{STRING_WRAPPER}#{new_value}#{STRING_WRAPPER}"
|
74
|
-
end
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
data/lib/timber/macros.rb
DELETED
@@ -1,21 +0,0 @@
|
|
1
|
-
require "singleton"
|
2
|
-
|
3
|
-
module Timber
|
4
|
-
module Patterns
|
5
|
-
module DelegatedSingleton
|
6
|
-
def self.included(klass)
|
7
|
-
klass.class_eval do
|
8
|
-
extend ClassMethods
|
9
|
-
include Singleton
|
10
|
-
end
|
11
|
-
end
|
12
|
-
|
13
|
-
module ClassMethods
|
14
|
-
private
|
15
|
-
def method_missing(name, *args, &block)
|
16
|
-
instance.send(name, *args, &block)
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
@@ -1,22 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Patterns
|
3
|
-
# Module to fall inline with Rail's core object crazy changes.
|
4
|
-
# If Rails is present, it will play nice. If not, it will work just fine.
|
5
|
-
module ToJSON
|
6
|
-
# We explicitly do not do anything with the arguments as we do not need them.
|
7
|
-
# We avoid the unneccssary complexity.
|
8
|
-
def as_json(*_args)
|
9
|
-
@as_json ||= Macros::Compactor.compact(json_payload).freeze
|
10
|
-
end
|
11
|
-
|
12
|
-
def to_json(*_args)
|
13
|
-
@to_json ||= as_json.to_json.freeze
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
def json_payload
|
18
|
-
raise NotImplementedError.new("#json_payload is not implemented for #{self.class}")
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
data/lib/timber/patterns.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Probes
|
3
|
-
# Wraps process_action so that we get *anu* logs written within the controller.
|
4
|
-
# This is superior to using process_action in ActionController::LogSubscriber.
|
5
|
-
class ActionControllerBase < Probe
|
6
|
-
module InstanceMethods
|
7
|
-
def process(*args)
|
8
|
-
request_context = Contexts::HTTPRequests::ActionControllerSpecific.new(self)
|
9
|
-
organization_context = Contexts::Organizations::ActionController.new(self)
|
10
|
-
user_context = Contexts::Users::ActionController.new(self)
|
11
|
-
response_context = Contexts::HTTPResponses::ActionController.new(self)
|
12
|
-
# The order is relevant here, request_context is higher in the hierarchy
|
13
|
-
CurrentContext.add(request_context, organization_context, user_context, response_context) do
|
14
|
-
super
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
|
19
|
-
def initialize
|
20
|
-
require "action_controller"
|
21
|
-
rescue LoadError => e
|
22
|
-
raise RequirementNotMetError.new(e.message)
|
23
|
-
end
|
24
|
-
|
25
|
-
def insert!
|
26
|
-
return true if ::ActionController::Base.include?(InstanceMethods)
|
27
|
-
::ActionController::Base.send(:include, InstanceMethods)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
@@ -1,15 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Probes
|
3
|
-
class ActiveSupportLogSubscriber < Probe
|
4
|
-
module ActionController
|
5
|
-
def self.process_action(_log_subscriber, event, &_block)
|
6
|
-
context = CurrentContext.get(Contexts::HTTPResponses::ActionController)
|
7
|
-
if context
|
8
|
-
context.event = event
|
9
|
-
end
|
10
|
-
yield
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
@@ -1,26 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Probes
|
3
|
-
class ActiveSupportLogSubscriber < Probe
|
4
|
-
class ActionView
|
5
|
-
def self.render_collection(_log_subscriber, event, &_block)
|
6
|
-
wrap(event) { yield }
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.render_partial(_log_subscriber, event, &_block)
|
10
|
-
wrap(event) { yield }
|
11
|
-
end
|
12
|
-
|
13
|
-
def self.render_template(_log_subscriber, event, &_block)
|
14
|
-
wrap(event) { yield }
|
15
|
-
end
|
16
|
-
|
17
|
-
private
|
18
|
-
def self.wrap(event, &_block)
|
19
|
-
context1 = Contexts::TemplateRenders::ActionView.new(event)
|
20
|
-
context2 = Contexts::TemplateRenders::ActionViewSpecific.new(event)
|
21
|
-
CurrentContext.add(context1, context2) { yield }
|
22
|
-
end
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
@@ -1,13 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Probes
|
3
|
-
class ActiveSupportLogSubscriber < Probe
|
4
|
-
module ActiveRecord
|
5
|
-
def self.sql(log_subscriber, event, &_block)
|
6
|
-
context1 = Contexts::SQLQueries::ActiveRecord.new(log_subscriber, event)
|
7
|
-
context2 = Contexts::SQLQueries::ActiveRecordSpecific.new(log_subscriber, event)
|
8
|
-
CurrentContext.add(context1, context2) { yield }
|
9
|
-
end
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
@@ -1,62 +0,0 @@
|
|
1
|
-
require "timber/probes/active_support_log_subscriber/action_controller"
|
2
|
-
require "timber/probes/active_support_log_subscriber/action_view"
|
3
|
-
require "timber/probes/active_support_log_subscriber/active_record"
|
4
|
-
|
5
|
-
module Timber
|
6
|
-
module Probes
|
7
|
-
# We want to wrap every log subscriber. Think about something like
|
8
|
-
# lograge. We want to add context to those logs as well, not just
|
9
|
-
# the internal rails log subscribers.
|
10
|
-
class ActiveSupportLogSubscriber < Probe
|
11
|
-
module ClassMethods
|
12
|
-
def self.included(klass)
|
13
|
-
klass.class_eval do
|
14
|
-
alias_method :_timber_old_send, :send
|
15
|
-
|
16
|
-
# Override send since the #finish method uses that to send the event.
|
17
|
-
# This allows us to wrap the actual method.
|
18
|
-
def send(method_name, *args, &block)
|
19
|
-
if args.first.is_a?(ActiveSupport::Notifications::Event)
|
20
|
-
ActiveSupportLogSubscriber.wrap(self, args.first) do
|
21
|
-
_timber_old_send(method_name, *args, &block)
|
22
|
-
end
|
23
|
-
else
|
24
|
-
_timber_old_send(method_name, *args, &block)
|
25
|
-
end
|
26
|
-
end
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class << self
|
32
|
-
WRAPPER_MAP = {
|
33
|
-
"action_controller" => ActionController,
|
34
|
-
"action_view" => ActionView,
|
35
|
-
"active_record" => ActiveRecord
|
36
|
-
}.freeze
|
37
|
-
EVENT_DELIMITER = ".".freeze
|
38
|
-
|
39
|
-
def wrap(log_subscriber, event, &_block)
|
40
|
-
event_name, namespace = event.name.split(EVENT_DELIMITER)
|
41
|
-
wrapper = WRAPPER_MAP[namespace]
|
42
|
-
if wrapper && wrapper.respond_to?(event_name)
|
43
|
-
wrapper.send(event_name, log_subscriber, event) { yield }
|
44
|
-
else
|
45
|
-
yield
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def initialize
|
51
|
-
require "active_support/log_subscriber"
|
52
|
-
rescue LoadError => e
|
53
|
-
raise RequirementNotMetError.new(e.message)
|
54
|
-
end
|
55
|
-
|
56
|
-
def insert!
|
57
|
-
return true if ::ActiveSupport::LogSubscriber.include?(ClassMethods)
|
58
|
-
::ActiveSupport::LogSubscriber.send(:include, ClassMethods)
|
59
|
-
end
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
data/lib/timber/probes/heroku.rb
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Probes
|
3
|
-
class Heroku < Probe
|
4
|
-
class << self
|
5
|
-
attr_accessor :inserted
|
6
|
-
end
|
7
|
-
|
8
|
-
def initialize
|
9
|
-
if dyno.nil?
|
10
|
-
raise RequirementNotMetError.new("The DYNO environment variable is not set. " +
|
11
|
-
"Not in the Heroku environment.")
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def insert!
|
16
|
-
return true if self.class.inserted == true
|
17
|
-
context = Contexts::Servers::HerokuSpecific.new(dyno)
|
18
|
-
# Note we don't use a block here, this is because
|
19
|
-
# the context is persistent.
|
20
|
-
CurrentContext.add(context)
|
21
|
-
self.class.inserted = true
|
22
|
-
end
|
23
|
-
|
24
|
-
private
|
25
|
-
def dyno
|
26
|
-
ENV['DYNO']
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
data/lib/timber/probes/logger.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require "logger"
|
2
|
-
|
3
|
-
module Timber
|
4
|
-
module Probes
|
5
|
-
class Logger < Probe
|
6
|
-
module InstanceMethods
|
7
|
-
def self.included(klass)
|
8
|
-
klass.class_eval do
|
9
|
-
alias_method :_timber_old_add, :add
|
10
|
-
|
11
|
-
def add(level, *args, &block)
|
12
|
-
if self == Config.logger
|
13
|
-
_timber_old_add(level, *args, &block)
|
14
|
-
else
|
15
|
-
context = Contexts::Logger.new(level, progname)
|
16
|
-
CurrentContext.add(context) do
|
17
|
-
_timber_old_add(level, *args, &block)
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
23
|
-
end
|
24
|
-
|
25
|
-
def insert!
|
26
|
-
return true if ::Logger.include?(InstanceMethods)
|
27
|
-
::Logger.send(:include, InstanceMethods)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/lib/timber/probes/rack.rb
DELETED
@@ -1,36 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Probes
|
3
|
-
class Rack < Probe
|
4
|
-
class Middleware
|
5
|
-
def initialize(app)
|
6
|
-
@app = app
|
7
|
-
end
|
8
|
-
|
9
|
-
def call(env)
|
10
|
-
context = Contexts::HTTPRequests::Rack.new(env)
|
11
|
-
CurrentContext.add(context) do
|
12
|
-
@app.call(env)
|
13
|
-
end
|
14
|
-
end
|
15
|
-
end
|
16
|
-
|
17
|
-
attr_reader :middleware, :insert_before
|
18
|
-
|
19
|
-
def initialize(middleware, insert_before)
|
20
|
-
if middleware.nil?
|
21
|
-
raise RequirementNotMetError.new("The middleware class attribute is not set. " +
|
22
|
-
"We need a middleware to insert the probe.")
|
23
|
-
end
|
24
|
-
@middleware = middleware
|
25
|
-
@insert_before = insert_before
|
26
|
-
end
|
27
|
-
|
28
|
-
def insert!
|
29
|
-
return true if middleware.instance_variable_get(:"@_timber_inserted") == true
|
30
|
-
# Rails uses a proxy :/
|
31
|
-
middleware.instance_variable_set(:"@_timber_inserted", true)
|
32
|
-
middleware.insert_before insert_before, Middleware
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
end
|
data/lib/timber/probes/server.rb
DELETED
@@ -1,18 +0,0 @@
|
|
1
|
-
module Timber
|
2
|
-
module Probes
|
3
|
-
class Server < Probe
|
4
|
-
class << self
|
5
|
-
attr_accessor :inserted
|
6
|
-
end
|
7
|
-
|
8
|
-
def insert!
|
9
|
-
return true if self.class.inserted == true
|
10
|
-
context = Contexts::Server.new
|
11
|
-
# Note we don't use a block here, this is because
|
12
|
-
# the context is persistent.
|
13
|
-
CurrentContext.add(context)
|
14
|
-
self.class.inserted = true
|
15
|
-
end
|
16
|
-
end
|
17
|
-
end
|
18
|
-
end
|
@@ -1,31 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Timber::Bootstrap do
|
4
|
-
describe ".bootstrap!" do
|
5
|
-
let(:middleware) { Rack::Builder.new }
|
6
|
-
let(:insert_before) { ::Rails::Rack::Logger }
|
7
|
-
|
8
|
-
def self.it_should_not_bootstrap
|
9
|
-
it "should not bootstrap" do
|
10
|
-
expect(Timber::Probes).to_not receive(:insert!)
|
11
|
-
expect(described_class.bootstrap!(middleware, insert_before)).to be false
|
12
|
-
end
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.it_should_bootstrap
|
16
|
-
it "should bootstrap" do
|
17
|
-
expect(Timber::Probes).to receive(:insert!).once
|
18
|
-
expect(described_class.bootstrap!(middleware, insert_before)).to be true
|
19
|
-
end
|
20
|
-
end
|
21
|
-
|
22
|
-
it_should_bootstrap
|
23
|
-
|
24
|
-
context "disabled" do
|
25
|
-
before(:each) { Timber::Config.enabled = false }
|
26
|
-
after(:each) { Timber::Config.enabled = true }
|
27
|
-
|
28
|
-
it_should_not_bootstrap
|
29
|
-
end
|
30
|
-
end
|
31
|
-
end
|
data/spec/timber/context_spec.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Timber::Contexts::Exception do
|
4
|
-
let(:exception) do
|
5
|
-
begin
|
6
|
-
raise StandardError.new("this is a message")
|
7
|
-
rescue Exception => e
|
8
|
-
e
|
9
|
-
end
|
10
|
-
end
|
11
|
-
let(:context) { described_class.new(exception) }
|
12
|
-
|
13
|
-
describe ".as_json" do
|
14
|
-
subject { context.as_json }
|
15
|
-
its([:exception, :backtrace]) { should_not be_nil }
|
16
|
-
its([:exception, :name]) { should eq("StandardError") }
|
17
|
-
its([:exception, :message]) { should eq("this is a message") }
|
18
|
-
end
|
19
|
-
|
20
|
-
describe ".backtrace" do
|
21
|
-
subject { context.backtrace }
|
22
|
-
its(:size) { should eq(5) }
|
23
|
-
end
|
24
|
-
|
25
|
-
describe ".name" do
|
26
|
-
subject { context.name }
|
27
|
-
it { should eq("StandardError") }
|
28
|
-
end
|
29
|
-
|
30
|
-
describe ".message" do
|
31
|
-
subject { context.message }
|
32
|
-
it { should eq("this is a message") }
|
33
|
-
end
|
34
|
-
end
|
@@ -1,49 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Timber::Contexts::Organizations::ActionController do
|
4
|
-
around(:each) do |example|
|
5
|
-
class PagesController < ActionController::Base
|
6
|
-
layout nil
|
7
|
-
|
8
|
-
def index
|
9
|
-
render json: {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def method_for_action(action_name)
|
13
|
-
action_name
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
def current_organization
|
18
|
-
# I want this to execute a query and test logging that query
|
19
|
-
Organization.first
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
example.run
|
24
|
-
|
25
|
-
Object.send(:remove_const, :PagesController)
|
26
|
-
end
|
27
|
-
|
28
|
-
let(:context) { described_class.new(PagesController.new) }
|
29
|
-
|
30
|
-
describe "#name" do
|
31
|
-
subject { context.name }
|
32
|
-
it { should be_nil }
|
33
|
-
|
34
|
-
context "with an organization" do
|
35
|
-
before(:each) { Organization.create!(name: "Timber") }
|
36
|
-
it { should eq("Timber") }
|
37
|
-
|
38
|
-
context "with an organization context" do
|
39
|
-
around(:each) do |example|
|
40
|
-
Timber::CurrentContext.add(context) do
|
41
|
-
example.run
|
42
|
-
end
|
43
|
-
end
|
44
|
-
|
45
|
-
it { should eq("Timber") }
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
@@ -1,65 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Timber::Contexts::Users::ActionController do
|
4
|
-
around(:each) do |example|
|
5
|
-
class PagesController < ActionController::Base
|
6
|
-
layout nil
|
7
|
-
|
8
|
-
def index
|
9
|
-
render json: {}
|
10
|
-
end
|
11
|
-
|
12
|
-
def method_for_action(action_name)
|
13
|
-
action_name
|
14
|
-
end
|
15
|
-
|
16
|
-
private
|
17
|
-
def current_user
|
18
|
-
# I want this to execute a query and test logging that query
|
19
|
-
@user ||= User.first
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
example.run
|
24
|
-
|
25
|
-
Object.send(:remove_const, :PagesController)
|
26
|
-
|
27
|
-
Timber::Probes::ActiveSupportLogSubscriber.insert!
|
28
|
-
end
|
29
|
-
|
30
|
-
let(:context) { described_class.new(PagesController.new) }
|
31
|
-
|
32
|
-
describe "#email" do
|
33
|
-
subject { context.email }
|
34
|
-
it { should be_nil }
|
35
|
-
|
36
|
-
context "with a user" do
|
37
|
-
before(:each) { User.create!(email: "a@a.com") }
|
38
|
-
it { should eq("a@a.com") }
|
39
|
-
|
40
|
-
context "with a user context" do
|
41
|
-
around(:each) do |example|
|
42
|
-
Timber::CurrentContext.add(context) do
|
43
|
-
example.run
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
it { should eq("a@a.com") }
|
48
|
-
|
49
|
-
context "with a debug log level" do
|
50
|
-
around(:each) do |example|
|
51
|
-
old_level = ::Rails.logger.level
|
52
|
-
::Rails.logger.level = ::Logger::DEBUG
|
53
|
-
example.run
|
54
|
-
::Rails.logger.level = old_level
|
55
|
-
end
|
56
|
-
|
57
|
-
# If the user object is not cached, it will create an infinite loop.
|
58
|
-
# This is because getting the user executes a query, which in turn creates
|
59
|
-
# logs, with tries to grab the user again, etc.
|
60
|
-
it { should eq("a@a.com") }
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
65
|
-
end
|
@@ -1,40 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Timber::CurrentLineIndexes do
|
4
|
-
def add_log_line
|
5
|
-
Timber::LogLine.new("test")
|
6
|
-
end
|
7
|
-
|
8
|
-
describe "#log_line_added" do
|
9
|
-
it "only includes the valid stack" do
|
10
|
-
expect(Timber::CurrentContext).to receive(:valid_stack).twice.and_return([])
|
11
|
-
add_log_line
|
12
|
-
end
|
13
|
-
|
14
|
-
context "with a context" do
|
15
|
-
let(:heroku_context) { Timber::Contexts::Servers::HerokuSpecific.new("web.1")}
|
16
|
-
|
17
|
-
around(:each) do |example|
|
18
|
-
Timber::CurrentContext.add(heroku_context) do
|
19
|
-
example.run
|
20
|
-
end
|
21
|
-
end
|
22
|
-
|
23
|
-
context "with a log line" do
|
24
|
-
before(:each) { add_log_line }
|
25
|
-
|
26
|
-
it "sets the context to 0" do
|
27
|
-
expect(described_class.indexes[heroku_context]).to eq(0)
|
28
|
-
end
|
29
|
-
|
30
|
-
context "with an additional log line" do
|
31
|
-
before(:each) { add_log_line }
|
32
|
-
|
33
|
-
it "increments properly" do
|
34
|
-
expect(described_class.indexes[heroku_context]).to eq(1)
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|