timber 2.0.19 → 2.0.20

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: 2e4d4e220779ebe8ea442c98c2f03f36cf12f438
4
- data.tar.gz: e995c553745a8839d306eea480d359063a779b9c
3
+ metadata.gz: 946dc64576210d225bbf4952fa78363705b3b87f
4
+ data.tar.gz: e972b58acf8efc60ebcc79746939d7bbceeadd06
5
5
  SHA512:
6
- metadata.gz: ca96f8e714fef59f4a14155b0376094928171636f2ca4cbb372ef928112d5e4c9c1f4be40c2cb856f94568d4139066e95d4544380fa043540c831a138f06a5d0
7
- data.tar.gz: 41e76ccddb69c9961330560d78c9d82d941e2af0ad91e6e506ae99628147ea3ff96f43c9979299fdaa84b3638adaf88512e1e1532f11c7b33aae8a5287853031
6
+ metadata.gz: f44fdf7da119df5a80cd1cb589f1c55d8fee39bfccd6cacf35eaf9b5944afdc227cb6d715473c651d3830035915bc62df11cae4c7c58a779331870fa23659d26
7
+ data.tar.gz: 7cad85ce7ea3c9df75fd2d3fc7e18df07d42d20f294bba6af8803dce710f7b9a7e0a8990ef243d3feff942807625ffb8b40bc2ecde89c98e2604a7e129c94533
@@ -1,3 +1,6 @@
1
+ require "base64"
2
+ require "net/https"
3
+
1
4
  module Timber
2
5
  module LogDevices
3
6
  # A highly efficient log device that buffers and delivers log messages over HTTPS to
@@ -80,6 +83,10 @@ module Timber
80
83
  # each HTTP payload. If the queue exceeds this limit an HTTP request will be issued. Bigger
81
84
  # payloads mean higher throughput, but also use more memory. Timber will not accept
82
85
  # payloads larger than 1mb.
86
+ # @option attributes [Symbol] :flush_continuously (true) This should only be disabled under
87
+ # special circumstsances (like test suites). Setting this to `false` disables the
88
+ # continuous flushing of log message. As a result, flushing must be handled externally
89
+ # via the #flush method.
83
90
  # @option attributes [Symbol] :flush_interval (1) How often the client should
84
91
  # attempt to deliver logs to the Timber API in fractional seconds. The HTTP client buffers
85
92
  # logs and this options represents how often that will happen, assuming `:batch_byte_size`
@@ -106,22 +113,25 @@ module Timber
106
113
  @api_key = api_key || raise(ArgumentError.new("The api_key parameter cannot be blank"))
107
114
  @timber_url = URI.parse(options[:timber_url] || ENV['TIMBER_URL'] || TIMBER_URL)
108
115
  @batch_size = options[:batch_size] || 1_000
116
+ @flush_continuously = options[:flush_continuously] != false
109
117
  @flush_interval = options[:flush_interval] || 1 # 1 second
110
118
  @requests_per_conn = options[:requests_per_conn] || 2_500
111
119
  @msg_queue = LogMsgQueue.new(@batch_size)
112
120
  @request_queue = options[:request_queue] || SizedQueue.new(3)
113
121
  @requests_in_flight = 0
114
-
115
- if options[:threads] != false
116
- @outlet_thread = Thread.new { outlet }
117
- @flush_thread = Thread.new { intervaled_flush }
118
- end
119
122
  end
120
123
 
121
124
  # Write a new log line message to the buffer, and deliver if the msg exceeds the
122
125
  # payload limit.
123
126
  def write(msg)
124
127
  @msg_queue.enqueue(msg)
128
+
129
+ # Lazily start flush threads to ensure threads are alive after forking processes.
130
+ # If the threads are started during instantiation they will not be copied when
131
+ # the current process is forked. This is the case with various web servers,
132
+ # such as phusion passenger.
133
+ ensure_flush_threads_are_started
134
+
125
135
  if @msg_queue.full?
126
136
  debug_logger.debug("Flushing timber buffer via write") if debug_logger
127
137
  flush
@@ -129,6 +139,19 @@ module Timber
129
139
  true
130
140
  end
131
141
 
142
+ def flush
143
+ @last_flush = Time.now
144
+ msgs = @msg_queue.flush
145
+ return if msgs.empty?
146
+
147
+ req = Net::HTTP::Post.new(@timber_url.path)
148
+ req['Authorization'] = authorization_payload
149
+ req['Content-Type'] = CONTENT_TYPE
150
+ req['User-Agent'] = USER_AGENT
151
+ req.body = msgs.to_msgpack
152
+ @request_queue.enq(req)
153
+ end
154
+
132
155
  # Closes the log device, cleans up, and attempts one last delivery.
133
156
  def close
134
157
  @flush_thread.kill if @flush_thread
@@ -141,17 +164,20 @@ module Timber
141
164
  Timber::Config.instance.debug_logger
142
165
  end
143
166
 
144
- def flush
145
- @last_flush = Time.now
146
- msgs = @msg_queue.flush
147
- return if msgs.empty?
148
-
149
- req = Net::HTTP::Post.new(@timber_url.path)
150
- req['Authorization'] = authorization_payload
151
- req['Content-Type'] = CONTENT_TYPE
152
- req['User-Agent'] = USER_AGENT
153
- req.body = msgs.to_msgpack
154
- @request_queue.enq(req)
167
+ # This is a convenience method to ensure the flush thread are
168
+ # started. This is called lazily from #write so that we
169
+ # only start the threads as needed, but it also ensures
170
+ # threads are started after process forking.
171
+ def ensure_flush_threads_are_started
172
+ if @flush_continuously
173
+ if @outlet_thread.nil? || !@outlet_thread.alive?
174
+ @outlet_thread = Thread.new { outlet }
175
+ end
176
+
177
+ if @flush_thread.nil? || !@flush_thread.alive?
178
+ @flush_thread = Thread.new { intervaled_flush }
179
+ end
180
+ end
155
181
  end
