jls-lumberjack 0.0.3 → 0.0.4

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,158 @@
1
+ require "socket"
2
+ require "thread"
3
+ require "openssl"
4
+ require "zlib"
5
+
6
+ module Lumberjack
7
+
8
+ SEQUENCE_MAX = (2**(0.size * 8 -2) -1)
9
+
10
+ class Client
11
+ def initialize(opts={})
12
+ @opts = {
13
+ :port => 0,
14
+ :addresses => [],
15
+ :ssl_certificate => nil,
16
+ :window_size => 5000
17
+ }.merge(opts)
18
+
19
+ @opts[:addresses] = [@opts[:addresses]] if @opts[:addresses].class == String
20
+ raise "Must set a port." if @opts[:port] == 0
21
+ raise "Must set atleast one address" if @opts[:addresses].empty? == 0
22
+ raise "Must set a ssl certificate or path" if @opts[:ssl_certificate].nil?
23
+
24
+ @socket = connect
25
+
26
+ end
27
+
28
+ private
29
+ def connect
30
+ addrs = @opts[:addresses].shuffle
31
+ begin
32
+ raise "Could not connect to any hosts" if addrs.empty?
33
+ opts = @opts
34
+ opts[:address] = addrs.pop
35
+ Lumberjack::Socket.new(opts)
36
+ rescue *[Errno::ECONNREFUSED,SocketError]
37
+ retry
38
+ end
39
+ end
40
+
41
+ public
42
+ def write(hash)
43
+ @socket.write_hash(hash)
44
+ end
45
+
46
+ public
47
+ def host
48
+ @socket.host
49
+ end
50
+ end
51
+
52
+ class Socket
53
+
54
+ # Create a new Lumberjack Socket.
55
+ #
56
+ # - options is a hash. Valid options are:
57
+ #
58
+ # * :port - the port to listen on
59
+ # * :address - the host/address to bind to
60
+ # * :ssl_certificate - the path to the ssl cert to use
61
+ attr_reader :sequence
62
+ attr_reader :window_size
63
+ attr_reader :host
64
+ def initialize(opts={})
65
+ @sequence = 0
66
+ @last_ack = 0
67
+ @opts = {
68
+ :port => 0,
69
+ :address => "127.0.0.1",
70
+ :ssl_certificate => nil,
71
+ :window_size => 5000
72
+ }.merge(opts)
73
+ @host = @opts[:address]
74
+ @window_size = @opts[:window_size]
75
+
76
+ tcp_socket = TCPSocket.new(@opts[:address], @opts[:port])
77
+ openssl_cert = OpenSSL::X509::Certificate.new(File.read(@opts[:ssl_certificate]))
78
+ @socket = OpenSSL::SSL::SSLSocket.new(tcp_socket)
79
+ @socket.connect
80
+
81
+ #if @socket.peer_cert.to_s != openssl_cert.to_s
82
+ # raise "Client and server certificates do not match."
83
+ #end
84
+
85
+ @socket.syswrite(["1", "W", @window_size].pack("AAN"))
86
+ end
87
+
88
+ private
89
+ def inc
90
+ @sequence = 0 if @sequence+1 > Lumberjack::SEQUENCE_MAX
91
+ @sequence += 1
92
+ end
93
+
94
+ private
95
+ def write(msg)
96
+ compress = Zlib::Deflate.deflate(msg)
97
+ @socket.syswrite(["1","C",compress.length,compress].pack("AANA#{compress.length}"))
98
+ end
99
+
100
+ public
101
+ def write_hash(hash)
102
+ frame = to_frame(hash, inc)
103
+ ack if (@sequence - @last_ack) >= @window_size
104
+ write frame
105
+ end
106
+
107
+ private
108
+ def ack
109
+ version = @socket.read(1)
110
+ type = @socket.read(1)
111
+ raise "Whoa we shouldn't get this frame: #{type}" if type != "A"
112
+ @last_ack = @socket.read(4).unpack("N").first
113
+ ack if (@sequence - @last_ack) >= Lumberjack::WINDOW_SIZE
114
+ end
115
+
116
+ private
117
+ def to_frame(hash, sequence)
118
+ frame = ["1", "D", sequence]
119
+ pack = "AAN"
120
+ keys = deep_keys(hash)
121
+ frame << keys.length
122
+ pack << "N"
123
+ keys.each do |k|
124
+ val = deep_get(hash,k)
125
+ key_length = k.length
126
+ val_length = val.length
127
+ frame << key_length
128
+ pack << "N"
129
+ frame << k
130
+ pack << "A#{key_length}"
131
+ frame << val_length
132
+ pack << "N"
133
+ frame << val
134
+ pack << "A#{val_length}"
135
+ end
136
+ frame.pack(pack)
137
+ end
138
+
139
+ private
140
+ def deep_get(hash, key="")
141
+ return hash if key.nil?
142
+ deep_get(
143
+ hash[key.split('.').first],
144
+ key[key.split('.').first.length+1..key.length]
145
+ )
146
+ end
147
+
148
+ private
149
+ def deep_keys(hash, prefix="")
150
+ keys = []
151
+ hash.each do |k,v|
152
+ keys << "#{prefix}#{k}" if v.class == String
153
+ keys << deep_keys(hash[k], "#{k}.") if v.class == Hash
154
+ end
155
+ keys.flatten
156
+ end
157
+ end
158
+ end
@@ -127,8 +127,7 @@ module Lumberjack
127
127
  return @io.read(bytes)
128
128
  elsif @buffer.length > bytes
129
129
  #puts "reading buffered"
130
- data = @buffer[0...bytes]
131
- @buffer[0...bytes] = ""
130
+ data = @buffer.slice!(0...bytes)
132
131
  return data
133
132
  else
134
133
  data = @buffer.clone
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jls-lumberjack
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-06 00:00:00.000000000 Z
12
+ date: 2012-11-09 00:00:00.000000000 Z
13
13
  dependencies: []
14
14
  description: lumberjack log transport library
15
15
  email:
@@ -19,6 +19,7 @@ extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
21
  - lib/lumberjack/server.rb
22
+ - lib/lumberjack/client.rb
22
23
  homepage: https://github.com/jordansissel/lumberjack
23
24
  licenses: []
24
25
  post_install_message: