timber 2.5.1 → 2.6.0.pre.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +10 -1
- data/lib/timber/config.rb +2 -1
- data/lib/timber/contexts/custom.rb +10 -3
- data/lib/timber/contexts/http.rb +23 -7
- data/lib/timber/contexts/organization.rb +14 -3
- data/lib/timber/contexts/release.rb +17 -4
- data/lib/timber/contexts/runtime.rb +28 -9
- data/lib/timber/contexts/session.rb +11 -2
- data/lib/timber/contexts/system.rb +13 -3
- data/lib/timber/contexts/user.rb +22 -6
- data/lib/timber/events/controller_call.rb +14 -24
- data/lib/timber/events/custom.rb +8 -5
- data/lib/timber/events/error.rb +11 -31
- data/lib/timber/events/http_request.rb +39 -13
- data/lib/timber/events/http_response.rb +32 -14
- data/lib/timber/events/sql_query.rb +10 -7
- data/lib/timber/events/template_render.rb +11 -5
- data/lib/timber/log_entry.rb +7 -31
- data/lib/timber/logger.rb +1 -5
- data/lib/timber/util.rb +2 -2
- data/lib/timber/util/attribute_normalizer.rb +90 -0
- data/lib/timber/util/hash.rb +51 -1
- data/lib/timber/util/non_nil_hash_builder.rb +38 -0
- data/lib/timber/version.rb +1 -1
- data/spec/timber/events/error_spec.rb +8 -22
- data/spec/timber/events/http_request_spec.rb +1 -1
- data/spec/timber/events_spec.rb +1 -1
- data/spec/timber/integrations/action_dispatch/debug_exceptions_spec.rb +1 -1
- data/spec/timber/log_entry_spec.rb +0 -39
- data/spec/timber/logger_spec.rb +0 -5
- data/spec/timber/util/attribute_normalizer_spec.rb +90 -0
- metadata +8 -8
- data/lib/timber/util/http_event.rb +0 -69
- data/lib/timber/util/object.rb +0 -15
- data/spec/timber/util/http_event_spec.rb +0 -15
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 10838667c7f285fea9c51270f12594b2106299e1
|
4
|
+
data.tar.gz: f91eaaac75c0ed243686771c415a3f44d6c431b3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8cc093229929a57566e15f4fe81a9f2fbf36c0259a85123e43cbe077e9a14828147620b60be1a7953560ac691923146dcccb2075adbe64fb331bae9a1e388206
|
7
|
+
data.tar.gz: 5478c747ded3aa62d3fcf0b877e5e09bccafb94c72e1b4812b2dea0cac2aa5fe2e86435532c66f16b35596178c64d2502a40687fe97437f13e6db641cbb296b8
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [2.6.0-beta1] - 2017-10-28
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
|
14
|
+
- Encoding and rewind issues for file upload parameters have been resolved. Timber
|
15
|
+
improved attribute normalization across all contexts and events, ignoring binary
|
16
|
+
values like this in general.
|
17
|
+
|
10
18
|
## [2.5.1] - 2017-10-27
|
11
19
|
|
12
20
|
### Fixed
|
@@ -103,7 +111,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
103
111
|
instead of applying back pressure.
|
104
112
|
|
105
113
|
|
106
|
-
[Unreleased]: https://github.com/timberio/timber-ruby/compare/v2.
|
114
|
+
[Unreleased]: https://github.com/timberio/timber-ruby/compare/v2.6.0-beta1...HEAD
|
115
|
+
[2.6.0-beta1]: https://github.com/timberio/timber-ruby/compare/v2.5.1...v2.6.0-beta1
|
107
116
|
[2.5.1]: https://github.com/timberio/timber-ruby/compare/v2.5.0...v2.5.1
|
108
117
|
[2.5.0]: https://github.com/timberio/timber-ruby/compare/v2.4.0...v2.5.0
|
109
118
|
[2.4.0]: https://github.com/timberio/timber-ruby/compare/v2.3.4...v2.4.0
|
data/lib/timber/config.rb
CHANGED
@@ -25,6 +25,7 @@ module Timber
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
+
DEFAULT_HTTP_BODY_LIMIT = 2048.freeze
|
28
29
|
DEVELOPMENT_NAME = "development".freeze
|
29
30
|
PRODUCTION_NAME = "production".freeze
|
30
31
|
STAGING_NAME = "staging".freeze
|
@@ -36,7 +37,7 @@ module Timber
|
|
36
37
|
|
37
38
|
# @private
|
38
39
|
def initialize
|
39
|
-
@http_body_limit =
|
40
|
+
@http_body_limit = DEFAULT_HTTP_BODY_LIMIT
|
40
41
|
end
|
41
42
|
|
42
43
|
# Convenience method for logging debug statements to the debug logger
|
@@ -24,13 +24,20 @@ module Timber
|
|
24
24
|
attr_reader :type, :data
|
25
25
|
|
26
26
|
def initialize(attributes)
|
27
|
-
|
28
|
-
@
|
27
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
28
|
+
@type = normalizer.fetch!(:type, :symbol)
|
29
|
+
@data = normalizer.fetch!(:data, :hash)
|
29
30
|
end
|
30
31
|
|
31
32
|
# Builds a hash representation containing simple objects, suitable for serialization (JSON).
|
33
|
+
def to_hash
|
34
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
35
|
+
h.add(type, data)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
32
39
|
def as_json(options = {})
|
33
|
-
|
40
|
+
to_hash
|
34
41
|
end
|
35
42
|
end
|
36
43
|
end
|
data/lib/timber/contexts/http.rb
CHANGED
@@ -13,22 +13,38 @@ module Timber
|
|
13
13
|
# @note This context should be installed automatically through the,
|
14
14
|
# {Intregrations::Rack::HTTPContext} Rack middleware.
|
15
15
|
class HTTP < Context
|
16
|
+
HOST_MAX_BYTES = 256.freeze
|
17
|
+
METHOD_MAX_BYTES = 20.freeze
|
18
|
+
PATH_MAX_BYTES = 2048.freeze
|
19
|
+
REMOTE_ADDR_MAX_BYTES = 256.freeze
|
20
|
+
REQUEST_ID_MAX_BYTES = 256.freeze
|
21
|
+
|
16
22
|
@keyspace = :http
|
17
23
|
|
18
24
|
attr_reader :host, :method, :path, :remote_addr, :request_id
|
19
25
|
|
20
26
|
def initialize(attributes)
|
21
|
-
|
22
|
-
@
|
23
|
-
@
|
24
|
-
@
|
25
|
-
@
|
27
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
28
|
+
@host = normalizer.fetch(:host, :string, :limit => HOST_MAX_BYTES)
|
29
|
+
@method = normalizer.fetch!(:method, :string, :upcase => true, :limit => METHOD_MAX_BYTES)
|
30
|
+
@path = normalizer.fetch(:path, :string, :limit => PATH_MAX_BYTES)
|
31
|
+
@remote_addr = normalizer.fetch(:remote_addr, :string, :limit => REMOTE_ADDR_MAX_BYTES)
|
32
|
+
@request_id = normalizer.fetch(:request_id, :string, :limit => REQUEST_ID_MAX_BYTES)
|
26
33
|
end
|
27
34
|
|
28
35
|
# Builds a hash representation containing simple objects, suitable for serialization (JSON).
|
36
|
+
def to_hash
|
37
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
38
|
+
h.add(:host, host)
|
39
|
+
h.add(:method, method)
|
40
|
+
h.add(:path, path)
|
41
|
+
h.add(:remote_addr, remote_addr)
|
42
|
+
h.add(:request_id, request_id)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
29
46
|
def as_json(_options = {})
|
30
|
-
|
31
|
-
:request_id => request_id}
|
47
|
+
to_hash
|
32
48
|
end
|
33
49
|
end
|
34
50
|
end
|
@@ -19,18 +19,29 @@ module Timber
|
|
19
19
|
# end
|
20
20
|
#
|
21
21
|
class Organization < Context
|
22
|
+
ID_MAX_BYTES = 256.freeze
|
23
|
+
NAME_MAX_BYTES = 256.freeze
|
24
|
+
|
22
25
|
@keyspace = :organization
|
23
26
|
|
24
27
|
attr_reader :id, :name
|
25
28
|
|
26
29
|
def initialize(attributes)
|
27
|
-
|
28
|
-
@
|
30
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
31
|
+
@id = normalizer.fetch(:id, :string, :limit => ID_MAX_BYTES)
|
32
|
+
@name = normalizer.fetch(:name, :string, :limit => NAME_MAX_BYTES)
|
29
33
|
end
|
30
34
|
|
31
35
|
# Builds a hash representation containing simple objects, suitable for serialization (JSON).
|
36
|
+
def to_hash
|
37
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
38
|
+
h.add(:id, id)
|
39
|
+
h.add(:name, name)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
32
43
|
def as_json(_options = {})
|
33
|
-
|
44
|
+
to_hash
|
34
45
|
end
|
35
46
|
end
|
36
47
|
end
|
@@ -8,6 +8,10 @@ module Timber
|
|
8
8
|
#
|
9
9
|
# @note To automatically set this context, see {.from_env}.
|
10
10
|
class Release < Context
|
11
|
+
COMMIT_HASH_MAX_BYTES = 256.freeze
|
12
|
+
CREATED_AT_MAX_BYTES = 256.freeze
|
13
|
+
VERSION_MAX_BYTES = 256.freeze
|
14
|
+
|
11
15
|
@keyspace = :release
|
12
16
|
|
13
17
|
class << self
|
@@ -36,14 +40,23 @@ module Timber
|
|
36
40
|
attr_reader :commit_hash, :created_at, :version
|
37
41
|
|
38
42
|
def initialize(attributes)
|
39
|
-
|
40
|
-
@
|
41
|
-
@
|
43
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
44
|
+
@commit_hash = normalizer.fetch(:commit_hash, :string, :limit => COMMIT_HASH_MAX_BYTES)
|
45
|
+
@created_at = normalizer.fetch(:created_at, :string, :limit => CREATED_AT_MAX_BYTES)
|
46
|
+
@version = normalizer.fetch(:version, :string, :limit => VERSION_MAX_BYTES)
|
42
47
|
end
|
43
48
|
|
44
49
|
# Builds a hash representation containing simple objects, suitable for serialization (JSON).
|
50
|
+
def to_hash
|
51
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
52
|
+
h.add(:commit_hash, commit_hash)
|
53
|
+
h.add(:created_at, created_at)
|
54
|
+
h.add(:version, version)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
45
58
|
def as_json(_options = {})
|
46
|
-
|
59
|
+
to_hash
|
47
60
|
end
|
48
61
|
end
|
49
62
|
end
|
@@ -7,24 +7,43 @@ module Timber
|
|
7
7
|
# origin in your code. For example, if you are debugging a specific class, you can narrow
|
8
8
|
# by that class and see only it's logs.
|
9
9
|
class Runtime < Context
|
10
|
+
APPLICATION_MAX_BYTES = 256.freeze
|
11
|
+
CLASS_NAME_MAX_BYTES = 256.freeze
|
12
|
+
FILE_MAX_BYTES = 1024.freeze
|
13
|
+
FUNCTION_MAX_BYTES = 256.freeze
|
14
|
+
MODULE_NAME_MAX_BYTES = 256.freeze
|
15
|
+
VM_PID_MAX_BYTES = 256.freeze
|
16
|
+
|
10
17
|
@keyspace = :runtime
|
11
18
|
|
12
19
|
attr_reader :application, :class_name, :file, :function, :line, :module_name, :vm_pid
|
13
20
|
|
14
21
|
def initialize(attributes)
|
15
|
-
|
16
|
-
@
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
20
|
-
@
|
21
|
-
@
|
22
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
23
|
+
@application = normalizer.fetch(:application, :string, :limit => APPLICATION_MAX_BYTES)
|
24
|
+
@class_name = normalizer.fetch(:class_name, :string, :limit => CLASS_NAME_MAX_BYTES)
|
25
|
+
@file = normalizer.fetch(:file, :string, :limit => FILE_MAX_BYTES)
|
26
|
+
@function = normalizer.fetch(:function, :string, :limit => FUNCTION_MAX_BYTES)
|
27
|
+
@line = normalizer.fetch(:line, :integer)
|
28
|
+
@module_name = normalizer.fetch(:module_name, :string, :limit => MODULE_NAME_MAX_BYTES)
|
29
|
+
@vm_pid = normalizer.fetch(:vm_pid, :string, :limit => VM_PID_MAX_BYTES)
|
22
30
|
end
|
23
31
|
|
24
32
|
# Builds a hash representation containing simple objects, suitable for serialization (JSON).
|
33
|
+
def to_hash
|
34
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
35
|
+
h.add(:application, application)
|
36
|
+
h.add(:class_name, class_name)
|
37
|
+
h.add(:file, file)
|
38
|
+
h.add(:function, function)
|
39
|
+
h.add(:line, line)
|
40
|
+
h.add(:module_name, module_name)
|
41
|
+
h.add(:vm_pid, vm_pid)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
25
45
|
def as_json(_options = {})
|
26
|
-
|
27
|
-
line: line, module_name: module_name, vm_pid: vm_pid}
|
46
|
+
to_hash
|
28
47
|
end
|
29
48
|
end
|
30
49
|
end
|
@@ -11,17 +11,26 @@ module Timber
|
|
11
11
|
# @note This is tracked automatically with the {Integrations::Rack::SessionContext} rack
|
12
12
|
# middleware.
|
13
13
|
class Session < Context
|
14
|
+
ID_MAX_BYTES = 256.freeze
|
15
|
+
|
14
16
|
@keyspace = :session
|
15
17
|
|
16
18
|
attr_reader :id
|
17
19
|
|
18
20
|
def initialize(attributes)
|
19
|
-
|
21
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
22
|
+
@id = normalizer.fetch!(:id, :string, :limit => ID_MAX_BYTES)
|
20
23
|
end
|
21
24
|
|
22
25
|
# Builds a hash representation containing simple objects, suitable for serialization (JSON).
|
26
|
+
def to_hash
|
27
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
28
|
+
h.add(:id, id)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
23
32
|
def as_json(_options = {})
|
24
|
-
|
33
|
+
to_hash
|
25
34
|
end
|
26
35
|
end
|
27
36
|
end
|
@@ -8,18 +8,28 @@ module Timber
|
|
8
8
|
# @note This is tracked automatically in {CurrentContext}. When the current context
|
9
9
|
# is initialized, the system context gets added automatically.
|
10
10
|
class System < Context
|
11
|
+
HOSTNAME_MAX_BYTES = 256.freeze
|
12
|
+
|
11
13
|
@keyspace = :system
|
12
14
|
|
13
15
|
attr_reader :hostname, :pid
|
14
16
|
|
15
17
|
def initialize(attributes)
|
16
|
-
|
17
|
-
@
|
18
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
19
|
+
@hostname = normalizer.fetch(:hostname, :string, :limit => HOSTNAME_MAX_BYTES)
|
20
|
+
@pid = normalizer.fetch(:pid, :integer)
|
18
21
|
end
|
19
22
|
|
20
23
|
# Builds a hash representation containing simple objects, suitable for serialization (JSON).
|
24
|
+
def to_hash
|
25
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
26
|
+
h.add(:hostname, hostname)
|
27
|
+
h.add(:pid, pid)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
21
31
|
def as_json(_options = {})
|
22
|
-
|
32
|
+
to_hash
|
23
33
|
end
|
24
34
|
end
|
25
35
|
end
|
data/lib/timber/contexts/user.rb
CHANGED
@@ -11,21 +11,37 @@ module Timber
|
|
11
11
|
# middleware for supported authentication frameworks. See {Integrations::Rack::UserContext}
|
12
12
|
# for more details.
|
13
13
|
class User < Context
|
14
|
+
ID_MAX_BYTES = 256.freeze
|
15
|
+
NAME_MAX_BYTES = 256.freeze
|
16
|
+
EMAIL_MAX_BYTES = 256.freeze
|
17
|
+
TYPE_MAX_BYTES = 256.freeze
|
18
|
+
|
14
19
|
@keyspace = :user
|
15
20
|
|
16
21
|
attr_reader :id, :name, :email, :type, :meta
|
17
22
|
|
18
23
|
def initialize(attributes)
|
19
|
-
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@
|
24
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
25
|
+
@id = normalizer.fetch(:id, :string, :limit => ID_MAX_BYTES)
|
26
|
+
@name = normalizer.fetch(:name, :string, :limit => NAME_MAX_BYTES)
|
27
|
+
@email = normalizer.fetch(:email, :string, :limit => EMAIL_MAX_BYTES)
|
28
|
+
@type = normalizer.fetch(:type, :string, :limit => TYPE_MAX_BYTES)
|
29
|
+
@meta = normalizer.fetch(:meta, :hash)
|
24
30
|
end
|
25
31
|
|
26
32
|
# Builds a hash representation containing simple objects, suitable for serialization (JSON).
|
33
|
+
def to_hash
|
34
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
35
|
+
h.add(:id, id)
|
36
|
+
h.add(:name, name)
|
37
|
+
h.add(:email, email)
|
38
|
+
h.add(:type, type)
|
39
|
+
h.add(:meta, meta)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
27
43
|
def as_json(_options = {})
|
28
|
-
|
44
|
+
to_hash
|
29
45
|
end
|
30
46
|
end
|
31
47
|
end
|
@@ -8,22 +8,30 @@ module Timber
|
|
8
8
|
# Processing by PagesController#home as HTML
|
9
9
|
#
|
10
10
|
# @note This event should be installed automatically through integrations,
|
11
|
-
# such as the {Integrations::ActionController
|
11
|
+
# such as the {Integrations::ActionController} integration.
|
12
12
|
class ControllerCall < Timber::Event
|
13
|
+
ACTION_MAX_BYTES = 256.freeze
|
14
|
+
FORMAT_MAX_BYTES = 256.freeze
|
15
|
+
CONTROLLER_MAX_BYTES = 256.freeze
|
13
16
|
PARAMS_JSON_MAX_BYTES = 32_768.freeze
|
14
17
|
PASSWORD_NAME = 'password'.freeze
|
15
18
|
|
16
19
|
attr_reader :controller, :action, :params, :format
|
17
20
|
|
18
21
|
def initialize(attributes)
|
19
|
-
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
22
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
23
|
+
@controller = normalizer.fetch!(:controller, :string, :limit => CONTROLLER_MAX_BYTES)
|
24
|
+
@action = normalizer.fetch!(:action, :string, :limit => ACTION_MAX_BYTES)
|
25
|
+
@params = normalizer.fetch(:params, :hash, :sanitize => [PASSWORD_NAME])
|
26
|
+
@format = normalizer.fetch(:format, :string, :limit => FORMAT_MAX_BYTES)
|
23
27
|
end
|
24
28
|
|
25
29
|
def to_hash
|
26
|
-
|
30
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
31
|
+
h.add(:controller, controller)
|
32
|
+
h.add(:action, action)
|
33
|
+
h.add(:params_json, params.to_json.byteslice(0, PARAMS_JSON_MAX_BYTES))
|
34
|
+
end
|
27
35
|
end
|
28
36
|
alias to_h to_hash
|
29
37
|
|
@@ -42,24 +50,6 @@ module Timber
|
|
42
50
|
end
|
43
51
|
message
|
44
52
|
end
|
45
|
-
|
46
|
-
private
|
47
|
-
def params_json
|
48
|
-
@params_json ||=
|
49
|
-
if params.nil? || params == {}
|
50
|
-
nil
|
51
|
-
else
|
52
|
-
params.to_json.byteslice(0, PARAMS_JSON_MAX_BYTES)
|
53
|
-
end
|
54
|
-
end
|
55
|
-
|
56
|
-
def sanitize_params(params)
|
57
|
-
if params.is_a?(::Hash)
|
58
|
-
Util::Hash.sanitize(params, [PASSWORD_NAME])
|
59
|
-
else
|
60
|
-
params
|
61
|
-
end
|
62
|
-
end
|
63
53
|
end
|
64
54
|
end
|
65
55
|
end
|
data/lib/timber/events/custom.rb
CHANGED
@@ -23,12 +23,13 @@ module Timber
|
|
23
23
|
# @option attributes [Hash] :data A hash of JSON encodable data to be stored with the
|
24
24
|
# log line.
|
25
25
|
def initialize(attributes)
|
26
|
-
|
27
|
-
@
|
26
|
+
normalizer = Util::AttributeNormalizer.new(attributes)
|
27
|
+
@type = normalizer.fetch!(:type, :symbol)
|
28
|
+
@message = normalizer.fetch!(:message, :string)
|
28
29
|
|
29
|
-
data =
|
30
|
+
data = normalizer.fetch!(:data, :hash)
|
30
31
|
|
31
|
-
if data.
|
32
|
+
if !data.nil? && data[:time_ms].is_a?(Time)
|
32
33
|
data[:time_ms] = Timer.duration_ms(data[:time_ms])
|
33
34
|
@message << " in #{data[:time_ms]}ms"
|
34
35
|
end
|
@@ -37,7 +38,9 @@ module Timber
|
|
37
38
|
end
|
38
39
|
|
39
40
|
def to_hash
|
40
|
-
|
41
|
+
@to_hash ||= Util::NonNilHashBuilder.build do |h|
|
42
|
+
h.add(type, data)
|
43
|
+
end
|
41
44
|
end
|
42
45
|
alias to_h to_hash
|
43
46
|
|