156
182
 
157
183
  def intervaled_flush
@@ -5,7 +5,7 @@ module Timber
5
5
  # `Logger` and the log device that you set it up with.
6
6
  class LogEntry #:nodoc:
7
7
  DT_PRECISION = 6.freeze
8
- SCHEMA = "https://raw.githubusercontent.com/timberio/log-event-json-schema/2.0.1/schema.json".freeze
8
+ SCHEMA = "https://raw.githubusercontent.com/timberio/log-event-json-schema/v2.0.4/schema.json".freeze
9
9
 
10
10
  attr_reader :context_snapshot, :event, :level, :message, :progname, :tags, :time, :time_ms
11
11
 
@@ -1,3 +1,3 @@
1
1
  module Timber
2
- VERSION = "2.0.19"
2
+ VERSION = "2.0.20"
3
3
  end
@@ -1,13 +1,18 @@
1
1
  require "spec_helper"
2
2
 
3
+ # Note: these tests access instance variables and private methods as a means of
4
+ # not muddying the public API. This object should expose a simple buffer like
5
+ # API, tests should not alter that.
3
6
  describe Timber::LogDevices::HTTP do
4
7
  describe "#initialize" do
5
8
  it "should initialize properly" do
6
9
  http = described_class.new("MYKEY", flush_interval: 0.1)
10
+
11
+ # Ensure that threads have not started
7
12
  thread = http.instance_variable_get(:@flush_thread)
8
- expect(thread).to be_alive
9
- thread = http.instance_variable_get(:@flush_thread)
10
- expect(thread).to be_alive
13
+ expect(thread).to be_nil
14
+ thread = http.instance_variable_get(:@outlet_thread)
15
+ expect(thread).to be_nil
11
16
  end
12
17
  end
13
18
 
@@ -20,6 +25,15 @@ describe Timber::LogDevices::HTTP do
20
25
  expect(msg_queue.flush).to eq(["test log message"])
21
26
  end
22
27
 
28
+ it "should start the flush threads" do
29
+ http.write("test log message")
30
+
31
+ thread = http.instance_variable_get(:@flush_thread)
32
+ expect(thread).to be_alive
33
+ thread = http.instance_variable_get(:@outlet_thread)
34
+ expect(thread).to be_alive
35
+ end
36
+
23
37
  context "with a low batch size" do
24
38
  let(:http) { described_class.new("MYKEY", :batch_size => 2) }
25
39
 
@@ -35,6 +49,7 @@ describe Timber::LogDevices::HTTP do
35
49
  let(:http) { described_class.new("MYKEY") }
36
50
 
37
51
  it "should kill the threads" do
52
+ http.send(:ensure_flush_threads_are_started)
38
53
  http.close
39
54
  thread = http.instance_variable_get(:@flush_thread)
40
55
  sleep 0.1 # too fast!
@@ -57,7 +72,7 @@ describe Timber::LogDevices::HTTP do
57
72
  let(:time) { Time.utc(2016, 9, 1, 12, 0, 0) }
58
73
 
59
74
  it "should add a request to the queue" do
60
- http = described_class.new("MYKEY", threads: false)
75
+ http = described_class.new("MYKEY", flush_continuously: false)
61
76
  log_entry = Timber::LogEntry.new("INFO", time, nil, "test log message 1", nil, nil)
62
77
  http.write(log_entry)
63
78
  log_entry = Timber::LogEntry.new("INFO", time, nil, "test log message 2", nil, nil)
@@ -73,7 +88,7 @@ describe Timber::LogDevices::HTTP do
73
88
  end
74
89
 
75
90
  it "should preserve formatting for mshpack payloads" do
76
- http = described_class.new("MYKEY", threads: false)
91
+ http = described_class.new("MYKEY", flush_continuously: false)
77
92
  http.write("This is a log message 1".to_msgpack)
78
93
  http.write("This is a log message 2".to_msgpack)
79
94
  http.send(:flush)
@@ -84,9 +99,10 @@ describe Timber::LogDevices::HTTP do
84
99
  describe "#intervaled_flush" do
85
100
  it "should start a intervaled flush thread and flush on an interval" do
86
101
  http = described_class.new("MYKEY", flush_interval: 0.1)
102
+ http.send(:ensure_flush_threads_are_started)
87
103
  expect(http).to receive(:flush).exactly(1).times
88
104
  sleep 0.12 # too fast!
89
- mock = expect(http).to receive(:flush).exactly(1).times
105
+ expect(http).to receive(:flush).exactly(1).times
90
106
  sleep 0.12 # too fast!
91
107
  end
92
108
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: timber
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.19
4
+ version: 2.0.20
5
5
  platform: ruby
6
6
  authors:
7
7
  - Timber Technologies, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-05-15 00:00:00.000000000 Z
11
+ date: 2017-05-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: msgpack
@@ -264,7 +264,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
264
264
  version: '0'
265
265
  requirements: []
266
266
  rubyforge_project:
267
- rubygems_version: 2.6.8
267
+ rubygems_version: 2.5.2
268
268
  signing_key:
269
269
  specification_version: 4
270
270
  summary: Log Better. Solve Problems Faster. https://timber.io