timber 2.6.2 → 3.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 (142) hide show
  1. checksums.yaml +5 -5
  2. data/.travis.yml +8 -38
  3. data/CHANGELOG.md +9 -0
  4. data/README.md +30 -284
  5. data/Rakefile +78 -0
  6. data/lib/timber.rb +6 -6
  7. data/lib/timber/config.rb +1 -83
  8. data/lib/timber/config/integrations.rb +1 -47
  9. data/lib/timber/context.rb +3 -24
  10. data/lib/timber/contexts.rb +2 -30
  11. data/lib/timber/contexts/http.rb +16 -36
  12. data/lib/timber/contexts/release.rb +12 -23
  13. data/lib/timber/contexts/runtime.rb +9 -36
  14. data/lib/timber/contexts/session.rb +8 -21
  15. data/lib/timber/contexts/system.rb +9 -16
  16. data/lib/timber/contexts/user.rb +13 -33
  17. data/lib/timber/current_context.rb +16 -78
  18. data/lib/timber/event.rb +12 -9
  19. data/lib/timber/events.rb +1 -33
  20. data/lib/timber/events/controller_call.rb +20 -31
  21. data/lib/timber/events/error.rb +18 -26
  22. data/lib/timber/events/exception.rb +1 -0
  23. data/lib/timber/events/sql_query.rb +14 -24
  24. data/lib/timber/events/template_render.rb +13 -24
  25. data/lib/timber/integration.rb +1 -1
  26. data/lib/timber/integrator.rb +1 -1
  27. data/lib/timber/log_devices/http.rb +98 -19
  28. data/lib/timber/log_entry.rb +6 -24
  29. data/lib/timber/logger.rb +5 -14
  30. data/lib/timber/util.rb +1 -6
  31. data/lib/timber/util/non_nil_hash_builder.rb +3 -1
  32. data/lib/timber/version.rb +1 -1
  33. data/spec/README.md +2 -8
  34. data/spec/spec_helper.rb +0 -7
  35. data/spec/support/timber.rb +1 -3
  36. data/spec/timber/current_context_spec.rb +12 -50
  37. data/spec/timber/events/controller_call_spec.rb +4 -4
  38. data/spec/timber/events/error_spec.rb +4 -9
  39. data/spec/timber/log_devices/http_spec.rb +26 -2
  40. data/spec/timber/log_entry_spec.rb +12 -6
  41. data/spec/timber/logger_spec.rb +27 -68
  42. data/timber.gemspec +1 -1
  43. metadata +5 -139
  44. data/gemfiles/rails-3.0.gemfile +0 -5
  45. data/gemfiles/rails-3.1.gemfile +0 -5
  46. data/gemfiles/rails-3.2.gemfile +0 -5
  47. data/gemfiles/rails-4.0.gemfile +0 -9
  48. data/gemfiles/rails-4.1.gemfile +0 -9
  49. data/gemfiles/rails-4.2.gemfile +0 -9
  50. data/gemfiles/rails-5.0.gemfile +0 -9
  51. data/gemfiles/rails-5.1.gemfile +0 -9
  52. data/gemfiles/rails-edge.gemfile +0 -7
  53. data/lib/timber/cli.rb +0 -60
  54. data/lib/timber/cli/api.rb +0 -183
  55. data/lib/timber/cli/api/application.rb +0 -34
  56. data/lib/timber/cli/config_file.rb +0 -71
  57. data/lib/timber/cli/file_helper.rb +0 -53
  58. data/lib/timber/cli/installer.rb +0 -70
  59. data/lib/timber/cli/installers.rb +0 -102
  60. data/lib/timber/cli/installers/config_file.rb +0 -51
  61. data/lib/timber/cli/installers/other.rb +0 -59
  62. data/lib/timber/cli/installers/rails.rb +0 -225
  63. data/lib/timber/cli/installers/root.rb +0 -116
  64. data/lib/timber/cli/io.rb +0 -100
  65. data/lib/timber/cli/io/ansi.rb +0 -22
  66. data/lib/timber/cli/io/messages.rb +0 -198
  67. data/lib/timber/cli/os_helper.rb +0 -74
  68. data/lib/timber/config/integrations/rack.rb +0 -74
  69. data/lib/timber/contexts/custom.rb +0 -44
  70. data/lib/timber/contexts/organization.rb +0 -48
  71. data/lib/timber/events/custom.rb +0 -53
  72. data/lib/timber/events/http_request.rb +0 -71
  73. data/lib/timber/events/http_response.rb +0 -81
  74. data/lib/timber/frameworks.rb +0 -19
  75. data/lib/timber/frameworks/rails.rb +0 -27
  76. data/lib/timber/integrations.rb +0 -29
  77. data/lib/timber/integrations/action_controller.rb +0 -18
  78. data/lib/timber/integrations/action_controller/log_subscriber.rb +0 -27
  79. data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +0 -46
  80. data/lib/timber/integrations/action_dispatch.rb +0 -23
  81. data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +0 -53
  82. data/lib/timber/integrations/action_view.rb +0 -18
  83. data/lib/timber/integrations/action_view/log_subscriber.rb +0 -27
  84. data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +0 -83
  85. data/lib/timber/integrations/active_record.rb +0 -18
  86. data/lib/timber/integrations/active_record/log_subscriber.rb +0 -26
  87. data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +0 -53
  88. data/lib/timber/integrations/rack.rb +0 -27
  89. data/lib/timber/integrations/rack/error_event.rb +0 -64
  90. data/lib/timber/integrations/rack/http_context.rb +0 -27
  91. data/lib/timber/integrations/rack/http_events.rb +0 -210
  92. data/lib/timber/integrations/rack/middleware.rb +0 -28
  93. data/lib/timber/integrations/rack/session_context.rb +0 -65
  94. data/lib/timber/integrations/rack/user_context.rb +0 -135
  95. data/lib/timber/integrations/rails.rb +0 -22
  96. data/lib/timber/integrations/rails/rack_logger.rb +0 -60
  97. data/lib/timber/overrides.rb +0 -12
  98. data/lib/timber/overrides/active_support_3_tagged_logging.rb +0 -111
  99. data/lib/timber/overrides/active_support_buffered_logger.rb +0 -22
  100. data/lib/timber/overrides/active_support_tagged_logging.rb +0 -66
  101. data/lib/timber/overrides/lograge.rb +0 -18
  102. data/lib/timber/overrides/rails_stdout_logging.rb +0 -21
  103. data/lib/timber/util/active_support_log_subscriber.rb +0 -37
  104. data/lib/timber/util/attribute_normalizer.rb +0 -89
  105. data/lib/timber/util/hash.rb +0 -90
  106. data/lib/timber/util/request.rb +0 -72
  107. data/lib/timber/util/struct.rb +0 -16
  108. data/spec/rails/tagged_logging_spec.rb +0 -44
  109. data/spec/support/action_controller.rb +0 -8
  110. data/spec/support/active_record.rb +0 -32
  111. data/spec/support/rails.rb +0 -67
  112. data/spec/support/rails/templates/_partial.html +0 -1
  113. data/spec/support/rails/templates/template.html +0 -1
  114. data/spec/timber/cli/config_file_spec.rb +0 -26
  115. data/spec/timber/cli/installers/config_file_spec.rb +0 -36
  116. data/spec/timber/cli/installers/other_spec.rb +0 -49
  117. data/spec/timber/cli/installers/rails_spec.rb +0 -364
  118. data/spec/timber/cli/installers/root_spec.rb +0 -73
  119. data/spec/timber/config_spec.rb +0 -28
  120. data/spec/timber/contexts/custom_spec.rb +0 -11
  121. data/spec/timber/contexts/organization_spec.rb +0 -11
  122. data/spec/timber/contexts/runtime_spec.rb +0 -11
  123. data/spec/timber/contexts/system_spec.rb +0 -11
  124. data/spec/timber/contexts/user_spec.rb +0 -11
  125. data/spec/timber/contexts_spec.rb +0 -49
  126. data/spec/timber/event_spec.rb +0 -10
  127. data/spec/timber/events/custom_spec.rb +0 -36
  128. data/spec/timber/events/http_request_spec.rb +0 -32
  129. data/spec/timber/events/http_response_spec.rb +0 -12
  130. data/spec/timber/events_spec.rb +0 -55
  131. data/spec/timber/integrations/action_controller/log_subscriber_spec.rb +0 -55
  132. data/spec/timber/integrations/action_dispatch/debug_exceptions_spec.rb +0 -53
  133. data/spec/timber/integrations/action_view/log_subscriber_spec.rb +0 -115
  134. data/spec/timber/integrations/active_record/log_subscriber_spec.rb +0 -46
  135. data/spec/timber/integrations/rack/error_event_spec.rb +0 -63
  136. data/spec/timber/integrations/rack/http_context_spec.rb +0 -60
  137. data/spec/timber/integrations/rack/http_events_spec.rb +0 -101
  138. data/spec/timber/integrations/rack/session_context_spec.rb +0 -62
  139. data/spec/timber/integrations/rails/rack_logger_spec.rb +0 -58
  140. data/spec/timber/util/attribute_normalizer_spec.rb +0 -90
  141. data/spec/timber/util/hash_spec.rb +0 -30
  142. data/spec/timber/util/request_spec.rb +0 -10
