jls-lumberjack 0.0.25 → 0.0.26

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: 55126155d83d8600b7bdb19be71a4c1ea995ca9f
4
- data.tar.gz: c4ec4e35094641991017a659963291587225c1e3
3
+ metadata.gz: d0a7b199bd230caef5c79839f655b115bdd0dece
4
+ data.tar.gz: b2ff3afdc5164f2cfc14516d999f75f33b44eec8
5
5
  SHA512:
6
- metadata.gz: e9d2d85c73ca79c218b7d951095bf49a3962fa43e992f3ba4d667ef7a1ba7bbaecba4841706eba2de5db0c3ebbffa72e13181aecacb8509dc58bc67dfd2fa28b
7
- data.tar.gz: ea44f28977d8eb96c78c68b913a1c61b37d1e936ad190a7b07d947b6f2bc9f131f15491a0705f0745e718fb77733157d760537ff362634d89e196093bfa56d6e
6
+ metadata.gz: 7ce044107a0d0f981186aa8b95d5938e6caf9d1ef4f108f08c5af6c65cb505763eff1eefff4987be950c5fadaa067ef38eb5e70adce22f1b524ac922b42bc09f
7
+ data.tar.gz: 9562ba9687ef1aafa71514aaf028d5d66206eff57a9020e6f28441954c36837431b27a010f5883ea25ae0e8276f30e070d889e39f05145e273aba118ea4fff45
@@ -1,3 +1,22 @@
1
+ require "json"
2
+
1
3
  module Lumberjack
2
4
  SEQUENCE_MAX = (2**32-1).freeze
5
+
6
+ @@json = Class.new do
7
+ def self.load(blob)
8
+ JSON.parse(blob)
9
+ end
10
+ def self.dump(v)
11
+ v.to_json
12
+ end
13
+ end
14
+
15
+ def self.json
16
+ @@json
17
+ end
18
+
19
+ def self.json=(j)
20
+ @@json = j
21
+ end
3
22
  end
@@ -13,6 +13,7 @@ module Lumberjack
13
13
  :addresses => [],
14
14
  :ssl_certificate => nil,
15
15
  :ssl => true,
16
+ :json => false,
16
17
  }.merge(opts)
17
18
 
18
19
  @opts[:addresses] = [@opts[:addresses]] if @opts[:addresses].class == String
@@ -21,7 +22,6 @@ module Lumberjack
21
22
  raise "Must set a ssl certificate or path" if @opts[:ssl_certificate].nil? && @opts[:ssl]
22
23
 
23
24
  @socket = connect
24
-
25
25
  end
26
26
 
27
27
  private
@@ -38,8 +38,8 @@ module Lumberjack
38
38
  end
39
39
 
40
40
  public
41
- def write(elements)
42
- @socket.write_sync(elements)
41
+ def write(elements, opts={})
42
+ @socket.write_sync(elements, opts)
43
43
  end
44
44
 
45
45
  public
@@ -69,6 +69,7 @@ module Lumberjack
69
69
  :address => "127.0.0.1",
70
70
  :ssl_certificate => nil,
71
71
  :ssl => true,
72
+ :json => false,
72
73
  }.merge(opts)
73
74
  @host = @opts[:address]
74
75
 
@@ -117,11 +118,16 @@ module Lumberjack
117
118
  end
118
119
 
119
120
  public
120
- def write_sync(elements)
121
+ def write_sync(elements, opts={})
122
+ options = {
123
+ :json => @opts[:json],
124
+ }.merge(opts)
125
+
121
126
  elements = [elements] if elements.is_a?(Hash)
122
127
  send_window_size(elements.size)
123
128
 
124
- payload = elements.map { |element| Encoder.to_frame(element, inc) }.join
129
+ encoder = options[:json] ? JsonEncoder : FrameEncoder
130
+ payload = elements.map { |element| encoder.to_frame(element, inc) }.join
125
131
  compress = compress_payload(payload)
126
132
  send_payload(compress)
127
133
 
@@ -159,7 +165,17 @@ module Lumberjack
159
165
  end
160
166
  end
161
167
 
