timber 1.1.14 → 2.0.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.
Files changed (106) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +4 -2
  3. data/.travis.yml +47 -0
  4. data/Gemfile +1 -28
  5. data/README.md +83 -298
  6. data/bin/timber +13 -0
  7. data/gemfiles/rails-3.0.gemfile +5 -0
  8. data/gemfiles/rails-3.1.gemfile +5 -0
  9. data/gemfiles/rails-3.2.gemfile +5 -0
  10. data/gemfiles/rails-4.0.gemfile +9 -0
  11. data/gemfiles/rails-4.1.gemfile +9 -0
  12. data/gemfiles/rails-4.2.gemfile +9 -0
  13. data/gemfiles/rails-5.0.gemfile +9 -0
  14. data/gemfiles/rails-edge.gemfile +7 -0
  15. data/lib/timber.rb +7 -7
  16. data/lib/timber/cli.rb +72 -0
  17. data/lib/timber/cli/api.rb +104 -0
  18. data/lib/timber/cli/application.rb +28 -0
  19. data/lib/timber/cli/install.rb +186 -0
  20. data/lib/timber/cli/io_helper.rb +58 -0
  21. data/lib/timber/cli/messages.rb +170 -0
  22. data/lib/timber/config.rb +47 -6
  23. data/lib/timber/contexts/http.rb +2 -2
  24. data/lib/timber/current_context.rb +1 -1
  25. data/lib/timber/event.rb +8 -0
  26. data/lib/timber/events.rb +2 -0
  27. data/lib/timber/events/controller_call.rb +12 -3
  28. data/lib/timber/events/exception.rb +4 -3
  29. data/lib/timber/events/http_client_request.rb +61 -0
  30. data/lib/timber/events/http_client_response.rb +47 -0
  31. data/lib/timber/events/http_server_request.rb +15 -23
  32. data/lib/timber/events/http_server_response.rb +9 -9
  33. data/lib/timber/events/sql_query.rb +2 -2
  34. data/lib/timber/events/template_render.rb +2 -2
  35. data/lib/timber/frameworks/rails.rb +31 -6
  36. data/lib/timber/integrations.rb +22 -0
  37. data/lib/timber/integrations/action_controller/log_subscriber.rb +25 -0
  38. data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +40 -0
  39. data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +51 -0
  40. data/lib/timber/integrations/action_view/log_subscriber.rb +25 -0
  41. data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +73 -0
  42. data/lib/timber/integrations/active_record/log_subscriber.rb +25 -0
  43. data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +39 -0
  44. data/lib/timber/integrations/active_support/tagged_logging.rb +71 -0
  45. data/lib/timber/integrations/rack.rb +16 -0
  46. data/lib/timber/integrations/rack/exception_event.rb +28 -0
  47. data/lib/timber/integrations/rack/http_context.rb +25 -0
  48. data/lib/timber/integrations/rack/http_events.rb +46 -0
  49. data/lib/timber/integrations/rack/user_context.rb +59 -0
  50. data/lib/timber/integrations/rails/rack_logger.rb +49 -0
  51. data/lib/timber/integrator.rb +24 -0
  52. data/lib/timber/log_devices/http.rb +14 -21
  53. data/lib/timber/log_entry.rb +1 -1
  54. data/lib/timber/logger.rb +38 -12
  55. data/lib/timber/overrides.rb +9 -0
  56. data/lib/timber/overrides/lograge.rb +14 -0
  57. data/lib/timber/overrides/rails_server.rb +10 -0
  58. data/lib/timber/util.rb +2 -0
  59. data/lib/timber/util/active_support_log_subscriber.rb +13 -9
  60. data/lib/timber/util/http_event.rb +54 -0
  61. data/lib/timber/util/request.rb +44 -0
  62. data/lib/timber/version.rb +1 -1
  63. data/spec/README.md +5 -9
  64. data/spec/spec_helper.rb +1 -4
  65. data/spec/support/action_controller.rb +7 -3
  66. data/spec/support/active_record.rb +23 -19
  67. data/spec/support/rails.rb +56 -32
  68. data/spec/support/timber.rb +2 -3
  69. data/spec/support/webmock.rb +1 -0
  70. data/spec/timber/integrations/action_controller/log_subscriber_spec.rb +55 -0
  71. data/spec/timber/integrations/action_dispatch/debug_exceptions_spec.rb +53 -0
  72. data/spec/timber/integrations/action_view/log_subscriber_spec.rb +115 -0
  73. data/spec/timber/integrations/active_record/log_subscriber_spec.rb +46 -0
  74. data/spec/timber/integrations/rack/http_context_spec.rb +60 -0
  75. data/spec/timber/integrations/rails/rack_logger_spec.rb +58 -0
  76. data/spec/timber/logger_spec.rb +45 -9
  77. data/timber.gemspec +29 -3
  78. metadata +143 -46
  79. data/Appraisals +0 -41
  80. data/circle.yml +0 -33
  81. data/lib/timber/overrides/logger_add.rb +0 -38
  82. data/lib/timber/probe.rb +0 -23
  83. data/lib/timber/probes.rb +0 -23
  84. data/lib/timber/probes/action_controller_log_subscriber.rb +0 -20
  85. data/lib/timber/probes/action_controller_log_subscriber/log_subscriber.rb +0 -64
  86. data/lib/timber/probes/action_controller_user_context.rb +0 -52
  87. data/lib/timber/probes/action_dispatch_debug_exceptions.rb +0 -80
  88. data/lib/timber/probes/action_view_log_subscriber.rb +0 -20
  89. data/lib/timber/probes/action_view_log_subscriber/log_subscriber.rb +0 -69
  90. data/lib/timber/probes/active_record_log_subscriber.rb +0 -20
  91. data/lib/timber/probes/active_record_log_subscriber/log_subscriber.rb +0 -31
  92. data/lib/timber/probes/active_support_tagged_logging.rb +0 -63
  93. data/lib/timber/probes/rails_rack_logger.rb +0 -77
  94. data/lib/timber/rack_middlewares.rb +0 -12
  95. data/lib/timber/rack_middlewares/http_context.rb +0 -30
  96. data/spec/support/action_view.rb +0 -4
  97. data/spec/support/coveralls.rb +0 -2
  98. data/spec/support/simplecov.rb +0 -9
  99. data/spec/timber/overrides/logger_add_spec.rb +0 -26
  100. data/spec/timber/probes/action_controller_log_subscriber_spec.rb +0 -65
  101. data/spec/timber/probes/action_controller_user_context_spec.rb +0 -53
  102. data/spec/timber/probes/action_dispatch_debug_exceptions_spec.rb +0 -48
  103. data/spec/timber/probes/action_view_log_subscriber_spec.rb +0 -107
  104. data/spec/timber/probes/active_record_log_subscriber_spec.rb +0 -47
  105. data/spec/timber/probes/rails_rack_logger_spec.rb +0 -46
  106. data/spec/timber/rack_middlewares/http_context_spec.rb +0 -47
