timber 2.0.24 → 2.1.0.rc1
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.
- checksums.yaml +4 -4
- data/.travis.yml +2 -2
- data/CHANGELOG +3 -0
- data/README.md +314 -59
- data/bin/timber +11 -2
- data/lib/timber.rb +2 -7
- data/lib/timber/cli.rb +16 -28
- data/lib/timber/cli/api.rb +80 -14
- data/lib/timber/cli/api/application.rb +30 -0
- data/lib/timber/cli/config_file.rb +66 -0
- data/lib/timber/cli/file_helper.rb +43 -0
- data/lib/timber/cli/installer.rb +58 -0
- data/lib/timber/cli/installers.rb +37 -0
- data/lib/timber/cli/installers/other.rb +47 -0
- data/lib/timber/cli/installers/rails.rb +255 -0
- data/lib/timber/cli/installers/root.rb +189 -0
- data/lib/timber/cli/io.rb +97 -0
- data/lib/timber/cli/io/ansi.rb +22 -0
- data/lib/timber/cli/io/messages.rb +213 -0
- data/lib/timber/cli/os_helper.rb +53 -0
- data/lib/timber/config.rb +97 -43
- data/lib/timber/config/integrations.rb +63 -0
- data/lib/timber/config/integrations/rack.rb +74 -0
- data/lib/timber/context.rb +13 -10
- data/lib/timber/contexts.rb +1 -0
- data/lib/timber/contexts/custom.rb +16 -3
- data/lib/timber/contexts/http.rb +10 -3
- data/lib/timber/contexts/organization.rb +4 -0
- data/lib/timber/contexts/release.rb +46 -0
- data/lib/timber/contexts/runtime.rb +7 -1
- data/lib/timber/contexts/session.rb +8 -1
- data/lib/timber/contexts/system.rb +5 -1
- data/lib/timber/contexts/user.rb +9 -2
- data/lib/timber/current_context.rb +43 -11
- data/lib/timber/events/controller_call.rb +4 -0
- data/lib/timber/events/custom.rb +13 -5
- data/lib/timber/events/exception.rb +4 -0
- data/lib/timber/events/http_client_request.rb +4 -0
- data/lib/timber/events/http_client_response.rb +4 -0
- data/lib/timber/events/http_server_request.rb +5 -0
- data/lib/timber/events/http_server_response.rb +15 -3
- data/lib/timber/events/sql_query.rb +3 -0
- data/lib/timber/events/template_render.rb +3 -0
- data/lib/timber/integration.rb +40 -0
- data/lib/timber/integrations.rb +21 -14
- data/lib/timber/integrations/action_controller.rb +18 -0
- data/lib/timber/integrations/action_controller/log_subscriber.rb +2 -0
- data/lib/timber/integrations/action_controller/log_subscriber/timber_log_subscriber.rb +6 -0
- data/lib/timber/integrations/action_dispatch.rb +23 -0
- data/lib/timber/integrations/action_dispatch/debug_exceptions.rb +2 -0
- data/lib/timber/integrations/action_view.rb +18 -0
- data/lib/timber/integrations/action_view/log_subscriber.rb +2 -0
- data/lib/timber/integrations/action_view/log_subscriber/timber_log_subscriber.rb +10 -0
- data/lib/timber/integrations/active_record.rb +18 -0
- data/lib/timber/integrations/active_record/log_subscriber.rb +2 -0
- data/lib/timber/integrations/active_record/log_subscriber/timber_log_subscriber.rb +8 -0
- data/lib/timber/integrations/rack.rb +12 -2
- data/lib/timber/integrations/rack/exception_event.rb +38 -5
- data/lib/timber/integrations/rack/http_context.rb +4 -6
- data/lib/timber/integrations/rack/http_events.rb +177 -27
- data/lib/timber/integrations/rack/middleware.rb +28 -0
- data/lib/timber/integrations/rack/session_context.rb +5 -6
- data/lib/timber/integrations/rack/user_context.rb +90 -43
- data/lib/timber/integrations/rails.rb +22 -0
- data/lib/timber/integrations/rails/rack_logger.rb +2 -0
- data/lib/timber/integrator.rb +18 -3
- data/lib/timber/log_devices/http.rb +107 -99
- data/lib/timber/log_devices/http/dropping_sized_queue.rb +26 -0
- data/lib/timber/log_devices/http/flushable_sized_queue.rb +42 -0
- data/lib/timber/log_entry.rb +14 -2
- data/lib/timber/logger.rb +51 -36
- data/lib/timber/overrides.rb +2 -0
- data/lib/timber/overrides/active_support_3_tagged_logging.rb +103 -0
- data/lib/timber/overrides/active_support_tagged_logging.rb +53 -90
- data/lib/timber/timer.rb +21 -0
- data/lib/timber/util/hash.rb +1 -1
- data/lib/timber/util/http_event.rb +16 -3
- data/lib/timber/version.rb +1 -1
- data/spec/support/timber.rb +2 -3
- data/spec/timber/cli/installers/rails_spec.rb +160 -0
- data/spec/timber/cli/installers/root_spec.rb +100 -0
- data/spec/timber/config_spec.rb +28 -0
- data/spec/timber/current_context_spec.rb +61 -12
- data/spec/timber/events/custom_spec.rb +13 -2
- data/spec/timber/events/exception_spec.rb +15 -0
- data/spec/timber/events/http_server_request_spec.rb +3 -3
- data/spec/timber/integrations/rack/http_events_spec.rb +101 -0
- data/spec/timber/log_devices/http_spec.rb +20 -4
- data/spec/timber/log_entry_spec.rb +2 -1
- data/spec/timber/logger_spec.rb +8 -8
- metadata +40 -9
- data/benchmarks/rails.rb +0 -122
- data/lib/timber/cli/application.rb +0 -28
- data/lib/timber/cli/install.rb +0 -196
- data/lib/timber/cli/io_helper.rb +0 -65
- data/lib/timber/cli/messages.rb +0 -180
- data/lib/timber/integrations/active_support/tagged_logging.rb +0 -71
@@ -0,0 +1,97 @@
|
|
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
|
+
|
21
|
+
if api
|
22
|
+
api.event(:waiting_for_input, prompt: event_prompt)
|
23
|
+
end
|
24
|
+
|
25
|
+
write prompt + " "
|
26
|
+
input = gets.downcase
|
27
|
+
|
28
|
+
if api
|
29
|
+
api.event(:received_input, prompt: event_prompt, value: input)
|
30
|
+
end
|
31
|
+
|
32
|
+
if allowed_inputs.include?(input)
|
33
|
+
input
|
34
|
+
else
|
35
|
+
if iteration == 10
|
36
|
+
raise "It appears we're having an issue receiving correct input for:\n\n" \
|
37
|
+
"#{prompt}\n\n" \
|
38
|
+
"We were expecting one of #{allowed_inputs}, but got #{input.inspect}."
|
39
|
+
else
|
40
|
+
puts "Woops! That's not a valid input. Please enter one of #{allowed_inputs.join(", ")}."
|
41
|
+
ask(prompt, allowed_inputs, options, iteration + 1)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def ask_to_proceed
|
47
|
+
message = "Ready to proceed?"
|
48
|
+
case ask_yes_no(message)
|
49
|
+
when :yes
|
50
|
+
true
|
51
|
+
when :no
|
52
|
+
ask_to_proceed
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
def ask_yes_no(message, options = {})
|
57
|
+
case ask(message + " (y/n)", ["y", "n"], options)
|
58
|
+
when "y"
|
59
|
+
:yes
|
60
|
+
when "n"
|
61
|
+
:no
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def gets
|
66
|
+
value = io_in.gets
|
67
|
+
value ? value.chomp.downcase : ""
|
68
|
+
end
|
69
|
+
|
70
|
+
def puts(message, color = nil)
|
71
|
+
if color
|
72
|
+
message = ANSI.colorize(message, color)
|
73
|
+
end
|
74
|
+
|
75
|
+
io_out.puts(message)
|
76
|
+
end
|
77
|
+
|
78
|
+
def task(message, &block)
|
79
|
+
write IO::Messages.task_start(message), :blue
|
80
|
+
result = yield
|
81
|
+
puts IO::Messages.task_complete(message), :green
|
82
|
+
result
|
83
|
+
rescue Exception => e
|
84
|
+
puts IO::Messages.task_failed(message), :red
|
85
|
+
raise e
|
86
|
+
end
|
87
|
+
|
88
|
+
def write(message, color = nil)
|
89
|
+
if color
|
90
|
+
message = ANSI.colorize(message, color)
|
91
|
+
end
|
92
|
+
|
93
|
+
io_out.write(message)
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
@@ -0,0 +1,22 @@
|
|
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
|
@@ -0,0 +1,213 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "timber/cli/io/ansi"
|
4
|
+
require "timber/cli/os_helper"
|
5
|
+
|
6
|
+
module Timber
|
7
|
+
class CLI
|
8
|
+
class IO
|
9
|
+
module Messages
|
10
|
+
extend self
|
11
|
+
|
12
|
+
APP_URL = "https://app.timber.io"
|
13
|
+
DOCS_URL = "https://timber.io/docs"
|
14
|
+
OBTAIN_KEY_DOCS_URL = "https://timber.io/docs/app/obtain-api-key/"
|
15
|
+
REPO_URL = "https://github.com/timberio/timber-ruby"
|
16
|
+
SUPPORT_EMAIL = "support@timber.io"
|
17
|
+
TWITTER_HANDLE = "@timberdotio"
|
18
|
+
WEBSITE_URL = "https://timber.io"
|
19
|
+
MAX_LENGTH = 80.freeze
|
20
|
+
|
21
|
+
def application_details(app)
|
22
|
+
message = <<-MESSAGE
|
23
|
+
Woot! Your API 🔑 is valid:
|
24
|
+
|
25
|
+
Name: #{app.name} (#{app.environment})
|
26
|
+
Framework: #{app.framework_type}
|
27
|
+
Platform: #{app.platform_type}
|
28
|
+
MESSAGE
|
29
|
+
message.rstrip
|
30
|
+
end
|
31
|
+
|
32
|
+
def edit_app_url(app)
|
33
|
+
"#{APP_URL}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def bad_experience_message
|
37
|
+
message = <<-MESSAGE
|
38
|
+
Bummer! That is certainly not the experience we were going for.
|
39
|
+
|
40
|
+
Could you tell us why you a bad experience?
|
41
|
+
|
42
|
+
(this will be sent directly to the Timber engineering team)
|
43
|
+
MESSAGE
|
44
|
+
message.rstrip
|
45
|
+
end
|
46
|
+
|
47
|
+
def git_commands
|
48
|
+
message = <<-MESSAGE
|
49
|
+
#{ANSI.colorize("git add config/initializers/timber.rb", :blue)}
|
50
|
+
#{ANSI.colorize("git commit -am 'Install the timber logger'", :blue)}
|
51
|
+
MESSAGE
|
52
|
+
message.rstrip
|
53
|
+
end
|
54
|
+
|
55
|
+
def console_url(app)
|
56
|
+
message = <<-MESSAGE
|
57
|
+
Your console URL: https://app.timber.io/organizations/timber/apps/#{app.slug}/console
|
58
|
+
MESSAGE
|
59
|
+
end
|
60
|
+
|
61
|
+
def contact
|
62
|
+
message = <<-MESSAGE
|
63
|
+
Website: #{WEBSITE_URL}
|
64
|
+
Documentation: #{DOCS_URL}
|
65
|
+
Support: #{SUPPORT_EMAIL}
|
66
|
+
MESSAGE
|
67
|
+
message.rstrip
|
68
|
+
end
|
69
|
+
|
70
|
+
def copied_to_clipboard
|
71
|
+
IO::ANSI.colorize("(✓ copied to clipboard)", :green)
|
72
|
+
end
|
73
|
+
|
74
|
+
def http_environment_variables(api_key)
|
75
|
+
command = "export TIMBER_API_KEY=\"#{api_key}\""
|
76
|
+
copied = OSHelper.copy_to_clipboard(command)
|
77
|
+
|
78
|
+
message = <<-MESSAGE
|
79
|
+
Great! Add this variable to your environment:
|
80
|
+
|
81
|
+
#{ANSI.colorize(command, :blue)}
|
82
|
+
|
83
|
+
MESSAGE
|
84
|
+
message = message.rstrip
|
85
|
+
|
86
|
+
if copied
|
87
|
+
message << "\n #{copied_to_clipboard}"
|
88
|
+
end
|
89
|
+
|
90
|
+
message
|
91
|
+
end
|
92
|
+
|
93
|
+
def free_data
|
94
|
+
message = <<-MESSAGE
|
95
|
+
Because you're awesome, we've credited your account with ✨ 50mb✨. Get more:
|
96
|
+
|
97
|
+
* Get ✨ 250mb✨ for tweeting your experience to #{TWITTER_HANDLE}
|
98
|
+
* Get ✨ 100mb✨ for starring our repo: #{REPO_URL}
|
99
|
+
* Get ✨ 100mb✨ for following #{TWITTER_HANDLE} on twitter
|
100
|
+
MESSAGE
|
101
|
+
message.rstrip
|
102
|
+
end
|
103
|
+
|
104
|
+
def header
|
105
|
+
message = <<-MESSAGE
|
106
|
+
🌲 Timber.io Ruby Installer
|
107
|
+
|
108
|
+
^ ^ ^ ^ ___I_ ^ ^ ^ ^ ^ ^ ^
|
109
|
+
/|\\/|\\/|\\ /|\\ /\\-_--\\ /|\\/|\\ /|\\/|\\/|\\ /|\\/|\\
|
110
|
+
/|\\/|\\/|\\ /|\\ / \\_-__\\ /|\\/|\\ /|\\/|\\/|\\ /|\\/|\\
|
111
|
+
/|\\/|\\/|\\ /|\\ |[]| [] | /|\\/|\\ /|\\/|\\/|\\ /|\\/|\\
|
112
|
+
MESSAGE
|
113
|
+
message.rstrip
|
114
|
+
end
|
115
|
+
|
116
|
+
def heroku_install(app)
|
117
|
+
command = "heroku drains:add #{app.heroku_drain_url}"
|
118
|
+
copied = OSHelper.copy_to_clipboard(command)
|
119
|
+
|
120
|
+
message = <<-MESSAGE
|
121
|
+
First, let's setup your Heroku drain. Run this command in a separate window:
|
122
|
+
|
123
|
+
#{ANSI.colorize(command, :blue)}
|
124
|
+
MESSAGE
|
125
|
+
message = message.rstrip
|
126
|
+
|
127
|
+
if copied
|
128
|
+
message << "\n #{copied_to_clipboard}"
|
129
|
+
end
|
130
|
+
|
131
|
+
message
|
132
|
+
end
|
133
|
+
|
134
|
+
def no_api_key_provided
|
135
|
+
message = <<-MESSAGE
|
136
|
+
Hey there! Welcome to Timber. In order to proceed, you'll need an API key.
|
137
|
+
If you already have one, you can run this installer like:
|
138
|
+
|
139
|
+
#{ANSI.colorize("bundle exec timber install my-api-key", :blue)}
|
140
|
+
|
141
|
+
#{obtain_key_instructions}
|
142
|
+
MESSAGE
|
143
|
+
message.rstrip
|
144
|
+
end
|
145
|
+
|
146
|
+
def obtain_key_instructions
|
147
|
+
message = <<-MESSAGE
|
148
|
+
Don't have a key? Head over to:
|
149
|
+
|
150
|
+
#{ANSI.colorize(APP_URL, :blue)}
|
151
|
+
|
152
|
+
For a simple guide, checkout out:
|
153
|
+
|
154
|
+
#{ANSI.colorize(OBTAIN_KEY_DOCS_URL, :blue)}
|
155
|
+
|
156
|
+
If you're stuck, contact us:
|
157
|
+
|
158
|
+
#{ANSI.colorize(SUPPORT_EMAIL, :blue)}
|
159
|
+
MESSAGE
|
160
|
+
message.rstrip
|
161
|
+
end
|
162
|
+
|
163
|
+
def separator
|
164
|
+
"--------------------------------------------------------------------------------"
|
165
|
+
end
|
166
|
+
|
167
|
+
def spinner(iteration)
|
168
|
+
rem = iteration % 3
|
169
|
+
case rem
|
170
|
+
when 0
|
171
|
+
"/"
|
172
|
+
when 1
|
173
|
+
"-"
|
174
|
+
when 2
|
175
|
+
"\\"
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def failed
|
180
|
+
"Failed :("
|
181
|
+
end
|
182
|
+
|
183
|
+
def success
|
184
|
+
"✓ Success!"
|
185
|
+
end
|
186
|
+
|
187
|
+
def task_complete(message)
|
188
|
+
remainder = MAX_LENGTH - message.length - success.length
|
189
|
+
|
190
|
+
dots = "." * remainder
|
191
|
+
"\r#{message}#{dots}#{success}"
|
192
|
+
end
|
193
|
+
|
194
|
+
def task_failed(message)
|
195
|
+
remainder = MAX_LENGTH - message.length - failed.length
|
196
|
+
|
197
|
+
dots = "." * remainder
|
198
|
+
"\r#{message}#{dots}#{failed}"
|
199
|
+
end
|
200
|
+
|
201
|
+
def task_start(message)
|
202
|
+
remainder = MAX_LENGTH - message.length - success.length
|
203
|
+
|
204
|
+
"\r#{message}" + ("." * remainder)
|
205
|
+
end
|
206
|
+
|
207
|
+
def we_love_you_too
|
208
|
+
"Thanks! We 💖 you too!"
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
module Timber
|
2
|
+
class CLI
|
3
|
+
module OSHelper
|
4
|
+
def self.copy_to_clipboard?
|
5
|
+
`which pbcopy` != ""
|
6
|
+
rescue Exception
|
7
|
+
false
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.copy_to_clipboard(input)
|
11
|
+
::IO.popen('pbcopy', 'w') { |f| f << input }
|
12
|
+
true
|
13
|
+
rescue Exception
|
14
|
+
false
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.git_commit_changes
|
18
|
+
begin
|
19
|
+
`git add config/initializers/timber.rb`
|
20
|
+
rescue Exception
|
21
|
+
end
|
22
|
+
|
23
|
+
`git commit -am 'Install the timber logger'`
|
24
|
+
true
|
25
|
+
rescue Exception
|
26
|
+
false
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.has_git?
|
30
|
+
begin
|
31
|
+
`which git` != ""
|
32
|
+
rescue Exception
|
33
|
+
false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
# Attemps to open a URL in the user's default browser across
|
38
|
+
# the popular operating systems.
|
39
|
+
def self.open(link)
|
40
|
+
if RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/
|
41
|
+
system "start #{link}"
|
42
|
+
elsif RbConfig::CONFIG['host_os'] =~ /darwin/
|
43
|
+
system "open #{link}"
|
44
|
+
elsif RbConfig::CONFIG['host_os'] =~ /linux|bsd/
|
45
|
+
system "xdg-open #{link}"
|
46
|
+
end
|
47
|
+
true
|
48
|
+
rescue Exception
|
49
|
+
false
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
data/lib/timber/config.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
1
|
require "logger"
|
2
2
|
require "singleton"
|
3
3
|
|
4
|
+
require "timber/config/integrations"
|
5
|
+
|
4
6
|
module Timber
|
5
|
-
#
|
7
|
+
# Singleton class for reading and setting Timber configuration.
|
6
8
|
#
|
7
|
-
# For Rails apps this is installed into `config.timber`. See examples below.
|
9
|
+
# For Rails apps, this is installed into `config.timber`. See examples below.
|
8
10
|
#
|
9
11
|
# @example Rails example
|
10
12
|
# config.timber.append_metadata = false
|
@@ -12,9 +14,11 @@ module Timber
|
|
12
14
|
# config = Timber::Config.instance
|
13
15
|
# config.append_metdata = false
|
14
16
|
class Config
|
17
|
+
# @private
|
15
18
|
class NoLoggerError < StandardError; end
|
16
19
|
|
17
|
-
|
20
|
+
# @private
|
21
|
+
class SimpleLogFormatter < ::Logger::Formatter
|
18
22
|
# This method is invoked when a log event occurs
|
19
23
|
def call(severity, timestamp, progname, msg)
|
20
24
|
"[Timber] #{String === msg ? msg : msg.inspect}\n"
|
@@ -26,11 +30,10 @@ module Timber
|
|
26
30
|
|
27
31
|
include Singleton
|
28
32
|
|
29
|
-
attr_writer :
|
33
|
+
attr_writer :http_body_limit
|
30
34
|
|
31
35
|
# @private
|
32
36
|
def initialize
|
33
|
-
@header_filters = []
|
34
37
|
@http_body_limit = 2000
|
35
38
|
end
|
36
39
|
|
@@ -44,11 +47,16 @@ module Timber
|
|
44
47
|
# config.timber.debug_logger = ::Logger.new(STDOUT)
|
45
48
|
# @example Everything else
|
46
49
|
# Timber::Config.instance.debug_logger = ::Logger.new(STDOUT)
|
50
|
+
def debug_logger=(value)
|
51
|
+
@debug_logger = value
|
52
|
+
end
|
53
|
+
|
54
|
+
# Accessor method for {#debug_logger=}.
|
47
55
|
def debug_logger
|
48
56
|
@debug_logger
|
49
57
|
end
|
50
58
|
|
51
|
-
# A convenience method for writing debug messages to a file.
|
59
|
+
# A convenience method for writing internal Timber debug messages to a file.
|
52
60
|
#
|
53
61
|
# @example Rails
|
54
62
|
# config.timber.debug_to_file("#{Rails.root}/log/timber.log")
|
@@ -62,19 +70,19 @@ module Timber
|
|
62
70
|
file.binmode
|
63
71
|
file.sync = config.autoflush_log
|
64
72
|
file_logger = ::Logger.new(file)
|
65
|
-
file_logger.formatter =
|
73
|
+
file_logger.formatter = SimpleLogFormatter.new
|
66
74
|
self.debug_logger = file_logger
|
67
75
|
end
|
68
76
|
|
69
|
-
# A convenience method for writing debug messages to
|
77
|
+
# A convenience method for writing internal Timber debug messages to STDOUT.
|
70
78
|
#
|
71
79
|
# @example Rails
|
72
|
-
# config.timber.
|
80
|
+
# config.timber.debug_to_stdout
|
73
81
|
# @example Everything else
|
74
|
-
# Timber::Config.instance.
|
82
|
+
# Timber::Config.instance.debug_to_stdout
|
75
83
|
def debug_to_stdout
|
76
84
|
stdout_logger = ::Logger.new(STDOUT)
|
77
|
-
stdout_logger.formatter =
|
85
|
+
stdout_logger.formatter = SimpleLogFormatter.new
|
78
86
|
self.debug_logger = stdout_logger
|
79
87
|
end
|
80
88
|
|
@@ -82,10 +90,13 @@ module Timber
|
|
82
90
|
# It should be rare that you have to set this. If the aforementioned env vars are not
|
83
91
|
# set please do.
|
84
92
|
#
|
85
|
-
# @example
|
86
|
-
# config.timber.environment = "staging"
|
87
|
-
# @example Everything else
|
93
|
+
# @example If you do not set `RACK_ENV` or `RAILS_ENV`
|
88
94
|
# Timber::Config.instance.environment = "staging"
|
95
|
+
def environment=(value)
|
96
|
+
@environment = value
|
97
|
+
end
|
98
|
+
|
99
|
+
# Accessor method for {#environment=}
|
89
100
|
def environment
|
90
101
|
@environment ||= ENV["RACK_ENV"] || ENV["RAILS_ENV"] || "development"
|
91
102
|
end
|
@@ -95,9 +106,14 @@ module Timber
|
|
95
106
|
#
|
96
107
|
# @example Rails
|
97
108
|
# # config/environments/production.rb
|
98
|
-
# config.timber.
|
99
|
-
def
|
100
|
-
@
|
109
|
+
# config.timber.header_filter_headers += ['api-key']
|
110
|
+
def http_header_filters=(value)
|
111
|
+
@http_header_filters = value
|
112
|
+
end
|
113
|
+
|
114
|
+
# Accessor method for {#http_header_filters=}
|
115
|
+
def http_header_filters
|
116
|
+
@http_header_filters ||= []
|
101
117
|
end
|
102
118
|
|
103
119
|
# Truncates captured HTTP bodies to this specified limit. The default is `2000`.
|
@@ -110,38 +126,75 @@ module Timber
|
|
110
126
|
# config.timber.http_body_limit = 500
|
111
127
|
# @example Everything else
|
112
128
|
# Timber::Config.instance.http_body_limit = 500
|
129
|
+
def http_body_limit=(value)
|
130
|
+
@http_body_limit = value
|
131
|
+
end
|
132
|
+
|
133
|
+
# Accessor method for {#http_body_limit=}
|
113
134
|
def http_body_limit
|
114
135
|
@http_body_limit
|
115
136
|
end
|
116
137
|
|
117
|
-
#
|
138
|
+
# Convenience method for accessing the various `Timber::Integrations::*` class
|
139
|
+
# settings. These provides settings for enabling, disabled, and silencing integrations.
|
140
|
+
# See {Integrations} for a full list of available methods.
|
141
|
+
def integrations
|
142
|
+
Integrations
|
143
|
+
end
|
144
|
+
|
145
|
+
# A convenience method that automatically sets Timber's configuration to closely match
|
146
|
+
# the behavior of the ruby lograge library. This makes it easier when transitioning
|
147
|
+
# from lograge.
|
118
148
|
#
|
119
|
-
#
|
149
|
+
# It turns this:
|
120
150
|
#
|
121
|
-
#
|
122
|
-
#
|
151
|
+
# Started GET "/" for 127.0.0.1 at 2012-03-10 14:28:14 +0100
|
152
|
+
# Processing by HomeController#index as HTML
|
153
|
+
# Rendered text template within layouts/application (0.0ms)
|
154
|
+
# Rendered layouts/_assets.html.erb (2.0ms)
|
155
|
+
# Rendered layouts/_top.html.erb (2.6ms)
|
156
|
+
# Rendered layouts/_about.html.erb (0.3ms)
|
157
|
+
# Rendered layouts/_google_analytics.html.erb (0.4ms)
|
158
|
+
# Completed 200 OK in 79ms (Views: 78.8ms | ActiveRecord: 0.0ms)
|
123
159
|
#
|
124
|
-
#
|
125
|
-
#
|
126
|
-
# @
|
127
|
-
#
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
160
|
+
# Into this:
|
161
|
+
#
|
162
|
+
# Get "/" sent 200 OK in 79ms @metadata {...}
|
163
|
+
#
|
164
|
+
# In other words it:
|
165
|
+
#
|
166
|
+
# 1. Silences ActiveRecord SQL query logs.
|
167
|
+
# 2. Silences ActiveView template rendering logs.
|
168
|
+
# 3. Silences ActionController controller call logs.
|
169
|
+
# 4. Collapses HTTP request and response logs into a single event.
|
170
|
+
#
|
171
|
+
# Notice also that is is not exactly like lograge. This is intentional. Lograge has
|
172
|
+
# a number of downsides:
|
173
|
+
#
|
174
|
+
# 1. The attribute names (`method`, `format`, `status`, `db`, etc) are too generalized and vague.
|
175
|
+
# This makes it _very_ likely that it will clash with other structured data you're
|
176
|
+
# logging.
|
177
|
+
# 2. It doesn't support context making it near impossible to view in-app logs generated for
|
178
|
+
# the same request.
|
179
|
+
def logrageify!
|
180
|
+
integrations.action_controller.silence = true
|
181
|
+
integrations.action_view.silence = true
|
182
|
+
integrations.active_record.silence = true
|
183
|
+
integrations.rack.http_events.collapse_into_single_event = true
|
134
184
|
end
|
135
185
|
|
136
186
|
# This is the _main_ logger Timber writes to. All of the Timber integrations write to
|
137
187
|
# this logger instance. It should be set to your global logger. For Rails, this is set
|
138
188
|
# automatically to `Rails.logger`, you should not have to set this.
|
139
189
|
#
|
140
|
-
# @example
|
141
|
-
#
|
142
|
-
#
|
143
|
-
|
144
|
-
|
190
|
+
# @example Non-rails frameworks
|
191
|
+
# my_global_logger = Timber::Logger.new(STDOUT)
|
192
|
+
# Timber::Config.instance.logger = my_global_logger
|
193
|
+
def logger=(value)
|
194
|
+
@logger = value
|
195
|
+
end
|
196
|
+
|
197
|
+
# Accessor method for {#logger=}.
|
145
198
|
def logger
|
146
199
|
if @logger.is_a?(Proc)
|
147
200
|
@logger.call()
|
@@ -150,13 +203,14 @@ module Timber
|
|
150
203
|
end
|
151
204
|
end
|
152
205
|
|
153
|
-
private
|
154
|
-
|
155
|
-
|
156
|
-
|
206
|
+
# @private
|
207
|
+
def production?
|
208
|
+
environment == PRODUCTION_NAME
|
209
|
+
end
|
157
210
|
|
158
|
-
|
159
|
-
|
160
|
-
|
211
|
+
# @private
|
212
|
+
def staging?
|
213
|
+
environment == STAGING_NAME
|
214
|
+
end
|
161
215
|
end
|
162
216
|
end
|