timber 2.6.2 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
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