162
- module Encoder
168
+ module JsonEncoder
169
+ def self.to_frame(hash, sequence)
170
+ json = Lumberjack::json.dump(hash)
171
+ json_length = json.bytesize
172
+ pack = "AANNA#{json_length}"
173
+ frame = ["1", "J", sequence, json_length, json]
174
+ frame.pack(pack)
175
+ end
176
+ end # JsonEncoder
177
+
178
+ module FrameEncoder
163
179
  def self.to_frame(hash, sequence)
164
180
  frame = ["1", "D", sequence]
165
181
  pack = "AAN"
@@ -4,6 +4,7 @@ require "socket"
4
4
  require "thread"
5
5
  require "openssl"
6
6
  require "zlib"
7
+ require "json"
7
8
  require "concurrent"
8
9
 
9
10
  module Lumberjack
@@ -65,7 +66,6 @@ module Lumberjack
65
66
  # unless the server is closing
66
67
  next unless connection
67
68
 
68
-
69
69
  Thread.new(connection) do |connection|
70
70
  connection.run(&block)
71
71
  end
@@ -94,7 +94,7 @@ module Lumberjack
94
94
  begin
95
95
  IO.select([@server], nil, nil, SOCKET_TIMEOUT)
96
96
  retry unless closed?
97
- rescue IOError => e # we currently closing
97
+ rescue IOError, Errno::EBADF => e # we currently closing
98
98
  raise e unless closed?
99
99
  end
100
100
  end
@@ -128,6 +128,11 @@ module Lumberjack
128
128
  end # class Server
129
129
 
130
130
  class Parser
131
+ PROTOCOL_VERSION_1 = "1".ord
132
+ PROTOCOL_VERSION_2 = "2".ord
133
+
134
+ SUPPORTED_PROTOCOLS = [PROTOCOL_VERSION_1, PROTOCOL_VERSION_2]
135
+
131
136
  def initialize
132
137
  @buffer_offset = 0
133
138
  @buffer = ""
@@ -196,24 +201,52 @@ module Lumberjack
196
201
 
197
202
  FRAME_WINDOW = "W".ord
198
203
  FRAME_DATA = "D".ord
204
+ FRAME_JSON_DATA = "J".ord
199
205
  FRAME_COMPRESSED = "C".ord
200
206
  def header(&block)
201
207
  version, frame_type = get.bytes.to_a[0..1]
208
+ version ||= PROTOCOL_VERSION_1
209
+
210
+ handle_version(version, &block)
202
211
 
203
212
  case frame_type
204
213
  when FRAME_WINDOW; transition(:window_size, 4)
205
214
  when FRAME_DATA; transition(:data_lead, 8)
215
+ when FRAME_JSON_DATA; transition(:json_data_lead, 8)
206
216
  when FRAME_COMPRESSED; transition(:compressed_lead, 4)
207
- else; raise "Unknown frame type: #{frame_type}"
217
+ else; raise "Unknown frame type: `#{frame_type}`"
208
218
  end
209
219
  end
210
220
 
221
+ def handle_version(version, &block)
222
+ if supported_protocol?(version)
223
+ yield :version, version
224
+ else
225
+ raise "unsupported protocol #{version}"
226
+ end
227
+ end
228
+
229
+ def supported_protocol?(version)
230
+ SUPPORTED_PROTOCOLS.include?(version)
231
+ end
232
+
211
233
  def window_size(&block)
212
234
  @window_size = get.unpack("N").first
213
235
  transition(:header, 2)
214
236
  yield :window_size, @window_size
215
237
  end # def window_size
216
238
 
239
+ def json_data_lead(&block)
240
+ @sequence, payload_size = get.unpack("NN")
241
+ transition(:json_data_payload, payload_size)
242
+ end
243
+
244
+ def json_data_payload(&block)
245
+ payload = get
246
+ yield :json, @sequence, Lumberjack::json.load(payload)
247
+ transition(:header, 2)
248
+ end
249
+
217
250
  def data_lead(&block)
218
251
  @sequence, @data_count = get.unpack("NN")
219
252
  @data = {}
@@ -274,8 +307,7 @@ module Lumberjack
274
307
  @fd = fd
275
308
 
276
309
  @server = server
277
- # a safe default until we are told by the client what window size to use
278
- @window_size = 1
310
+ @ack_handler = nil
279
311
  end
280
312
 
281
313
  def run(&block)
@@ -285,6 +317,8 @@ module Lumberjack
285
317
  rescue EOFError, OpenSSL::SSL::SSLError, IOError, Errno::ECONNRESET
