timber 2.0.0 → 2.0.1

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: eab99caab83ef2be6496c0ad1db6d736cf54817f
4
- data.tar.gz: dfdd212606d1ff42d908401e073ecf94a2cc2f72
3
+ metadata.gz: 59dfc96fa6eee2260cbfb09b2fb6eddfcae573e6
4
+ data.tar.gz: dce374823788ebcfeb4f036e2c01a09170354d2e
5
5
  SHA512:
6
- metadata.gz: b7e9143deab1f3d58076b7c55600f8ee72d7a11f3d659c1494f6bef053d03e444555564e1a7a7977fc1ed8bfab8b2c5d53bd1d238d2934b5d23537e6f23da2e5
7
- data.tar.gz: bb07cec849ea6a95a6480711b123612b1db91d6f4a59c23aac8c01b5f0b6ee921fc52ff43147a8123d9ad341b934055676e594cbc5ab4d1082268f423cd7d4f4
6
+ metadata.gz: 0cff008838b0289281df7f30904d65cf435a91c46f50050a23261cbba66c6a61db8632e649f77e3cbcb04fdda09b741b1cc02fc02aba0d0b239eb7105d298881
7
+ data.tar.gz: 4fbe781f747db8043c783e8732157f2d285e84f4ba14c0010b5944e082dbec86defdeacb9a5c66be5352122dd8652348aee09e26d33513256608569b927bf498
data/README.md CHANGED
@@ -15,7 +15,7 @@
15
15
 
16
16
  Timber turns your raw text logs into rich JSON events that can be consumed by the