@@ -1,225 +0,0 @@
1
- require "timber/cli/installer"
2
- require "timber/cli/installers/config_file"
3
- require "timber/cli/io/messages"
4
-
5
- module Timber
6
- class CLI
7
- module Installers
8
- class Rails < Installer
9
- # Runs the installer.
10
- def run(app)
11
- install_initializer(app)
12
- install_development_environment(app)
13
- install_test_environment(app)
14
-
15
- if !app.development? && !app.test?
16
- install_app_environment(app)
17
- end
18
- end
19
-
20
- private
21
- def install_initializer(app)
22
- initializer_path = File.join("config", "initializers", "timber.rb")
23
- installer = ConfigFile.new(io, api)
24
- installer.run(app, initializer_path)
25
- end
26
-
27
- # Determines the development preference
28
- def get_development_preference(app)
29
- if app.development?
30
- return :send
31
- else
32
- io.puts ""
33
- io.puts IO::Messages.separator
34
- io.puts ""
35
- io.puts "Would you like to temporarily send development logs to this Timber app?"
36
- io.puts "(Logs will still go to STDOUT, but this provides an easy way to kick the "
37
- io.puts "tires. Once you're done testing, you can disable this in "
38
- io.puts "#{IO::ANSI.colorize("config/environments/development.rb", :yellow)})"
39
- io.puts ""
40
- io.puts "y) Yes, send development logs to Timber", :blue
41
- io.puts "n) No, just print development logs to STDOUT", :blue
42
- io.puts ""
43
-
44
- input = io.ask_yes_no("Enter your choice:", event_prompt: "Send dev logs to Timber?")
45
-
46
- io.puts ""
47
- io.puts IO::Messages.separator
48
- io.puts ""
49
-
50
- case input
51
- when :yes
52
- :send
53
- when :no
54
- :dont_send
55
- end
56
- end
57
- end
58
-
59
- def install_development_environment(app)
60
- environment_file_path = get_environment_file_path("development")
61
- if environment_file_path
62
- if already_installed?(environment_file_path)
63
- io.task_complete("Timber already installed #{environment_file_path}")
64
- return :already_installed
65
- end
66
-
67
- development_preference = get_development_preference(app)
68
-
69
- case development_preference
70
- when :send
71
- api_key_code = get_api_key_code(:inline)
72
-
73
- logger_code = <<-CODE
74
- # Install the Timber.io logger
75
- # ----------------------------
76
- # Remove the `http_device` to stop sending development logs to Timber.
77
- # Be sure to keep the `file_device` or replace it with `STDOUT`.
78
- http_device = Timber::LogDevices::HTTP.new(#{api_key_code})
79
- file_device = File.open("\#{Rails.root}/log/development.log", "a")
80
- file_device.binmode
81
- log_devices = [http_device, file_device]
82
-
83
- # Do not modify below this line. It's important to keep the `Timber::Logger`
84
- # because it provides an API for logging structured data and capturing context.
85
- logger = Timber::Logger.new(*log_devices)
86
- logger.level = config.log_level
87
- config.logger = #{config_set_logger_code}
88
- CODE
89
-
90
- install_logger(environment_file_path, logger_code)
91
- return :http
92
-
93
- else
94
- install_stdout(environment_file_path)
95
- return :stdout
96
- end
97
- end
98
- end
99
-
100
- def install_test_environment(app)
101
- environment_file_path = get_environment_file_path("test")
102
- if environment_file_path
103
- if already_installed?(environment_file_path)
104
- io.task_complete("Timber already installed #{environment_file_path}")
105
- return :already_installed
106
- end
107
-
108
- # Tests should not be logged by default.
109
- install_nil(environment_file_path)
110
- :nil
111
- end
112
- end
113
-
114
- def install_app_environment(app)
115
- environment_file_path = get_environment_file_path(app.environment) || get_environment_file_path("production")
116
- if environment_file_path
117
- if already_installed?(environment_file_path)
118
- io.task_complete("Timber already installed #{environment_file_path}")
119
- return :already_installed
120
- end
121
-
122
- case get_delivery_strategy(app)
123
- when :http
124
- api_key_storage_preference = get_api_key_storage_preference
125
- install_http(environment_file_path, api_key_storage_preference)
126
- :http
127
- when :stdout
128
- install_stdout(environment_file_path)
129
- :stdout
130
- end
131
- end
132
- end
133
-
134
- # Wraps the logger in TaggedLogging if it is available. Older versions of Rails
135
- # do not include this constant.
136
- def config_set_logger_code
137
- @config_set_logger_code ||= defined?(::ActiveSupport::TaggedLogging) ?
138
- "ActiveSupport::TaggedLogging.new(logger)" : "logger"
139
- end
140
-
141
- def get_environment_file_path(environment)
142
- path = File.join("config", "environments", "#{environment}.rb")
143
- file_helper.exists?(path) ? path : nil
144
- end
145
-
146
- def install_nil(environment_file_path)
147
- logger_code = <<-CODE
148
- # Install the Timber.io logger
149
- # ----------------------------
150
- # `nil` is passed to disable logging. It's important to keep the `Timber::Logger`
151
- # because it provides an API for logging structured data and capturing context.
152
- logger = Timber::Logger.new(nil)
153
- logger.level = config.log_level
154
- config.logger = #{config_set_logger_code}
155
- CODE
156
-
157
- install_logger(environment_file_path, logger_code)
158
- end
159
-
160
- # Installs the Timber logger using the HTTP transport strategy in the
161
- # specified environment file.
162
- def install_http(environment_file_path, api_key_storage_type)
163
- api_key_code = get_api_key_code(api_key_storage_type)
164
-
165
- logger_code = <<-CODE
166
- # Install the Timber.io logger, send logs over HTTP.
167
- log_device = Timber::LogDevices::HTTP.new(#{api_key_code})
168
- logger = Timber::Logger.new(log_device)
169
- logger.level = config.log_level
170
- config.logger = #{config_set_logger_code}
171
- CODE
172
-
173
- install_logger(environment_file_path, logger_code)
174
- end
175
-
176
- # Installs the Timber logger using the STDOUT transport method in the specified
177
- # environment file.
178
- def install_stdout(environment_file_path)
179
- logger_code = <<-CODE
180
- # Install the Timber.io logger, send logs over STDOUT. Actual log delivery
181
- # to the Timber service is handled external of this application.
182
- logger = Timber::Logger.new(STDOUT)
183
- logger.level = config.log_level
184
- config.logger = #{config_set_logger_code}
185
- CODE
186
-
187
- install_logger(environment_file_path, logger_code)
188
- end
189
-
190
- # Determines if the environment is already installed.
191
- def already_installed?(environment_file_path)
192
- environment_file_contents = get_environment_file_contents(environment_file_path)
193
- logger_installed?(environment_file_contents)
194
- end
195
-
196
- # Convenience method for getting the current environment file contents.
197
- def get_environment_file_contents(environment_file_path)
198
- file_helper.read(environment_file_path)
199
- end
200
-
201
- # Determines if the Timber logger is already installed in the environment
202
- # file contents.
203
- def logger_installed?(environment_file_contents)
204
- environment_file_contents.include?("Timber::Logger.new")
205
- end
206
-
207
- # Installs the Timber logger in the specified environment file with the
208
- # provided logger code.
209
- def install_logger(environment_file_path, logger_code)
210
- current_contents = get_environment_file_contents(environment_file_path)
211
-
212
- task_message = "Installing the Timber::Logger in #{environment_file_path}"
213
- io.task(task_message) do
214
- if !logger_installed?(current_contents)
215
- new_contents = current_contents.sub(/\nend/, "\n\n#{logger_code}\nend")
216
- file_helper.write(environment_file_path, new_contents)
217
- end
218
- end
219
-
220
- true
221
- end
222
- end
223
- end
224
- end
225
- end
@@ -1,116 +0,0 @@
1
- # encoding: utf-8
2
-
3
- # Attempt to load rails so that we can determine the proper sub-installer to use.
4
- begin
5
- require "rails"
6
- rescue LoadError
7
- end
8
-
9
- require "timber/cli/api"
10
- require "timber/cli/installer"
11
- require "timber/cli/installers/other"
12
- require "timber/cli/installers/rails"
13
- require "timber/cli/io/messages"
14
- require "timber/cli/os_helper"
15
- require "timber/log_devices/http"
16
- require "timber/logger"
17
-
18
- module Timber
19
- class CLI
20
- module Installers
21
- # The root installer is the primary installer that is instantiated and
22
- # run when the installer starts. It is responsible for instantiating
23
- # the proper sub installers that install Timber in specific frameworks
24
- # and environments.
25
- class Root < Installer
26
- def run(app)
27
- io.puts IO::Messages.application_details(app)
28
- io.puts ""
29
-
30
- run_sub_installer(app)
31
- send_test_messages
32
- confirm_log_delivery
33
- api.event(:success)
34
- collect_feedback
35
- wrap_up(app)
36
- end
37
-
38
- private
39
- def run_sub_installer(app)
40
- sub_installer = get_sub_installer
41
- sub_installer.run(app)
42
- end
43
-
44
- def get_sub_installer
45
- if defined?(::Rails)
46
- Rails.new(io, api)
47
- else
48
- Other.new(io, api)
49
- end
50
- end
51
-
52
- def send_test_messages
53
- task_message = "Sending test logs"
54
- io.task(task_message) do
55
- http_device = LogDevices::HTTP.new(api.api_key)
56
- logger = Logger.new(http_device)
57
- logger.debug("Welcome to Timber!")
58
- logger.debug("This is a test log to ensure the pipes are working")
59
- logger.debug("Be sure to commit and deploy your app to start seeing real logs")
60
- # Close flushes and waits
61
- http_device.close
62
- end
63
- end
64
-
65
- def confirm_log_delivery
66
- task_message = "Confirming log delivery"
67
-
68
- io.task(task_message) do
69
- api.wait_for_logs do |iteration|
70
- io.write(IO::Messages.task_start(task_message), :blue)
71
- io.write(IO::Messages.spinner(iteration), :blue)
72
- end
73
- end
74
- end
75
-
76
- def wrap_up(app)
77
- io.puts ""
78
- io.puts IO::Messages.separator
79
- io.puts ""
80
- io.puts IO::ANSI.colorize("All done! Commit and deploy 🚀 to see logs in Timber.", :yellow)
81
- io.puts IO::ANSI.colorize("You can also test drive Timber by starting your app locally.", :yellow)
82
- io.puts ""
83
- end
84
-
85
- def collect_feedback
86
- io.puts ""
87
- io.puts IO::Messages.separator
88
- io.puts ""
89
-
90
- rating = io.ask("How would rate this install experience? 1 (bad) - 5 (perfect) or 'skip':", ["1", "2", "3", "4", "5", "skip"])
91
-
92
- case rating
93
- when "4", "5"
94
- api.event(:feedback, rating: rating.to_i)
95
- io.puts ""
96
- io.puts IO::Messages.we_love_you_too
97
-
98
- when "1", "2", "3"
99
- io.puts ""
100
- io.puts IO::Messages.bad_experience_message
101
- io.puts ""
102
- io.puts "Type your comments below (enter sends)"
103
- io.puts ""
104
-
105
- comments = io.gets
106
-
107
- api.event(:feedback, rating: rating.to_i, comments: comments)
108
-
109
- io.puts ""
110
- io.puts "Thank you! We take feedback seriously and will work to improve this."
111
- end
112
- end
113
- end
114
- end
115
- end
116
- end
@@ -1,100 +0,0 @@
1
- require "timber/cli/io/ansi"
2
- require "timber/cli/io/messages"
3
-
4
- module Timber
5
- class CLI
6
- # This is an abstraction for interfacing with IO devices. By default
7
- # it uses the STDOUT and STDIN io devices, but can be passed other devices
8
- # upon initialization.
9
- class IO
10
- attr_reader :io_out, :io_in
11
- attr_accessor :api
12
-
13
- def initialize(options = {})
14
- @io_out = options[:io_out] || STDOUT
15
- @io_in = options[:io_in] || STDIN
16
- end
17
-
18
- def ask(prompt, allowed_inputs, options = {}, iteration = 0)
19
- event_prompt = options[:event_prompt] || prompt
20
- write prompt + " "
21
- input = gets.downcase
22
-
23
- if allowed_inputs.include?(input)
24
- input
25
- else
26
- if iteration == 10
27
- raise "It appears we're having an issue receiving correct input for:\n\n" \
28
- "#{prompt}\n\n" \
29
- "We were expecting one of #{allowed_inputs}, but got #{input.inspect}."
30
- else
31
- puts "Woops! That's not a valid input. Please enter one of #{allowed_inputs.join(", ")}."
32
- ask(prompt, allowed_inputs, options, iteration + 1)
33
- end
34
- end
35
- end
36
-
37
- def ask_to_proceed
38
- message = "Ready to proceed?"
39
- case ask_yes_no(message)
40
- when :yes
41
- true
42
- when :no
43
- ask_to_proceed
44
- end
45
- end
46
-
47
- def ask_yes_no(message, options = {})
48
- case ask(message + " (y/n)", ["y", "n"], options)
49
- when "y"
50
- :yes
51
- when "n"
52
- :no
53
- end
54
- end
55
-
56
- def gets
57
- value = io_in.gets
58
- value ? value.chomp.downcase : ""
59
- end
60
-
61
- def puts(message, color = nil)
62
- if color
63
- message = ANSI.colorize(message, color)
64
- end
65
-
66
- io_out.puts(message)
67
- end
68
-
69
- def task(message, &block)
70
- task_start(message)
71
- result = yield
72
- task_complete(message)
73
- result
74
- rescue Exception => e
75
- task_failed(message)
76
- raise e
77
- end
78
-
79
- def task_start(message)
80
- write IO::Messages.task_start(message), :blue
81
- end
82
-
83
- def task_complete(message)
84
- puts IO::Messages.task_complete(message), :green
85
- end
86
-
87
- def task_failed(message)
88
- puts IO::Messages.task_failed(message), :red
89
- end
90
-
91
- def write(message, color = nil)
92
- if color
93
- message = ANSI.colorize(message, color)
94
- end
95
-
96
- io_out.write(message)
97
- end
98
- end
99
- end
100
- end
@@ -1,22 +0,0 @@
1
- module Timber
2
- class CLI
3
- class IO
4
- module ANSI
5
- def self.colorize(text, color)
6
- return text if Gem.win_platform?
7
-
8
- code =
9
- case color
10
- when :blue then 34
11
- when :red then 31
12
- when :green then 32
13
- when :yellow then 33
14
- else 0
15
- end
16
-
17
- "\e[#{code}m#{text}\e[0m"
18
- end
19
- end
20
- end
21
- end
22
- end