jls-lumberjack 0.0.23 → 0.0.24
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/lib/lumberjack.rb +3 -0
- data/lib/lumberjack/client.rb +26 -25
- data/lib/lumberjack/server.rb +39 -19
- data/spec/integration_spec.rb +74 -2
- data/spec/lumberjack/client_spec.rb +4 -38
- data/spec/lumberjack/server_spec.rb +33 -0
- data/spec/spec_helper.rb +4 -0
- metadata +38 -21
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d58912ce6afda9045d016510618a04363349628d
|
4
|
+
data.tar.gz: faeaba187853930185d78673f4b69c16c5b107bb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e40270de1f12efc47375be7a5a9cd9c83fae6ce2b615fe50885037746ecf074e1a26bf2dd4b2bf8a2ebdd1816c95f6d36b56e84de32e3fc5f73a225be7bc6aa7
|
7
|
+
data.tar.gz: 6224d5a7b5475195b0afd5168eea3c37a8c704cef432cf90b01cb8fcd520ea3293f1503e89b6bd4e0eaf2e84f24afeab78b7681ab9be4999e2720b2987291dd8
|
data/lib/lumberjack.rb
ADDED
data/lib/lumberjack/client.rb
CHANGED
@@ -1,20 +1,17 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require "lumberjack"
|
2
3
|
require "socket"
|
3
4
|
require "thread"
|
4
5
|
require "openssl"
|
5
6
|
require "zlib"
|
6
7
|
|
7
8
|
module Lumberjack
|
8
|
-
|
9
|
-
SEQUENCE_MAX = (2**32-1).freeze
|
10
|
-
|
11
9
|
class Client
|
12
10
|
def initialize(opts={})
|
13
11
|
@opts = {
|
14
12
|
:port => 0,
|
15
13
|
:addresses => [],
|
16
14
|
:ssl_certificate => nil,
|
17
|
-
:window_size => 5000
|
18
15
|
}.merge(opts)
|
19
16
|
|
20
17
|
@opts[:addresses] = [@opts[:addresses]] if @opts[:addresses].class == String
|
@@ -40,8 +37,8 @@ module Lumberjack
|
|
40
37
|
end
|
41
38
|
|
42
39
|
public
|
43
|
-
def write(
|
44
|
-
@socket.
|
40
|
+
def write(elements)
|
41
|
+
@socket.write_sync(elements)
|
45
42
|
end
|
46
43
|
|
47
44
|
public
|
@@ -51,7 +48,6 @@ module Lumberjack
|
|
51
48
|
end
|
52
49
|
|
53
50
|
class Socket
|
54
|
-
|
55
51
|
# Create a new Lumberjack Socket.
|
56
52
|
#
|
57
53
|
# - options is a hash. Valid options are:
|
@@ -60,7 +56,6 @@ module Lumberjack
|
|
60
56
|
# * :address - the host/address to bind to
|
61
57
|
# * :ssl_certificate - the path to the ssl cert to use
|
62
58
|
attr_reader :sequence
|
63
|
-
attr_reader :window_size
|
64
59
|
attr_reader :host
|
65
60
|
def initialize(opts={})
|
66
61
|
@sequence = 0
|
@@ -69,10 +64,8 @@ module Lumberjack
|
|
69
64
|
:port => 0,
|
70
65
|
:address => "127.0.0.1",
|
71
66
|
:ssl_certificate => nil,
|
72
|
-
:window_size => 5000
|
73
67
|
}.merge(opts)
|
74
68
|
@host = @opts[:address]
|
75
|
-
@window_size = @opts[:window_size]
|
76
69
|
|
77
70
|
connection_start(opts)
|
78
71
|
end
|
@@ -92,7 +85,6 @@ module Lumberjack
|
|
92
85
|
|
93
86
|
@socket = OpenSSL::SSL::SSLSocket.new(tcp_socket, ssl_context)
|
94
87
|
@socket.connect
|
95
|
-
@socket.syswrite(["1", "W", @window_size].pack("AAN"))
|
96
88
|
end
|
97
89
|
|
98
90
|
private
|
@@ -102,9 +94,12 @@ module Lumberjack
|
|
102
94
|
end
|
103
95
|
|
104
96
|
private
|
105
|
-
def
|
106
|
-
|
107
|
-
|
97
|
+
def send_window_size(size)
|
98
|
+
@socket.syswrite(["1", "W", size].pack("AAN"))
|
99
|
+
end
|
100
|
+
|
101
|
+
private
|
102
|
+
def send_payload(payload)
|
108
103
|
# SSLSocket has a limit of 16k per message
|
109
104
|
# execute multiple writes if needed
|
110
105
|
bytes_written = 0
|
@@ -114,18 +109,28 @@ module Lumberjack
|
|
114
109
|
end
|
115
110
|
|
116
111
|
public
|
117
|
-
def
|
118
|
-
|
119
|
-
|
120
|
-
|
112
|
+
def write_sync(elements)
|
113
|
+
elements = [elements] if elements.is_a?(Hash)
|
114
|
+
send_window_size(elements.size)
|
115
|
+
|
116
|
+
payload = elements.map { |element| Encoder.to_frame(element, inc) }.join
|
117
|
+
compress = compress_payload(payload)
|
118
|
+
send_payload(compress)
|
119
|
+
|
120
|
+
ack(elements.size)
|
121
|
+
end
|
122
|
+
|
123
|
+
private
|
124
|
+
def compress_payload(payload)
|
125
|
+
compress = Zlib::Deflate.deflate(payload)
|
126
|
+
["1", "C", compress.bytesize, compress].pack("AANA*")
|
121
127
|
end
|
122
128
|
|
123
129
|
private
|
124
|
-
def ack
|
130
|
+
def ack(size)
|
125
131
|
_, type = read_version_and_type
|
126
132
|
raise "Whoa we shouldn't get this frame: #{type}" if type != "A"
|
127
133
|
@last_ack = read_last_ack
|
128
|
-
ack if unacked_sequence_size >= @window_size
|
129
134
|
end
|
130
135
|
|
131
136
|
private
|
@@ -139,6 +144,7 @@ module Lumberjack
|
|
139
144
|
type = @socket.read(1)
|
140
145
|
[version, type]
|
141
146
|
end
|
147
|
+
|
142
148
|
private
|
143
149
|
def read_last_ack
|
144
150
|
@socket.read(4).unpack("N").first
|
@@ -146,11 +152,6 @@ module Lumberjack
|
|
146
152
|
end
|
147
153
|
|
148
154
|
module Encoder
|
149
|
-
def self.to_compressed_frame(hash, sequence)
|
150
|
-
compress = Zlib::Deflate.deflate(to_frame(hash, sequence))
|
151
|
-
["1", "C", compress.bytesize, compress].pack("AANA#{compress.length}")
|
152
|
-
end
|
153
|
-
|
154
155
|
def self.to_frame(hash, sequence)
|
155
156
|
frame = ["1", "D", sequence]
|
156
157
|
pack = "AAN"
|
data/lib/lumberjack/server.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# encoding: utf-8
|
2
|
+
require "lumberjack"
|
2
3
|
require "socket"
|
3
4
|
require "thread"
|
4
5
|
require "openssl"
|
@@ -207,11 +208,12 @@ module Lumberjack
|
|
207
208
|
end # class Parser
|
208
209
|
|
209
210
|
class Connection
|
211
|
+
READ_SIZE = 16384
|
212
|
+
|
210
213
|
def initialize(fd)
|
211
214
|
super()
|
212
215
|
@parser = Parser.new
|
213
216
|
@fd = fd
|
214
|
-
@last_ack = 0
|
215
217
|
|
216
218
|
# a safe default until we are told by the client what window size to use
|
217
219
|
@window_size = 1
|
@@ -219,19 +221,8 @@ module Lumberjack
|
|
219
221
|
|
220
222
|
def run(&block)
|
221
223
|
while true
|
222
|
-
|
223
|
-
|
224
|
-
# X: - on timeout, ack all.
|
225
|
-
# X: Doing so will prevent slow streams from retransmitting
|
226
|
-
# X: too many events after errors.
|
227
|
-
@parser.feed(@fd.sysread(16384)) do |event, *args|
|
228
|
-
case event
|
229
|
-
when :window_size; window_size(*args, &block)
|
230
|
-
when :data; data(*args, &block)
|
231
|
-
end
|
232
|
-
#send(event, *args)
|
233
|
-
end # feed
|
234
|
-
end # while true
|
224
|
+
read_socket(&block)
|
225
|
+
end
|
235
226
|
rescue EOFError, OpenSSL::SSL::SSLError, IOError, Errno::ECONNRESET
|
236
227
|
# EOF or other read errors, only action is to shutdown which we'll do in
|
237
228
|
# 'ensure'
|
@@ -239,6 +230,24 @@ module Lumberjack
|
|
239
230
|
close rescue 'Already closed stream'
|
240
231
|
end # def run
|
241
232
|
|
233
|
+
def read_socket(&block)
|
234
|
+
# TODO(sissel): Ack on idle.
|
235
|
+
# X: - if any unacked, IO.select
|
236
|
+
# X: - on timeout, ack all.
|
237
|
+
# X: Doing so will prevent slow streams from retransmitting
|
238
|
+
# X: too many events after errors.
|
239
|
+
@parser.feed(@fd.sysread(READ_SIZE)) do |event, *args|
|
240
|
+
case event
|
241
|
+
when :window_size
|
242
|
+
# We receive a new payload
|
243
|
+
window_size(*args)
|
244
|
+
reset_next_ack
|
245
|
+
when :data
|
246
|
+
data(*args, &block)
|
247
|
+
end
|
248
|
+
end
|
249
|
+
end
|
250
|
+
|
242
251
|
def close
|
243
252
|
@fd.close
|
244
253
|
end
|
@@ -247,13 +256,24 @@ module Lumberjack
|
|
247
256
|
@window_size = size
|
248
257
|
end
|
249
258
|
|
259
|
+
def reset_next_ack
|
260
|
+
@next_ack = nil
|
261
|
+
end
|
262
|
+
|
250
263
|
def data(sequence, map, &block)
|
251
264
|
block.call(map) if block_given?
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
265
|
+
ack_if_needed(sequence)
|
266
|
+
end
|
267
|
+
|
268
|
+
def compute_next_ack(sequence)
|
269
|
+
(sequence + @window_size - 1) % SEQUENCE_MAX
|
256
270
|
end
|
257
|
-
end # class Connection
|
258
271
|
|
272
|
+
def ack_if_needed(sequence)
|
273
|
+
# The first encoded event will contain the sequence number
|
274
|
+
# this is needed to know when we should ack.
|
275
|
+
@next_ack = compute_next_ack(sequence) if @next_ack.nil?
|
276
|
+
@fd.syswrite(["1A", sequence].pack("A*N")) if sequence == @next_ack
|
277
|
+
end
|
278
|
+
end # class Connection
|
259
279
|
end # module Lumberjack
|
data/spec/integration_spec.rb
CHANGED
@@ -7,12 +7,15 @@ require "fileutils"
|
|
7
7
|
require "thread"
|
8
8
|
require "spec_helper"
|
9
9
|
|
10
|
+
Thread.abort_on_exception = true
|
11
|
+
|
10
12
|
describe "A client" do
|
11
13
|
let(:certificate) { Flores::PKI.generate }
|
12
14
|
let(:certificate_file_crt) { "certificate.crt" }
|
13
15
|
let(:certificate_file_key) { "certificate.key" }
|
14
16
|
let(:port) { Flores::Random.integer(1024..65335) }
|
15
17
|
let(:host) { "127.0.0.1" }
|
18
|
+
let(:queue) { [] }
|
16
19
|
|
17
20
|
before do
|
18
21
|
expect(File).to receive(:read).at_least(1).with(certificate_file_crt) { certificate.first.to_s }
|
@@ -23,8 +26,8 @@ describe "A client" do
|
|
23
26
|
:ssl_certificate => certificate_file_crt,
|
24
27
|
:ssl_key => certificate_file_key)
|
25
28
|
|
26
|
-
Thread.new do
|
27
|
-
server.run { |data| }
|
29
|
+
@server = Thread.new do
|
30
|
+
server.run { |data| queue << data }
|
28
31
|
end
|
29
32
|
end
|
30
33
|
|
@@ -58,4 +61,73 @@ describe "A client" do
|
|
58
61
|
}.to raise_error(OpenSSL::SSL::SSLError, /certificate verify failed/)
|
59
62
|
end
|
60
63
|
end
|
64
|
+
|
65
|
+
shared_examples "send payload" do
|
66
|
+
it "supports single element" do
|
67
|
+
(1..random_number_of_events).each do |n|
|
68
|
+
expect(client.write(payload)).to eq(sequence_start + n)
|
69
|
+
end
|
70
|
+
sleep(0.5) # give time to the server to read the events
|
71
|
+
expect(queue.size).to eq(random_number_of_events)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "support sending multiple elements in one payload" do
|
75
|
+
expect(client.write(batch_payload)).to eq(sequence_start + batch_size)
|
76
|
+
sleep(0.5)
|
77
|
+
|
78
|
+
expect(queue.size).to eq(batch_size)
|
79
|
+
expect(queue).to match_array(batch_payload)
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "When transmitting a payload" do
|
84
|
+
let(:random_number_of_events) { Flores::Random.integer(2..10) }
|
85
|
+
let(:payload) { { "line" => "foobar" } }
|
86
|
+
let(:client) do
|
87
|
+
Lumberjack::Client.new(:port => port,
|
88
|
+
:host => host,
|
89
|
+
:addresses => host,
|
90
|
+
:ssl_certificate => certificate_file_crt)
|
91
|
+
end
|
92
|
+
let(:batch_size) { Flores::Random.integer(1..1024) }
|
93
|
+
let(:batch_payload) do
|
94
|
+
batch = []
|
95
|
+
batch_size.times do |n|
|
96
|
+
batch << { "line" => "foobar #{n}" }
|
97
|
+
end
|
98
|
+
batch
|
99
|
+
end
|
100
|
+
|
101
|
+
context "when sequence start at 0" do
|
102
|
+
let(:sequence_start) { 0 }
|
103
|
+
|
104
|
+
include_examples "send payload"
|
105
|
+
end
|
106
|
+
|
107
|
+
context "when sequence doesn't start at zero" do
|
108
|
+
let(:sequence_start) { Flores::Random.integer(1..2000) }
|
109
|
+
|
110
|
+
before do
|
111
|
+
client.instance_variable_get(:@socket).instance_variable_set(:@sequence, sequence_start)
|
112
|
+
end
|
113
|
+
|
114
|
+
include_examples "send payload"
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when the sequence rollover" do
|
118
|
+
let(:batch_size) { 100 }
|
119
|
+
let(:sequence_start) { Lumberjack::SEQUENCE_MAX - batch_size / 2 }
|
120
|
+
|
121
|
+
before do
|
122
|
+
client.instance_variable_get(:@socket).instance_variable_set(:@sequence, sequence_start)
|
123
|
+
end
|
124
|
+
|
125
|
+
it "adjusts the ack" do
|
126
|
+
expect(client.write(batch_payload)).to eq(batch_size / 2)
|
127
|
+
sleep(0.5)
|
128
|
+
expect(queue.size).to eq(batch_size)
|
129
|
+
expect(queue).to match_array(batch_payload)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
61
133
|
end
|
@@ -17,49 +17,25 @@ describe "Lumberjack::Client" do
|
|
17
17
|
|
18
18
|
before do
|
19
19
|
allow_any_instance_of(Lumberjack::Socket).to receive(:connection_start).and_return(true)
|
20
|
+
# mock any network call
|
21
|
+
allow(socket).to receive(:send_window_size).with(kind_of(Integer)).and_return(true)
|
22
|
+
allow(socket).to receive(:send_payload).with(kind_of(String)).and_return(true)
|
20
23
|
end
|
21
24
|
|
22
25
|
context "sequence" do
|
23
|
-
|
24
26
|
let(:hash) { {:a => 1, :b => 2}}
|
25
27
|
let(:max_unsigned_int) { (2**32)-1 }
|
26
28
|
|
27
29
|
before(:each) do
|
28
30
|
allow(socket).to receive(:ack).and_return(true)
|
29
|
-
allow(socket).to receive(:write).and_return(true)
|
30
31
|
end
|
31
32
|
|
32
33
|
it "force sequence to be an unsigned 32 bits int" do
|
33
34
|
socket.instance_variable_set(:@sequence, max_unsigned_int)
|
34
|
-
socket.
|
35
|
+
socket.write_sync(hash)
|
35
36
|
expect(socket.sequence).to eq(1)
|
36
37
|
end
|
37
38
|
end
|
38
|
-
|
39
|
-
context "ack" do
|
40
|
-
|
41
|
-
let(:hash) { {:a => 1, :b => 2}}
|
42
|
-
|
43
|
-
before(:each) do
|
44
|
-
allow(socket).to receive(:write).and_return(true)
|
45
|
-
end
|
46
|
-
|
47
|
-
it "increments the sequence per windows size" do
|
48
|
-
allow(socket).to receive(:read_version_and_type).and_return([1, 'A'])
|
49
|
-
expect(socket).to receive(:ack).twice.and_call_original
|
50
|
-
|
51
|
-
[5000, 10000].each do |last_ack|
|
52
|
-
windows_size = 5001
|
53
|
-
|
54
|
-
allow(socket).to receive(:read_last_ack).and_return(last_ack)
|
55
|
-
|
56
|
-
windows_size.times do
|
57
|
-
socket.write_hash(hash)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
end
|
62
|
-
end
|
63
39
|
end
|
64
40
|
|
65
41
|
describe Lumberjack::Encoder do
|
@@ -84,15 +60,5 @@ describe "Lumberjack::Client" do
|
|
84
60
|
expect(data["message"].force_encoding('UTF-8')).to eq(content["message"])
|
85
61
|
end
|
86
62
|
end
|
87
|
-
|
88
|
-
it 'should creates compressed frames' do
|
89
|
-
content = {
|
90
|
-
"message" => "国際ホッケー連盟" # International Hockey Federation
|
91
|
-
}
|
92
|
-
parser = Lumberjack::Parser.new
|
93
|
-
parser.feed(Lumberjack::Encoder.to_compressed_frame(content, 0)) do |code, sequence, data|
|
94
|
-
expect(data["message"].force_encoding('UTF-8')).to eq(content["message"])
|
95
|
-
end
|
96
|
-
end
|
97
63
|
end
|
98
64
|
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require "lumberjack/server"
|
3
|
+
require "spec_helper"
|
4
|
+
require "flores/random"
|
5
|
+
|
6
|
+
describe "Server" do
|
7
|
+
let(:socket) { double("socket") }
|
8
|
+
let(:connection) { Lumberjack::Connection.new(socket) }
|
9
|
+
let(:payload) { {"line" => "foobar" } }
|
10
|
+
let(:start_sequence) { Flores::Random.integer(0..2000) }
|
11
|
+
let(:random_number_of_events) { Flores::Random.integer(2..200) }
|
12
|
+
|
13
|
+
before do
|
14
|
+
expect(socket).to receive(:sysread).at_least(:once).with(Lumberjack::Connection::READ_SIZE).and_return("")
|
15
|
+
allow(socket).to receive(:syswrite).with(anything).and_return(true)
|
16
|
+
allow(socket).to receive(:close)
|
17
|
+
|
18
|
+
expectation = receive(:feed)
|
19
|
+
.with("")
|
20
|
+
.and_yield(:window_size, random_number_of_events)
|
21
|
+
|
22
|
+
random_number_of_events.times { |n| expectation.and_yield(:data, start_sequence + n + 1, payload) }
|
23
|
+
|
24
|
+
expect_any_instance_of(Lumberjack::Parser).to expectation
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "Connnection" do
|
28
|
+
it "should ack the end of a sequence" do
|
29
|
+
expect(socket).to receive(:syswrite).with(["1A", random_number_of_events + start_sequence].pack("A*N"))
|
30
|
+
connection.read_socket
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,55 +1,69 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jls-lumberjack
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.24
|
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-
|
11
|
+
date: 2015-08-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name: flores
|
15
14
|
requirement: !ruby/object:Gem::Requirement
|
16
15
|
requirements:
|
17
|
-
- -
|
16
|
+
- - ~>
|
18
17
|
- !ruby/object:Gem::Version
|
19
18
|
version: 0.0.6
|
20
|
-
|
19
|
+
name: flores
|
21
20
|
prerelease: false
|
21
|
+
type: :development
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- -
|
24
|
+
- - ~>
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: 0.0.6
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name: rspec
|
29
28
|
requirement: !ruby/object:Gem::Requirement
|
30
29
|
requirements:
|
31
|
-
- -
|
30
|
+
- - '>='
|
32
31
|
- !ruby/object:Gem::Version
|
33
32
|
version: '0'
|
34
|
-
|
33
|
+
name: rspec
|
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'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name: stud
|
43
42
|
requirement: !ruby/object:Gem::Requirement
|
44
43
|
requirements:
|
45
|
-
- -
|
44
|
+
- - '>='
|
46
45
|
- !ruby/object:Gem::Version
|
47
46
|
version: '0'
|
47
|
+
name: stud
|
48
|
+
prerelease: false
|
48
49
|
type: :development
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
name: pry
|
49
62
|
prerelease: false
|
63
|
+
type: :development
|
50
64
|
version_requirements: !ruby/object:Gem::Requirement
|
51
65
|
requirements:
|
52
|
-
- -
|
66
|
+
- - '>='
|
53
67
|
- !ruby/object:Gem::Version
|
54
68
|
version: '0'
|
55
69
|
description: lumberjack log transport library
|
@@ -59,35 +73,38 @@ executables: []
|
|
59
73
|
extensions: []
|
60
74
|
extra_rdoc_files: []
|
61
75
|
files:
|
76
|
+
- lib/lumberjack.rb
|
62
77
|
- lib/lumberjack/client.rb
|
63
78
|
- lib/lumberjack/server.rb
|
64
79
|
- spec/integration_spec.rb
|
65
80
|
- spec/lumberjack/client_spec.rb
|
81
|
+
- spec/lumberjack/server_spec.rb
|
66
82
|
- spec/spec_helper.rb
|
67
83
|
homepage: https://github.com/jordansissel/lumberjack
|
68
84
|
licenses: []
|
69
85
|
metadata: {}
|
70
|
-
post_install_message:
|
86
|
+
post_install_message:
|
71
87
|
rdoc_options: []
|
72
88
|
require_paths:
|
73
89
|
- lib
|
74
90
|
required_ruby_version: !ruby/object:Gem::Requirement
|
75
91
|
requirements:
|
76
|
-
- -
|
92
|
+
- - '>='
|
77
93
|
- !ruby/object:Gem::Version
|
78
94
|
version: '0'
|
79
95
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
80
96
|
requirements:
|
81
|
-
- -
|
97
|
+
- - '>='
|
82
98
|
- !ruby/object:Gem::Version
|
83
99
|
version: '0'
|
84
100
|
requirements: []
|
85
|
-
rubyforge_project:
|
86
|
-
rubygems_version: 2.4.
|
87
|
-
signing_key:
|
101
|
+
rubyforge_project:
|
102
|
+
rubygems_version: 2.4.8
|
103
|
+
signing_key:
|
88
104
|
specification_version: 4
|
89
105
|
summary: lumberjack log transport library
|
90
106
|
test_files:
|
91
107
|
- spec/integration_spec.rb
|
92
|
-
- spec/lumberjack/client_spec.rb
|
93
108
|
- spec/spec_helper.rb
|
109
|
+
- spec/lumberjack/client_spec.rb
|
110
|
+
- spec/lumberjack/server_spec.rb
|