17
17
  [Timber.io service](https://timber.io). It improves log data quality at the source, adding
18
- critical event and context data to your logs so that you can filter out the noise and
18
+ critical `event` and `context` data to your logs so that you can filter out the noise and
19
19
  solve problems faster.
20
20
 
21
21
  For example, Timber turns this:
@@ -9,7 +9,6 @@ module Timber
9
9
  include IOHelper
10
10
 
11
11
  def run(api_key)
12
- puts ""
13
12
  puts colorize(Messages.header, :green)
14
13
  puts colorize(Messages.separator, :green)
15
14
  puts colorize(Messages.contact, :green)
@@ -17,7 +16,7 @@ module Timber
17
16
  puts ""
18
17
 
19
18
  if !api_key
20
- puts colorize(Messages.no_api_key_provided, :red)
19
+ puts Messages.no_api_key_provided
21
20
  return
22
21
  end
23
22
 
@@ -28,6 +27,7 @@ module Timber
28
27
  app = Application.new(api)
29
28
 
30
29
  puts Messages.application_details(app)
30
+ puts ""
31
31
 
32
32
  case ask_yes_no("Are the above details correct?")
33
33
  when :yes
@@ -81,7 +81,7 @@ module Timber
81
81
  puts ""
82
82
  puts Messages.separator
83
83
  puts ""
84
- puts colorize(Messages.commit_and_deploy_reminder, :green)
84
+ puts Messages.commit_and_deploy_reminder
85
85
 
86
86
  api.event!(:success)
87
87
 
@@ -23,6 +23,7 @@ module Timber
23
23
 
24
24
  code =
25
25
  case color
26
+ when :blue then 34
26
27
  when :red then 31
27
28
  when :green then 32
28
29
  when :yellow then 33
@@ -3,6 +3,8 @@
3
3
  module Timber
4
4
  class CLI
5
5
  module Messages
6
+ include IOHelper
7
+
6
8
  extend self
7
9
 
8
10
  APP_URL = "https://app.timber.io"
@@ -41,7 +43,12 @@ message.rstrip
41
43
 
42
44
  def commit_and_deploy_reminder
43
45
  message = <<-MESSAGE
44
- Last step! Commit these changes and deploy. 🚀
46
+ Last step!
47
+
48
+ #{colorize("git add config/initializers/timber.rb", :blue)}
49
+ #{colorize("git commit -am 'Install Timber'", :blue)}
50
+
51
+ #{colorize("push and deploy", :blue)} 🚀
45
52
  MESSAGE
46
53
  message.rstrip
47
54
  end
@@ -75,7 +82,7 @@ Get free data on Timeber!
75
82
  * Get ✨ 50mb✨ for following #{TWITTER_HANDLE} on twitter
76
83
 
77
84
  (Your account will be credited within 2-3 business days.
78
- If you do not notice a credit please contact us: #{@support_email})
85
+ If you do not notice a credit please contact us: #{SUPPORT_EMAIL})
79
86
  MESSAGE
80
87
  message.rstrip
81
88
  end
@@ -94,11 +101,11 @@ message.rstrip
94
101
 
95
102
  def heroku_install(app)
96
103
  message = <<-MESSAGE
97
- Now we need to send your logs to the Timber service.
104
+ Now we need to send your logs from Heroku to Timber.
98
105
 
99
- Please run this command in a separate terminal and return back here when complete:
106
+ Please run this command in a separate terminal, return back when complete:
100
107
 
101
- heroku drains:add #{app.heroku_drain_url}
108
+ #{colorize("heroku drains:add #{app.heroku_drain_url}", :blue)}
102
109
 
103
110
  Note: Your Heroku app must be generating logs for this to work.
104
111
  MESSAGE
@@ -107,24 +114,29 @@ message.rstrip
107
114
 
108
115
  def no_api_key_provided
109
116
  message = <<-MESSAGE
110
- Woops! You didn't provide an API key. You can do so via:
117
+ Hey there! Welcome to Timber. In order to proceed, you'll need an API key.
118
+ If you already have one, you can run this installer like:
111
119
 
112
- bundle exec timber install my-api-key
120
+ #{colorize("bundle exec timber install my-api-key", :blue)}
113
121
 
114
122
  #{obtain_key_instructions}
115
123
  MESSAGE
116
- message.rstrip
124
+ message.rstrip
117
125
  end
118
126
 
119
127
  def obtain_key_instructions
120
128
  message = <<-MESSAGE
121
129
  Don't have a key? Head over to:
122
130
 
123
- https://app.timber.io
131
+ #{colorize("https://app.timber.io", :blue)}
124
132
 
125
133
  Once there, create an application. Your API key will be displayed afterwards.
126
134
  For more detailed instructions, checkout our docs page:
135
+
127
136
  https://timber.io/docs/app/obtain-api-key/
137
+
138
+ If you're confused, don't hesitate to contact us: #{SUPPORT_EMAIL}
139
+
128
140
  MESSAGE
129
141
  message.rstrip
130
142
  end
data/lib/timber/config.rb CHANGED
@@ -27,6 +27,7 @@ module Timber
27
27
  def initialize
28
28
  @capture_http_bodies = true
29
29
  @capture_http_body_content_types = [FORM_URL_ENCODED_CONTENT_TYPE, JSON_CONTENT_TYPE]
30
+ @http_body_limit = 2000
30
31
  end
31
32
 
32
33
  # Enables and disables the capturing of HTTP bodies in `Events::HTTPServerRequest`,
@@ -47,6 +48,12 @@ module Timber
47
48
  @debug_logger
48
49
  end
49
50
 
51
+ # Truncates captured HTTP bodies to this specified limit. The default is `2000`.
52
+ # If you want to capture more data, you can raise this to a maximum of `5000`,
53
+ # or lower this to be more efficient with data.
54
+ def http_body_limit
55
+ @http_body_limit
56
+ end
50
57
 
51
58
  # This is the logger Timber writes to. It should be set to your global
52
59
  # logger to keep the logging destination consitent. Please see `delegate_logger_to`
@@ -2,6 +2,7 @@ require "timber/contexts/custom"
2
2
  require "timber/contexts/http"
3
3
  require "timber/contexts/organization"
4
4
  require "timber/contexts/runtime"
5
+ require "timber/contexts/session"
5
6
  require "timber/contexts/system"
6
7
  require "timber/contexts/user"
7
8
 
@@ -0,0 +1,21 @@
1
+ module Timber
2
+ module Contexts
3
+ # The session context tracks the current session for the given user.
4
+ #
5
+ # @note This is tracked automatically with the `Integrations::Rack::SessionContext` rack
6
+ # middleware.
7
+ class Session < Context
8
+ @keyspace = :session
9
+
10
+ attr_reader :id
11
+
12
+ def initialize(attributes)
13
+ @id = attributes[:id] || raise(ArgumentError.new(":id is required"))
14
+ end
15
+
16
+ def as_json(_options = {})
17
+ {id: Timber::Util::Object.try(id, :to_s)}
18
+ end
19
+ end
20
+ end
21
+ end
@@ -2,33 +2,8 @@ module Timber
2
2
  module Contexts
3
3
  # The user context tracks the currently authenticated user.
4
4
  #
5
- # You will want to add this context at the time log the user in, typically
6
- # during the authentication flow.
7
- #
8
- # Note: Timber will attempt to automatically add this if you add a #current_user
9
- # method to your controllers. Most authentication solutions do this for you automatically.
10
- #
11
- # @example Basic example
12
- # user_context = Timber::Contexts::User.new(id: "abc1234", name: "Ben Johnson")
13
- # Timber::CurrentContext.with(user_context) do
14
- # # Logging will automatically include this context
15
- # logger.info("This is a log message")
16
- # end
17
- #
18
- # @example Rails example
19
- # class ApplicationController < ActionController::Base
20
- # around_filter :capture_user_context
21
- # private
22
- # def capture_user_context
23
- # if current_user
24
- # user_context = Timber::Contexts::User.new(id: current_user.id,
25
- # name: current_user.name, email: current_user.email)
26
- # Timber::CurrentContext.with(user_context) { yield }
27
- # else
28
- # yield
29
- # end
30
- # end
31
- # end
5
+ # @note This is tracked automatically with the `Integrations::Rack::UserContext` rack
6
+ # middleware.
32
7
  class User < Context
33
8
  @keyspace = :user
34
9
 
@@ -7,12 +7,14 @@ module Timber
7
7
  # @note This event should be installed automatically through integrations,
8
8
  # such as the {Integrations::ActionController::LogSubscriber} integration.
9
9
  class ControllerCall < Timber::Event
10
+ PASSWORD_NAME = 'password'.freeze
11
+
10
12
  attr_reader :controller, :action, :params, :format
11
13
 
12
14
  def initialize(attributes)
13
15
  @controller = attributes[:controller] || raise(ArgumentError.new(":controller is required"))
14
16
  @action = attributes[:action] || raise(ArgumentError.new(":action is required"))
15
- @params = attributes[:params]
17
+ @params = sanitize_params(attributes[:params])
16
18
  @format = attributes[:format]
17
19
  end
18
20
 
@@ -44,6 +46,22 @@ module Timber
44
46
  params.to_json
45
47
  end
46
48
  end
49
+
50
+ def sanitize_params(params)
51
+ if params.is_a?(::Hash)
52
+ params.each_with_object({}) do |(k, v), h|
53
+ k = k.to_s.downcase
54
+ case k
55
+ when PASSWORD_NAME
56
+ h[k] = SANITIZED_VALUE
57
+ else
58
+ h[k] = v
59
+ end
60
+ end
61
+ else
62
+ params
63
+ end
64
+ end
47
65
  end
48
66
  end
49
67
  end
@@ -19,7 +19,10 @@ module Timber
19
19
  @scheme = attributes[:scheme] || raise(ArgumentError.new(":scheme is required"))
20
20
  @request_id = attributes[:request_id]
21
21
 
22
- @body = Util::HTTPEvent.normalize_body(@headers["content-type"], attributes[:body])
22
+ # This is disabled for now. The ControllerCall event records the parsed params.
23
+ # This should be sufficient for body inspection. If we come across a case where
24
+ # it is not we can consider re-enabling this.
25
+ # @body = Util::HTTPEvent.normalize_body(attributes[:body])
23
26
  end
24
27
 
25
28
  def to_hash
@@ -1,6 +1,7 @@
1
1
  require "timber/integrations/rack/exception_event"
2
2
  require "timber/integrations/rack/http_context"
3
3
  require "timber/integrations/rack/http_events"
4
+ require "timber/integrations/rack/session_context"
4
5
  require "timber/integrations/rack/user_context"
5
6
 
6
7
  module Timber
@@ -9,7 +10,7 @@ module Timber
9
10
  # All available middlewares. The order is relevant. Middlewares that set
10
11
  # context are added first so that context is included in subsequent log lines.
11
12
  def self.middlewares
12
- @middlewares ||= [HTTPContext, UserContext, HTTPEvents, ExceptionEvent]
13
+ @middlewares ||= [HTTPContext, SessionContext, UserContext, HTTPEvents, ExceptionEvent]
13
14
  end
14
15
  end
15
16
  end
@@ -0,0 +1,37 @@
1
+ module Timber
2
+ module Integrations
3
+ module Rack
4
+ # Reponsible for adding the Session context for applications that use `Rack`.
5
+ class SessionContext
6
+ def initialize(app)
7
+ @app = app
8
+ end
9
+
10
+ def call(env)
11
+ id = get_session_id(env)
12
+ if id
13
+ context = Contexts::Session.new(id: get_session_id(env))
14
+ CurrentContext.with(context) do
15
+ @app.call(env)
16
+ end
17
+ else
18
+ @app.call(env)
19
+ end
20
+ end
21
+
22
+ private
23
+ def get_session_id(env)
24
+ if env['rack.session']
25
+ begin
26
+ env['rack.session'].id
27
+ rescue Exception
28
+ nil
29
+ end
30
+ else
31
+ nil
32
+ end
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -3,7 +3,7 @@ module Timber
3
3
  # `Logger` and the log device that you set it up with.
4
4
  class LogEntry #:nodoc:
5
5
  DT_PRECISION = 6.freeze
6
- SCHEMA = "https://raw.githubusercontent.com/timberio/log-event-json-schema/1.2.20/schema.json".freeze
6
+ SCHEMA = "https://raw.githubusercontent.com/timberio/log-event-json-schema/1.2.21/schema.json".freeze
7
7
 
8
8
  attr_reader :context_snapshot, :event, :level, :message, :progname, :tags, :time, :time_ms
9
9
 
@@ -1,8 +1,9 @@
1
1
  module Timber
2
2
  module Util
3
3
  module HTTPEvent
4
- BODY_LIMIT = 5_000.freeze
4
+ AUTHORIZATION_HEADER = 'authorization'.freeze
5
5
  QUERY_STRING_LIMIT = 5_000.freeze
6
+ SANITIZED_VALUE = '[sanitized]'.freeze
6
7
 
7
8
  extend self
8
9
 
@@ -20,7 +21,7 @@ module Timber
20
21
  body = body.body.to_s
21
22
  end
22
23
 
23
- body[0..(BODY_LIMIT - 1)]
24
+ body[0..(Config.instance.http_body_limit - 1)]
24
25
  else
25
26
  # Drop the body if it is not a format we want to capture.
26
27
  # This gives users more control to avoid loggin files, etc.
@@ -31,7 +32,13 @@ module Timber
31
32
  def normalize_headers(headers)
32
33
  if headers.is_a?(::Hash)
33
34
  headers.each_with_object({}) do |(k, v), h|
34
- h[k.to_s.downcase] = v
35
+ k = k.to_s.downcase
36
+ case k
37
+ when AUTHORIZATION_HEADER
38
+ h[k] = SANITIZED_VALUE
39
+ else
40
+ h[k] = v
41
+ end
35
42
  end
36
43
  else
37
44
  headers
@@ -1,3 +1,3 @@
1
1
  module Timber
2
- VERSION = "2.0.0"
2
+ VERSION = "2.0.1"
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Timber Technologies, Inc.
@@ -160,6 +160,7 @@ files:
160
160
  - lib/timber/contexts/http.rb
161
161
  - lib/timber/contexts/organization.rb
162
162
  - lib/timber/contexts/runtime.rb
163
+ - lib/timber/contexts/session.rb
163
164
  - lib/timber/contexts/system.rb
164
165
  - lib/timber/contexts/user.rb
165
166
  - lib/timber/current_context.rb
@@ -189,6 +190,7 @@ files:
189
190
  - lib/timber/integrations/rack/exception_event.rb
190
191
  - lib/timber/integrations/rack/http_context.rb
191
192
  - lib/timber/integrations/rack/http_events.rb
193
+ - lib/timber/integrations/rack/session_context.rb
192
194
  - lib/timber/integrations/rack/user_context.rb
193
195
  - lib/timber/integrations/rails/rack_logger.rb
194
196
  - lib/timber/integrator.rb