286
318
  # EOF or other read errors, only action is to shutdown which we'll do in
287
319
  # 'ensure'
320
+ rescue Errno::EAGAIN
321
+ retry unless server.closed?
288
322
  ensure
289
323
  close rescue 'Already closed stream'
290
324
  end # def run
@@ -297,42 +331,105 @@ module Lumberjack
297
331
  # X: too many events after errors.
298
332
  @parser.feed(@fd.sysread(READ_SIZE)) do |event, *args|
299
333
  case event
334
+ when :version
335
+ version(*args)
300
336
  when :window_size
301
- # We receive a new payload
302
- window_size(*args)
303
- reset_next_ack
337
+ reset_next_ack(*args)
304
338
  when :data
305
- data(*args, &block)
339
+ sequence, map = args
340
+ ack_if_needed(sequence) { data(map, &block) }
341
+ when :json
342
+ # If the payload is an array of items we will emit multiple events
343
+ # this behavior was moved from the plugin to the library.
344
+ # see this commit: https://github.com/logstash-plugins/logstash-input-lumberjack/pull/57/files#diff-1b9590423b15f04f215635164e7376ecR158
345
+ sequence, map = args
346
+
347
+ ack_if_needed(sequence) do
348
+ if map.is_a?(Array)
349
+ map.each { |e| data(e, &block) }
350
+ else
351
+ data(map, &block)
352
+ end
353
+ end
306
354
  end
307
355
  end
308
356
  end
309
357
 
358
+ def version(version)
359
+ @version = version
360
+ end
361
+
362
+ def ack_if_needed(sequence, &block)
363
+ block.call
364
+ send_ack(sequence) if @ack_handler.ack?(sequence)
365
+ end
366
+
310
367
  def close
311
368
  @fd.close unless @fd.closed?
312
369
  end
313
370
 
314
- def window_size(size)
315
- @window_size = size
371
+ def data(map, &block)
372
+ block.call(map) if block_given?
373
+ end
374
+
375
+ def reset_next_ack(window_size)
376
+ klass = (@version == Parser::PROTOCOL_VERSION_1) ? AckingProtocolV1 : AckingProtocolV2
377
+ @ack_handler = klass.new(window_size)
378
+ end
379
+
380
+ def send_ack(sequence)
381
+ @fd.syswrite(@ack_handler.ack_frame(sequence))
316
382
  end
383
+ end # class Connection
317
384
 
318
- def reset_next_ack
385
+ class AckingProtocolV1
386
+ def initialize(window_size)
319
387
  @next_ack = nil
388
+ @window_size = window_size
320
389
  end
321
390
 
322
- def data(sequence, map, &block)
323
- block.call(map) if block_given?
324
- ack_if_needed(sequence)
391
+ def ack?(sequence)
392
+ # The first encoded event will contain the sequence number
393
+ # this is needed to know when we should ack.
394
+ @next_ack = compute_next_ack(sequence) if @next_ack.nil?
395
+ sequence == @next_ack
396
+ end
397
+
398
+ def ack_frame(sequence)
399
+ ["1A", sequence].pack("A*N")
325
400
  end
326
-
401
+
402
+ private
327
403
  def compute_next_ack(sequence)
328
404
  (sequence + @window_size - 1) % SEQUENCE_MAX
329
405
  end
406
+ end
407
+
408
+ # Allow lumberjack to send partial ack back to the producer
409
+ # only V2 client support partial Acks
410
+ #
411
+ # Send Ack on every 20% of the data, so with default settings every 200 events
412
+ # This should reduce the congestion on retransmit.
413
+ class AckingProtocolV2
414
+ ACK_RATIO = 5
415
+
416
+ def initialize(window_size)
417
+ @window_size = window_size
418
+ @every = (window_size / ACK_RATIO).round
419
+ end
330
420
 
331
- def ack_if_needed(sequence)
332
- # The first encoded event will contain the sequence number
333
- # this is needed to know when we should ack.
334
- @next_ack = compute_next_ack(sequence) if @next_ack.nil?
335
- @fd.syswrite(["1A", sequence].pack("A*N")) if sequence == @next_ack
421
+ def ack?(sequence)
422
+ if @window_size == sequence
423
+ true
424
+ elsif sequence % @every == 0
425
+ true
426
+ else
427
+ false
428
+ end
336
429
  end