@@ -1,23 +0,0 @@
1
- module Timber
2
- # Base class for `Timber::Probes::*`.
3
- # @private
4
- class Probe
5
- class RequirementNotMetError < StandardError; end
6
-
7
- class << self
8
- def insert!(*args)
9
- new(*args).insert!
10
- Config.instance.logger.debug("Inserted probe #{name}")
11
- true
12
- # RequirementUnsatisfiedError is the only silent failure we support
13
- rescue RequirementNotMetError => e
14
- Config.instance.logger.debug("Failed inserting probe #{name}: #{e.message}")
15
- false
16
- end
17
- end
18
-
19
- def insert!
20
- raise NotImplementedError.new
21
- end
22
- end
23
- end
@@ -1,23 +0,0 @@
1
- require "timber/probes/action_controller_log_subscriber"
2
- require "timber/probes/action_controller_user_context"
3
- require "timber/probes/action_dispatch_debug_exceptions"
4
- require "timber/probes/action_view_log_subscriber"
5
- require "timber/probes/active_record_log_subscriber"
6
- require "timber/probes/active_support_tagged_logging"
7
- require "timber/probes/rails_rack_logger"
8
-
9
- module Timber
10
- # Namespace for all probes.
11
- # @private
12
- module Probes
13
- def self.insert!
14
- ActionControllerLogSubscriber.insert!
15
- ActionControllerUserContext.insert!
16
- ActionDispatchDebugExceptions.insert!
17
- ActionViewLogSubscriber.insert!
18
- ActiveRecordLogSubscriber.insert!
19
- ActiveSupportTaggedLogging.insert!
20
- RailsRackLogger.insert!
21
- end
22
- end
23
- end
@@ -1,20 +0,0 @@
1
- module Timber
2
- module Probes
3
- # Responsible for automatically tracking controller call and http response events
4
- # for applications that use `ActionController`.
5
- class ActionControllerLogSubscriber < Probe
6
- def initialize
7
- require "action_controller/log_subscriber"
8
- require "timber/probes/action_controller_log_subscriber/log_subscriber"
9
- rescue LoadError => e
10
- raise RequirementNotMetError.new(e.message)
11
- end
12
-
13
- def insert!
14
- return true if Util::ActiveSupportLogSubscriber.subscribed?(:action_controller, LogSubscriber)
15
- Util::ActiveSupportLogSubscriber.unsubscribe(:action_controller, ::ActionController::LogSubscriber)
16
- LogSubscriber.attach_to(:action_controller)
17
- end
18
- end
19
- end
20
- end
@@ -1,64 +0,0 @@
1
- module Timber
2
- module Probes
3
- class ActionControllerLogSubscriber < Probe
4
- # The log subscriber that replaces the default `ActionController::LogSubscriber`.
5
- # The intent of this subscriber is to, as transparently as possible, properly
6
- # track events that are being logged here. This LogSubscriber will never change
7
- # default behavior / log messages.
8
- class LogSubscriber < ::ActionController::LogSubscriber
9
- def start_processing(event)
10
- info do
11
- payload = event.payload
12
- params = payload[:params].except(*INTERNAL_PARAMS)
13
- format = extract_format(payload)
14
- format = format.to_s.upcase if format.is_a?(Symbol)
15
-
16
- Events::ControllerCall.new(
17
- controller: payload[:controller],
18
- action: payload[:action],
19
- format: format,
20
- params: params
21
- )
22
- end
23
- end
24
-
25
- def process_action(event)
26
- info do
27
- payload = event.payload
28
- additions = ActionController::Base.log_process_action(payload)
29
-
30
- status = payload[:status]
31
- if status.nil? && payload[:exception].present?
32
- exception_class_name = payload[:exception].first
33
- status = extract_status(exception_class_name)
34
- end
35
-
36
- Events::HTTPServerResponse.new(
37
- status: status,
38
- time_ms: event.duration,
39
- additions: additions
40
- )
41
- end
42
- end
43
-
44
- private
45
- def extract_format(payload)
46
- if payload.key?(:format)
47
- payload[:format] # rails > 4.X
48
- elsif payload.key?(:formats)
49
- payload[:formats].first # rails 3.X
50
- end
51
- end
52
-
53
- def extract_status(exception_class_name)
54
- if defined?(ActionDispatch::ExceptionWrapper)
55
- ActionDispatch::ExceptionWrapper.status_code_for_exception(exception_class_name)
56
- else
57
- # Rails 3.X
58
- Rack::Utils.status_code(ActionDispatch::ShowExceptions.rescue_responses[exception_class_name]) rescue nil
59
- end
60
- end
61
- end
62
- end
63
- end
64
- end
@@ -1,52 +0,0 @@
1
- module Timber
2
- module Probes
3
- # Responsible for automatically tracking controller call and http response events
4
- # for applications that use `ActionController`.
5
- class ActionControllerUserContext < Probe
6
- module AroundFilter
7
- def self.included(klass)
8
- klass.class_eval do
9
- if klass.respond_to?(:around_action)
10
- around_action :_timber_capture_user_context
11
- else
12
- around_filter :_timber_capture_user_context
13
- end
14
-
15
- private
16
- def _timber_capture_user_context
17
- if respond_to?(:current_user, true)
18
- id = Timber::Util::Object.try(current_user, :id)
19
- name = Timber::Util::Object.try(current_user, :name)
20
- if !name
21
- first_name = Timber::Util::Object.try(current_user, :first_name)
22
- last_name = Timber::Util::Object.try(current_user, :last_name)
23
- if first_name || last_name
24
- name = [first_name, last_name].compact.join(" ")
25
- end
26
- end
27
- email = Timber::Util::Object.try(current_user, :email)
28
- user_context = Timber::Contexts::User.new(:id => id, :name => name, :email => email)
29
- Timber::CurrentContext.with(user_context) do
30
- yield
31
- end
32
- else
33
- yield
34
- end
35
- end
36
- end
37
- end
38
- end
39
-
40
- def initialize
41
- require "action_controller"
42
- rescue LoadError => e
43
- raise RequirementNotMetError.new(e.message)
44
- end
45
-
46
- def insert!
47
- return true if ActionController::Base.include?(AroundFilter)
48
- ActionController::Base.send(:include, AroundFilter)
49
- end
50
- end
51
- end
52
- end
@@ -1,80 +0,0 @@
1
- module Timber
2
- module Probes
3
- # Reponsible for automatically tracking exception events in Rails applications. While
4
- # still preserving the default log style.
5
- class ActionDispatchDebugExceptions < Probe
6
- # For Rails >= 3.1
7
- # @private
8
- module DebugExceptionsInstanceMethods
9
- def self.included(klass)
10
- klass.class_eval do
11
- private
12
- def log_error(request, wrapper)
13
- logger = logger(request)
14
- return unless logger
15
-
16
- exception = wrapper.exception
17
-
18
- trace = wrapper.application_trace
19
- trace = wrapper.framework_trace if trace.empty?
20
-
21
- event = Events::Exception.new(
22
- name: exception.class.name,
23
- exception_message: exception.message,
24
- backtrace: trace
25
- )
26
-
27
- logger.fatal event
28
- end
29
- end
30
- end
31
- end
32
-
33
- # For Rails < 3.1
34
- # @private
35
- module ShowExceptionsInstanceMethods #:nodoc:
36
- def self.included(klass)
37
- klass.class_eval do
38
- private
39
- # We have to monkey patch because ruby < 2.0 does not support prepend.
40
- alias_method :_timber_old_log_error, :log_error
41
-
42
- def log_error(exception)
43
- return unless logger
44
-
45
- event = Events::Exception.new(
46
- name: exception.class.name,
47
- exception_message: exception.message,
48
- backtrace: application_trace(exception)
49
- )
50
-
51
- logger.fatal event
52
- end
53
- end
54
- end
55
- end
56
-
57
- def initialize
58
- begin
59
- # Rails >= 3.1
60
- require "action_dispatch/middleware/debug_exceptions"
61
- rescue LoadError
62
- # Rails < 3.1
63
- require "action_dispatch/middleware/show_exceptions"
64
- end
65
- rescue LoadError => e
66
- raise RequirementNotMetError.new(e.message)
67
- end
68
-
69
- def insert!
70
- if defined?(::ActionDispatch::DebugExceptions)
71
- return true if ::ActionDispatch::DebugExceptions.include?(DebugExceptionsInstanceMethods)
72
- ::ActionDispatch::DebugExceptions.send(:include, DebugExceptionsInstanceMethods)
73
- else
74
- return true if ::ActionDispatch::ShowExceptions.include?(ShowExceptionsInstanceMethods)
75
- ::ActionDispatch::ShowExceptions.send(:include, ShowExceptionsInstanceMethods)
76
- end
77
- end
78
- end
79
- end
80
- end
@@ -1,20 +0,0 @@
1
- module Timber
2
- module Probes
3
- # Reponsible for automatically tracking template rendering events in `ActionView` while
4
- # still preserving the default log style.
5
- class ActionViewLogSubscriber < Probe
6
- def initialize
7
- require "action_view/log_subscriber"
8
- require "timber/probes/action_view_log_subscriber/log_subscriber"
9
- rescue LoadError => e
10
- raise RequirementNotMetError.new(e.message)
11
- end
12
-
13
- def insert!
14
- return true if Util::ActiveSupportLogSubscriber.subscribed?(:action_view, LogSubscriber)
15
- Util::ActiveSupportLogSubscriber.unsubscribe(:action_view, ::ActionView::LogSubscriber)
16
- LogSubscriber.attach_to(:action_view)
17
- end
18
- end
19
- end
20
- end
@@ -1,69 +0,0 @@
1
- module Timber
2
- module Probes
3
- class ActionViewLogSubscriber < Probe
4
- # The log subscriber that replaces the default `ActionView::LogSubscriber`.
5
- # The intent of this subscriber is to, as transparently as possible, properly
6
- # track events that are being logged here. This LogSubscriber will never change
7
- # default behavior / log messages.
8
- class LogSubscriber < ::ActionView::LogSubscriber
9
- def render_template(event)
10
- info do
11
- full_name = from_rails_root(event.payload[:identifier])
12
- message = " Rendered #{full_name}"
13
- message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
14
- message << " (#{event.duration.round(1)}ms)"
15
-
16
- Events::TemplateRender.new(
17
- name: full_name,
18
- time_ms: event.duration,
19
- message: message
20
- )
21
- end
22
- end
23
-
24
- def render_partial(event)
25
- info do
26
- full_name = from_rails_root(event.payload[:identifier])
27
- message = " Rendered #{full_name}"
28
- message << " within #{from_rails_root(event.payload[:layout])}" if event.payload[:layout]
29
- message << " (#{event.duration.round(1)}ms)"
30
- message << " #{cache_message(event.payload)}" if event.payload.key?(:cache_hit)
31
-
32
- Events::TemplateRender.new(
33
- name: full_name,
34
- time_ms: event.duration,
35
- message: message
36
- )
37
- end
38
- end
39
-
40
- def render_collection(event)
41
- if respond_to?(:render_count, true)
42
- info do
43
- identifier = event.payload[:identifier] || "templates"
44
- full_name = from_rails_root(identifier)
45
- message = " Rendered collection of #{full_name}" \
46
- " #{render_count(event.payload)} (#{event.duration.round(1)}ms)"
47
-
48
- Events::TemplateRender.new(
49
- name: full_name,
50
- time_ms: event.duration,
51
- message: message
52
- )
53
- end
54
- else
55
- # Older versions of rails delegate this method to #render_template
56
- render_template(event)
57
- end
58
- end
59
-
60
- private
61
- def log_rendering_start(payload)
62
- # Consolidates 2 template rendering events into 1. We don't need 2 events for
63
- # rendering a template. If you disagree, please feel free to open a PR and we
64
- # can make this an option.
65
- end
66
- end
67
- end
68
- end
69
- end
@@ -1,20 +0,0 @@
1
- module Timber
2
- module Probes
3
- # Reponsible for automatimcally tracking SQL query events in `ActiveRecord`, while still
4
- # preserving the default log style.
5
- class ActiveRecordLogSubscriber < Probe
6
- def initialize
7
- require "active_record/log_subscriber"
8
- require "timber/probes/active_record_log_subscriber/log_subscriber"
9
- rescue LoadError => e
10
- raise RequirementNotMetError.new(e.message)
11
- end
12
-
13
- def insert!
14
- return true if Util::ActiveSupportLogSubscriber.subscribed?(:active_record, LogSubscriber)
15
- Util::ActiveSupportLogSubscriber.unsubscribe(:active_record, ::ActiveRecord::LogSubscriber)
16
- LogSubscriber.attach_to(:active_record)
17
- end
18
- end
19
- end
20
- end
@@ -1,31 +0,0 @@
1
- module Timber
2
- module Probes
3
- class ActiveRecordLogSubscriber < Probe
4
- # The log subscriber that replaces the default `ActiveRecord::LogSubscriber`.
5
- # The intent of this subscriber is to, as transparently as possible, properly
6
- # track events that are being logged here. This LogSubscriber will never change
7
- # default behavior / log messages.
8
- class LogSubscriber < ::ActiveRecord::LogSubscriber #:nodoc:
9
- def sql(event)
10
- super(event)
11
-
12
- if @message
13
- payload = event.payload
14
- event = Events::SQLQuery.new(
15
- sql: payload[:sql],
16
- time_ms: event.duration,
17
- message: @message
18
- )
19
-
20
- logger.debug event
21
- end
22
- end
23
-
24
- private
25
- def debug(message)
26
- @message = message
27
- end
28
- end
29
- end
30
- end
31
- end
@@ -1,63 +0,0 @@
1
- module Timber
2
- module Probes
3
- # Reponsible for automatimcally tracking SQL query events in `ActiveRecord`, while still
4
- # preserving the default log style.
5
- class ActiveSupportTaggedLogging < Probe
6
- module FormatterMethods
7
- def self.included(mod)
8
- mod.module_eval do
9
- alias_method :_timber_original_push_tags, :push_tags
10
- alias_method :_timber_original_pop_tags, :pop_tags
11
-
12
- def call(severity, timestamp, progname, msg)
13
- if is_a?(Timber::Logger::Formatter)
14
- # Don't convert the message into a string
15
- super(severity, timestamp, progname, msg)
16
- else
17
- super(severity, timestamp, progname, "#{tags_text}#{msg}")
18
- end
19
- end
20
- end
21
- end
22
- end
23
-
24
- module LoggerMethods
25
- def self.included(klass)
26
- klass.class_eval do
27
- def add(severity, message = nil, progname = nil, &block)
28
- if message.nil?
29
- if block_given?
30
- message = block.call
31
- else
32
- message = progname
33
- progname = nil #No instance variable for this like Logger
34
- end
35
- end
36
- if @logger.is_a?(Timber::Logger)
37
- @logger.add(severity, message, progname)
38
- else
39
- @logger.add(severity, "#{tags_text}#{message}", progname)
40
- end
41
- end
42
- end
43
- end
44
- end
45
-
46
- def initialize
47
- require "active_support/tagged_logging"
48
- rescue LoadError => e
49
- raise RequirementNotMetError.new(e.message)
50
- end
51
-
52
- def insert!
53
- if defined?(ActiveSupport::TaggedLogging::Formatter)
54
- return true if ActiveSupport::TaggedLogging::Formatter.include?(FormatterMethods)
55
- ActiveSupport::TaggedLogging::Formatter.send(:include, FormatterMethods)
56
- else
57
- return true if ActiveSupport::TaggedLogging.include?(LoggerMethods)
58
- ActiveSupport::TaggedLogging.send(:include, LoggerMethods)
59
- end
60
- end
61
- end
62
- end
63
- end