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 +4 -4
- data/README.md +1 -1
- data/lib/timber/cli/install.rb +3 -3
- data/lib/timber/cli/io_helper.rb +1 -0
- data/lib/timber/cli/messages.rb +21 -9
- data/lib/timber/config.rb +7 -0
- data/lib/timber/contexts.rb +1 -0
- data/lib/timber/contexts/session.rb +21 -0
- data/lib/timber/contexts/user.rb +2 -27
- data/lib/timber/events/controller_call.rb +19 -1
- data/lib/timber/events/http_server_request.rb +4 -1
- data/lib/timber/integrations/rack.rb +2 -1
- data/lib/timber/integrations/rack/session_context.rb +37 -0
- data/lib/timber/log_entry.rb +1 -1
- data/lib/timber/util/http_event.rb +10 -3
- data/lib/timber/version.rb +1 -1
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 59dfc96fa6eee2260cbfb09b2fb6eddfcae573e6
|
4
|
+
data.tar.gz: dce374823788ebcfeb4f036e2c01a09170354d2e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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:
|
data/lib/timber/cli/install.rb
CHANGED
@@ -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
|
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
|
84
|
+
puts Messages.commit_and_deploy_reminder
|
85
85
|
|
86
86
|
api.event!(:success)
|
87
87
|
|
data/lib/timber/cli/io_helper.rb
CHANGED
data/lib/timber/cli/messages.rb
CHANGED
@@ -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!
|
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: #{
|
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
|
104
|
+
Now we need to send your logs from Heroku to Timber.
|
98
105
|
|
99
|
-
Please run this command in a separate terminal
|
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
|
-
|
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`
|
data/lib/timber/contexts.rb
CHANGED
@@ -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
|
data/lib/timber/contexts/user.rb
CHANGED
@@ -2,33 +2,8 @@ module Timber
|
|
2
2
|
module Contexts
|
3
3
|
# The user context tracks the currently authenticated user.
|
4
4
|
#
|
5
|
-
#
|
6
|
-
#
|
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
|
-
|
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
|
data/lib/timber/log_entry.rb
CHANGED
@@ -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.
|
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
|
-
|
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..(
|
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
|
-
|
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
|
data/lib/timber/version.rb
CHANGED
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.
|
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
|