337
- end # class Connection
430
+
431
+ def ack_frame(sequence)
432
+ ["2A", sequence].pack("A*N")
433
+ end
434
+ end
338
435
  end # module Lumberjack
@@ -7,6 +7,7 @@ require "fileutils"
7
7
  require "thread"
8
8
  require "spec_helper"
9
9
 
10
+ Thread.abort_on_exception = true
10
11
  describe "A client" do
11
12
  let(:certificate) { Flores::PKI.generate }
12
13
  let(:certificate_file_crt) { "certificate.crt" }
@@ -134,10 +135,17 @@ describe "A client" do
134
135
  end
135
136
 
136
137
  context "When transmitting a payload" do
137
- let(:client) do
138
- Lumberjack::Client.new(:port => tcp_port, :host => host, :addresses => host, :ssl => false)
138
+ let(:options) { {:port => tcp_port, :host => host, :addresses => host, :ssl => false } }
139
+ let(:client) { Lumberjack::Client.new(options) }
140
+
141
+ context "json" do
142
+ let(:options) { super.merge({ :json => true }) }
143
+ include_examples "transmit payloads"
144
+ end
145
+
146
+ context "v1 frame" do
147
+ include_examples "transmit payloads"
139
148
  end
140
- include_examples "transmit payloads"
141
149
  end
142
150
  end
143
151
 
@@ -188,7 +196,15 @@ describe "A client" do
188
196
  :addresses => host,
189
197
  :ssl_certificate => certificate_file_crt)
190
198
  end
191
- include_examples "transmit payloads"
199
+
200
+ context "json" do
201
+ let(:options) { super.merge({ :json => true }) }
202
+ include_examples "transmit payloads"
203
+ end
204
+
205
+ context "v1 frame" do
206
+ include_examples "transmit payloads"
207
+ end
192
208
  end
193
209
  end
194
210
  end
@@ -0,0 +1,16 @@
1
+ # encoding: utf-8
2
+ require "lumberjack/server"
3
+ require "flores/random"
4
+
5
+ describe Lumberjack::AckingProtocolV1 do
6
+ let(:number_of_events) { Flores::Random.integer(100..1024) }
7
+
8
+ subject { Lumberjack::AckingProtocolV1.new(number_of_events) }
9
+
10
+ it "should return true only once" do
11
+ results = []
12
+ number_of_events.times { |n| results << subject.ack?(n) }
13
+ expect(results.size).to eq(number_of_events)
14
+ expect(results.count(true)).to eq(1)
15
+ end
16
+ end
@@ -0,0 +1,31 @@
1
+ # encoding: utf-8
2
+ require "lumberjack/server"
3
+ require "flores/random"
4
+
5
+ describe Lumberjack::AckingProtocolV2 do
6
+ let(:results) { [] }
7
+ subject { Lumberjack::AckingProtocolV2.new(number_of_events) }
8
+ before { 1.upto(number_of_events) { |n| results << subject.ack?(n) } }
9
+
10
+ context "with multiples events" do
11
+ let(:number_of_events) { Flores::Random.integer(100..1024) }
12
+
13
+ it "should return multiples partial acks" do
14
+ expect(results.size).to eq(number_of_events)
15
+ expect(results.count(true)).to be_within(1).of((number_of_events / number_of_events * Lumberjack::AckingProtocolV2::ACK_RATIO).ceil)
16
+ end
17
+
18
+ it "last ack should be true" do
19
+ expect(results.last).to be_truthy
20
+ end
21
+ end
22
+
23
+ context "with only one event" do
24
+ let(:number_of_events) { 1 }
25
+
26
+ it "should return true only once" do
27
+ expect(results.size).to eq(number_of_events)
28
+ expect(results.count(true)).to eq(1)
29
+ end
30
+ end
31
+ end
@@ -8,9 +8,7 @@ require "openssl"
8
8
  require "zlib"
9
9
 
10
10
  describe "Lumberjack::Client" do
11
-
12
11
  describe "Lumberjack::Socket" do
13
-
14
12
  let(:port) { 5000 }
15
13
 
16
14
  subject(:socket) { Lumberjack::Socket.new(:port => port, :ssl_certificate => "" ) }
@@ -38,16 +36,60 @@ describe "Lumberjack::Client" do
38
36
  end
