jls-lumberjack 0.0.3 → 0.0.4

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.
@@ -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: