timber 2.3.1 → 2.3.2
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 +7 -12
- data/CHANGELOG.md +9 -1
- data/lib/timber/log_entry.rb +37 -1
- data/lib/timber/util/hash.rb +6 -5
- data/lib/timber/version.rb +1 -1
- data/spec/spec_helper.rb +2 -0
- data/spec/timber/log_entry_spec.rb +39 -0
- metadata +1 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 373352a84897146620f309326fc062b02878325a
|
4
|
+
data.tar.gz: 96e89b0e9e0fed80d606e24878f8913e57e41905
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2d51f28a5d9a87976411f2b72ccfc20ab2048df76f97fed76a0529aa96950e971d7dff8b62dc6f5a83e5f92a0acf9572a148e6ef8e9ee83dae2872bdb54c2efc
|
7
|
+
data.tar.gz: b5b37925111a637b8eae96901660f15801b94501f191a4100d65e15539f6115bf4e1bc823be695d98ffff2f462918aeb1fc2fb8661e0550e3f303096588ab80c
|
data/.travis.yml
CHANGED
@@ -5,8 +5,9 @@ rvm:
|
|
5
5
|
- 1.9.3
|
6
6
|
- 2.2.6
|
7
7
|
- 2.3.3
|
8
|
-
- 2.4.
|
9
|
-
- jruby
|
8
|
+
- 2.4.2
|
9
|
+
- jruby-1.7.26
|
10
|
+
- jruby-9.1.9.0
|
10
11
|
gemfile:
|
11
12
|
- gemfiles/rails-3.0.gemfile
|
12
13
|
- gemfiles/rails-3.1.gemfile
|
@@ -14,7 +15,6 @@ gemfile:
|
|
14
15
|
- gemfiles/rails-4.0.gemfile
|
15
16
|
- gemfiles/rails-4.1.gemfile
|
16
17
|
- gemfiles/rails-4.2.gemfile
|
17
|
-
- gemfiles/rails-4.2.gemfile
|
18
18
|
- gemfiles/rails-5.0.gemfile
|
19
19
|
- gemfiles/rails-5.1.gemfile
|
20
20
|
- gemfiles/rails-edge.gemfile
|
@@ -38,15 +38,10 @@ matrix:
|
|
38
38
|
gemfile: "gemfiles/rails-3.2.gemfile"
|
39
39
|
allow_failures:
|
40
40
|
- rvm: 1.9.3 # bundler wont install the gems
|
41
|
-
- rvm: 2.4.
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
gemfile: gemfiles/rails-5.0.gemfile
|
46
|
-
- rvm: jruby
|
47
|
-
gemfile: gemfiles/rails-5.1.gemfile
|
48
|
-
- rvm: jruby
|
49
|
-
gemfile: gemfiles/rails-edge.gemfile
|
41
|
+
- rvm: 2.4.2
|
42
|
+
gemfile: gemfiles/rails-4.0.gemfile
|
43
|
+
- rvm: 2.4.2
|
44
|
+
gemfile: gemfiles/rails-4.1.gemfile
|
50
45
|
notifications:
|
51
46
|
email: false
|
52
47
|
slack:
|
data/CHANGELOG.md
CHANGED
@@ -7,6 +7,13 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
7
7
|
|
8
8
|
## [Unreleased]
|
9
9
|
|
10
|
+
## [2.3.2] - 2017-09-27
|
11
|
+
|
12
|
+
### Fixed
|
13
|
+
|
14
|
+
- Drop ASCII-8BIT (binary) data before encoding to JSON. This resolves encoding errors during
|
15
|
+
this process.
|
16
|
+
|
10
17
|
## [2.3.1] - 2017-09-26
|
11
18
|
|
12
19
|
### Fixed
|
@@ -52,7 +59,8 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
|
|
52
59
|
instead of applying back pressure.
|
53
60
|
|
54
61
|
|
55
|
-
[Unreleased]: https://github.com/timberio/timber-ruby/compare/v2.3.
|
62
|
+
[Unreleased]: https://github.com/timberio/timber-ruby/compare/v2.3.2...HEAD
|
63
|
+
[2.3.2]: https://github.com/timberio/timber-ruby/compare/v2.3.1...v2.3.2
|
56
64
|
[2.3.1]: https://github.com/timberio/timber-ruby/compare/v2.3.0...v2.3.1
|
57
65
|
[2.3.0]: https://github.com/timberio/timber-ruby/compare/v2.2.2...v2.3.0
|
58
66
|
[2.2.2]: https://github.com/timberio/timber-ruby/compare/v2.2.2...v2.2.3
|
data/lib/timber/log_entry.rb
CHANGED
@@ -8,6 +8,7 @@ module Timber
|
|
8
8
|
# Represents a new log entry into the log. This is an intermediary class between
|
9
9
|
# `Logger` and the log device that you set it up with.
|
10
10
|
class LogEntry #:nodoc:
|
11
|
+
BINARY_LIMIT_THRESHOLD = 1_000.freeze
|
11
12
|
DT_PRECISION = 6.freeze
|
12
13
|
MESSAGE_MAX_BYTES = 8192.freeze
|
13
14
|
SCHEMA = "https://raw.githubusercontent.com/timberio/log-event-json-schema/v3.1.1/schema.json".freeze
|
@@ -73,7 +74,30 @@ module Timber
|
|
73
74
|
hash
|
74
75
|
end
|
75
76
|
|
76
|
-
|
77
|
+
# Preparing a log event for JSON should remove any blank values. Timber strictly
|
78
|
+
# validates incoming data, including message size. Blank values will fail validation.
|
79
|
+
# Moreover, binary data (ASCII-8BIT) generally cannot be encoded into JSON because it
|
80
|
+
# contains characters outside of the valid UTF-8 space.
|
81
|
+
Util::Hash.deep_reduce(hash) do |k, v, h|
|
82
|
+
# Discard blank values
|
83
|
+
if !v.nil? && (!v.respond_to?(:length) || v.length > 0)
|
84
|
+
# If the value is a binary string, give it special treatment
|
85
|
+
if v.respond_to?(:encoding) && v.encoding == ::Encoding::ASCII_8BIT
|
86
|
+
# Only keep binary values less than a certain size. Sizes larger than this
|
87
|
+
# are almost always file uploads and data we do not want to log.
|
88
|
+
if v.length < BINARY_LIMIT_THRESHOLD
|
89
|
+
# Attempt to safely encode the data to UTF-8
|
90
|
+
encoded_value = encode_string(v)
|
91
|
+
if !encoded_value.nil?
|
92
|
+
h[k] = encoded_value
|
93
|
+
end
|
94
|
+
end
|
95
|
+
else
|
96
|
+
# Keep all other values
|
97
|
+
h[k] = v
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
77
101
|
end
|
78
102
|
|
79
103
|
def inspect
|
@@ -112,5 +136,17 @@ module Timber
|
|
112
136
|
def formatted_dt
|
113
137
|
@formatted_dt ||= time.iso8601(DT_PRECISION)
|
114
138
|
end
|
139
|
+
|
140
|
+
# Attempts to encode a non UTF-8 string into UTF-8, discarding invalid characters.
|
141
|
+
# If it fails, a nil is returned.
|
142
|
+
def encode_string(string)
|
143
|
+
string.encode('UTF-8', {
|
144
|
+
:invalid => :replace,
|
145
|
+
:undef => :replace,
|
146
|
+
:replace => '?'
|
147
|
+
})
|
148
|
+
rescue Exception
|
149
|
+
nil
|
150
|
+
end
|
115
151
|
end
|
116
152
|
end
|
data/lib/timber/util/hash.rb
CHANGED
@@ -6,19 +6,20 @@ module Timber
|
|
6
6
|
|
7
7
|
extend self
|
8
8
|
|
9
|
-
|
9
|
+
# Deeply reduces a hash into a new hash, passing the current key, value,
|
10
|
+
# and accumulated map up to that point. This allows the caller to
|
11
|
+
# conditionally rebuild the hash.
|
12
|
+
def deep_reduce(hash, &block)
|
10
13
|
new_hash = {}
|
11
14
|
|
12
15
|
hash.each do |k, v|
|
13
16
|
v = if v.is_a?(::Hash)
|
14
|
-
|
17
|
+
deep_reduce(v, &block)
|
15
18
|
else
|
16
19
|
v
|
17
20
|
end
|
18
21
|
|
19
|
-
|
20
|
-
new_hash[k] = v
|
21
|
-
end
|
22
|
+
block.call(k, v, new_hash)
|
22
23
|
end
|
23
24
|
|
24
25
|
new_hash
|
data/lib/timber/version.rb
CHANGED
data/spec/spec_helper.rb
CHANGED
@@ -20,6 +20,8 @@ if !ENV["RAILS_23"]
|
|
20
20
|
require File.join(File.dirname(__FILE__), 'support', 'active_record')
|
21
21
|
end
|
22
22
|
|
23
|
+
RSpec::Support::ObjectFormatter.default_instance.max_formatted_output_length = 5_000
|
24
|
+
|
23
25
|
RSpec.configure do |config|
|
24
26
|
config.color = true
|
25
27
|
config.order = :random
|
@@ -3,6 +3,45 @@ require "spec_helper"
|
|
3
3
|
describe Timber::LogEntry, :rails_23 => true do
|
4
4
|
let(:time) { Time.utc(2016, 9, 1, 12, 0, 0) }
|
5
5
|
|
6
|
+
describe "#as_json" do
|
7
|
+
it "should drop nil value keys" do
|
8
|
+
event = Timber::Events::Custom.new(type: :event_type, message: "event_message", data: {a: nil})
|
9
|
+
log_entry = described_class.new("INFO", time, nil, "log message", {}, event)
|
10
|
+
hash = log_entry.as_json
|
11
|
+
expect(hash.key?(:event)).to be false
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should drop blank string value keys" do
|
15
|
+
event = Timber::Events::Custom.new(type: :event_type, message: "event_message", data: {a: ""})
|
16
|
+
log_entry = described_class.new("INFO", time, nil, "log message", {}, event)
|
17
|
+
hash = log_entry.as_json
|
18
|
+
expect(hash.key?(:event)).to be false
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should drop empty array value keys" do
|
22
|
+
event = Timber::Events::Custom.new(type: :event_type, message: "event_message", data: {a: []})
|
23
|
+
log_entry = described_class.new("INFO", time, nil, "log message", {}, event)
|
24
|
+
hash = log_entry.as_json
|
25
|
+
expect(hash.key?(:event)).to be false
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should drop ascii-8bit (binary) value keys" do
|
29
|
+
binary = ("a" * 1001).force_encoding("ASCII-8BIT")
|
30
|
+
event = Timber::Events::Custom.new(type: :event_type, message: "event_message", data: {a: binary})
|
31
|
+
log_entry = described_class.new("INFO", time, nil, "log message", {}, event)
|
32
|
+
hash = log_entry.as_json
|
33
|
+
expect(hash.key?(:event)).to be false
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should keep ascii-8bit (binary) values below the threshold" do
|
37
|
+
binary = "test".force_encoding("ASCII-8BIT")
|
38
|
+
event = Timber::Events::Custom.new(type: :event_type, message: "event_message", data: {a: binary})
|
39
|
+
log_entry = described_class.new("INFO", time, nil, "log message", {}, event)
|
40
|
+
hash = log_entry.as_json
|
41
|
+
expect(hash[:event][:custom][:event_type][:a].encoding).to eq(::Encoding::UTF_8)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
6
45
|
describe "#to_msgpack" do
|
7
46
|
it "should encode properly with an event and context" do
|
8
47
|
event = Timber::Events::Custom.new(type: :event_type, message: "event_message", data: {a: 1})
|