39
37
  end
40
38
 
41
- describe Lumberjack::Encoder do
39
+ describe Lumberjack::FrameEncoder do
40
+ it 'should creates frames without truncating accentued characters' do
41
+ content = {
42
+ "message" => "Le Canadien de Montréal est la meilleure équipe au monde!",
43
+ "other" => "éléphant"
44
+ }
45
+ parser = Lumberjack::Parser.new
46
+ parser.feed(Lumberjack::FrameEncoder.to_frame(content, 0)) do |code, sequence, data|
47
+ if code == :data
48
+ expect(data["message"].force_encoding('UTF-8')).to eq(content["message"])
49
+ expect(data["other"].force_encoding('UTF-8')).to eq(content["other"])
50
+ end
51
+ end
52
+ end
53
+
54
+ it 'should creates frames without dropping multibytes characters' do
55
+ content = {
56
+ "message" => "国際ホッケー連盟" # International Hockey Federation
57
+ }
58
+ parser = Lumberjack::Parser.new
59
+ parser.feed(Lumberjack::FrameEncoder.to_frame(content, 0)) do |code, sequence, data|
60
+ expect(data["message"].force_encoding('UTF-8')).to eq(content["message"]) if code == :data
61
+ end
62
+ end
63
+ end
64
+
65
+ describe Lumberjack::JsonEncoder do
66
+ it 'should create frames from nested hash' do
67
+ content = {
68
+ "number" => 1,
69
+ "string" => "hello world",
70
+ "array" => [1,2,3],
71
+ "sub" => {
72
+ "a" => 1
73
+ }
74
+ }
75
+ parser = Lumberjack::Parser.new
76
+ frame = Lumberjack::JsonEncoder.to_frame(content, 0)
77
+ parser.feed(frame) do |code, sequence, data|
78
+ expect(data).to eq(content) if code == :json
79
+ end
80
+ end
81
+
42
82
  it 'should creates frames without truncating accentued characters' do
43
83
  content = {
44
84
  "message" => "Le Canadien de Montréal est la meilleure équipe au monde!",
45
85
  "other" => "éléphant"
46
86
  }
47
87
  parser = Lumberjack::Parser.new
48
- parser.feed(Lumberjack::Encoder.to_frame(content, 0)) do |code, sequence, data|
49
- expect(data["message"].force_encoding('UTF-8')).to eq(content["message"])
50
- expect(data["other"].force_encoding('UTF-8')).to eq(content["other"])
88
+ parser.feed(Lumberjack::JsonEncoder.to_frame(content, 0)) do |code, sequence, data|
89
+ if code == :json
90
+ expect(data["message"]).to eq(content["message"])
91
+ expect(data["other"]).to eq(content["other"])
92
+ end
51
93
  end
52
94
  end
53
95
 
@@ -56,8 +98,8 @@ describe "Lumberjack::Client" do
56
98
  "message" => "国際ホッケー連盟" # International Hockey Federation
57
99
  }
58
100
  parser = Lumberjack::Parser.new
59
- parser.feed(Lumberjack::Encoder.to_frame(content, 0)) do |code, sequence, data|
60
- expect(data["message"].force_encoding('UTF-8')).to eq(content["message"])
101
+ parser.feed(Lumberjack::JsonEncoder.to_frame(content, 0)) do |code, sequence, data|
102
+ expect(data["message"]).to eq(content["message"]) if code == :json
61
103
  end
62
104
  end
63
105
  end
@@ -17,8 +17,10 @@ describe "Connnection" do
17
17
  allow(socket).to receive(:syswrite).with(anything).and_return(true)
18
18
  allow(socket).to receive(:close)
19
19
 
20
+
20
21
  expectation = receive(:feed)
21
22
  .with("")
23
+ .and_yield(:version, Lumberjack::Parser::PROTOCOL_VERSION_1)
22
24
  .and_yield(:window_size, random_number_of_events)
23
25
 
24
26
  random_number_of_events.times { |n| expectation.and_yield(:data, start_sequence + n + 1, payload) }
metadata CHANGED
@@ -1,97 +1,97 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jls-lumberjack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.25
4
+ version: 0.0.26
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sissel
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-10-12 00:00:00.000000000 Z
11
+ date: 2015-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: concurrent-ruby
15
14
  requirement: !ruby/object:Gem::Requirement
16
15
  requirements:
17
- - - ">="
16
+ - - '>='
18
17
  - !ruby/object:Gem::Version
19
18
  version: '0'
20
- type: :runtime
19
+ name: concurrent-ruby
21
20
  prerelease: false
21
+ type: :runtime
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - '>='
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
- name: flores
29
28
  requirement: !ruby/object:Gem::Requirement
30
29
  requirements:
31
- - - "~>"
30
+ - - ~>
32
31
  - !ruby/object:Gem::Version
33
32
  version: 0.0.6
34
- type: :development
33
+ name: flores
35
34
  prerelease: false
35
+ type: :development
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ~>
39
39
  - !ruby/object:Gem::Version
40
40
  version: 0.0.6
41
41
  - !ruby/object:Gem::Dependency
42
- name: rspec
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
- - - ">="
44
+ - - '>='
46
45
  - !ruby/object:Gem::Version
47
46
  version: '0'
48
- type: :development
47
+ name: rspec
49
48
  prerelease: false
49
+ type: :development
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ">="
52
+ - - '>='
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: stud
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
- - - ">="
58
+ - - '>='
60
59
  - !ruby/object:Gem::Version
61
60
  version: '0'
62
- type: :development
61
+ name: stud
63
62
  prerelease: false
63
+ type: :development
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - '>='
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: pry
71
70
  requirement: !ruby/object:Gem::Requirement
72
71
  requirements:
73
- - - ">="
72
+ - - '>='
74
73
  - !ruby/object:Gem::Version
75
74
  version: '0'
76
- type: :development
75
+ name: pry
77
76
  prerelease: false
77
+ type: :development
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
- - - ">="
80
+ - - '>='
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: rspec-wait
85
84
  requirement: !ruby/object:Gem::Requirement
86
85
  requirements:
87
- - - ">="
86
+ - - '>='
88
87
  - !ruby/object:Gem::Version
89
88
  version: '0'
90
- type: :development
89
+ name: rspec-wait
91
90
  prerelease: false
91
+ type: :development
92
92
  version_requirements: !ruby/object:Gem::Requirement
93
93
  requirements:
94
- - - ">="
94
+ - - '>='
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
97
  description: lumberjack log transport library
@@ -105,6 +105,8 @@ files:
105
105
  - lib/lumberjack/client.rb
106
106
  - lib/lumberjack/server.rb
107
107
  - spec/integration_spec.rb
108
+ - spec/lumberjack/acking_protocol_v1_spec.rb
109
+ - spec/lumberjack/acking_protocol_v2_spec.rb
108
110
  - spec/lumberjack/client_spec.rb
109
111
  - spec/lumberjack/connection_spec.rb
110
112
  - spec/lumberjack/server_spec.rb
@@ -112,29 +114,31 @@ files:
112
114
  homepage: https://github.com/jordansissel/lumberjack
113
115
  licenses: []
114
116
  metadata: {}
115
- post_install_message:
117
+ post_install_message:
116
118
  rdoc_options: []
117
119
  require_paths:
118
120
  - lib
119
121
  required_ruby_version: !ruby/object:Gem::Requirement
120
122
  requirements:
121
- - - ">="
123
+ - - '>='
122
124
  - !ruby/object:Gem::Version
123
125
  version: '0'
124
126
  required_rubygems_version: !ruby/object:Gem::Requirement
125
127
  requirements:
126
- - - ">="
128
+ - - '>='
127
129
  - !ruby/object:Gem::Version
128
130
  version: '0'
129
131
  requirements: []
130
- rubyforge_project:
131
- rubygems_version: 2.4.6
132
- signing_key:
132
+ rubyforge_project:
133
+ rubygems_version: 2.4.8
134
+ signing_key:
133
135
  specification_version: 4
134
136
  summary: lumberjack log transport library
135
137
  test_files:
136
138
  - spec/integration_spec.rb
139
+ - spec/spec_helper.rb
140
+ - spec/lumberjack/acking_protocol_v1_spec.rb
141
+ - spec/lumberjack/acking_protocol_v2_spec.rb
137
142
  - spec/lumberjack/client_spec.rb
138
143
  - spec/lumberjack/connection_spec.rb
139
144
  - spec/lumberjack/server_spec.rb
140
- - spec/spec_helper.rb