loggregator_emitter 0.0.13.pre → 0.0.15.pre

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ Gemfile.lock
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- loggregator_emitter (0.0.13.pre)
4
+ loggregator_emitter (0.0.15.pre)
5
5
  beefcake (~> 0.3.7)
6
6
 
7
7
  GEM
@@ -15,7 +15,7 @@ GEM
15
15
  rspec-expectations (~> 2.14.0)
16
16
  rspec-mocks (~> 2.14.0)
17
17
  rspec-core (2.14.5)
18
- rspec-expectations (2.14.2)
18
+ rspec-expectations (2.14.3)
19
19
  diff-lcs (>= 1.1.3, < 2.0)
20
20
  rspec-mocks (2.14.3)
21
21
 
@@ -3,31 +3,40 @@ require 'socket'
3
3
  module LoggregatorEmitter
4
4
  class Emitter
5
5
  def initialize(loggregator_server, source_type, source_id = nil)
6
- host, port = loggregator_server.split(":")
7
- raise RuntimeError, "Must provide valid loggregator server: #{loggregator_server}" if (host == nil || port == nil)
8
- raise RuntimeError, "Must provide IP address for loggregator server: #{loggregator_server}" unless host.match(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/)
9
- @sockaddr_in = Socket.sockaddr_in(port, host)
6
+ raise ArgumentError, "Must provide valid source type" unless valid_source_type?(source_type)
7
+
8
+ @host, @port = loggregator_server.split(/:([^:]*$)/)
9
+ raise ArgumentError, "Must provide valid loggregator server: #{loggregator_server}" if !valid_hostname || !valid_port
10
10
 
11
- raise RuntimeError, "Must provide valid source type" unless valid_source_type?(source_type)
12
11
  @source_type = source_type
13
12
  @source_id = source_id && source_id.to_s
14
13
  end
15
14
 
16
15
  def emit(app_id, message)
17
- if app_id
18
- lm = create_log_message(app_id, message, LogMessage::MessageType::OUT)
19
- send_message(lm)
20
- end
16
+ emit_message(app_id, message, LogMessage::MessageType::OUT)
21
17
  end
22
18
 
23
19
  def emit_error(app_id, message)
20
+ emit_message(app_id, message, LogMessage::MessageType::ERR)
21
+ end
22
+
23
+ private
24
+
25
+ def valid_port
26
+ @port && @port.match(/^\d+$/)
27
+ end
28
+
29
+ def valid_hostname
30
+ @host && !@host.match(/:\/\//)
31
+ end
32
+
33
+ def emit_message(app_id, message, type)
24
34
  if app_id
25
- lm = create_log_message(app_id, message, LogMessage::MessageType::ERR)
35
+ lm = create_log_message(app_id, message, type)
26
36
  send_message(lm)
27
37
  end
28
38
  end
29
39
 
30
- private
31
40
  def create_log_message(app_id, message, type)
32
41
  lm = LogMessage.new()
33
42
  lm.time = Time.now
@@ -40,13 +49,13 @@ module LoggregatorEmitter
40
49
  end
41
50
 
42
51
  def send_message(lm)
43
- s = UDPSocket.new
44
- s.do_not_reverse_lookup = true
45
-
46
52
  result = lm.encode.buf
47
53
  result.unpack("C*")
48
54
 
49
- s.sendmsg_nonblock(result, 0, @sockaddr_in)
55
+ addrinfo_udp = Addrinfo.udp(@host, @port)
56
+ s = addrinfo_udp.ipv4?() ? UDPSocket.new : UDPSocket.new(Socket::AF_INET6)
57
+ s.do_not_reverse_lookup = true
58
+ s.sendmsg_nonblock(result, 0, addrinfo_udp)
50
59
  end
51
60
 
52
61
  def valid_source_type?(source_type)
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = "loggregator_emitter"
5
- spec.version = '0.0.13.pre'
5
+ spec.version = '0.0.15.pre'
6
6
  spec.authors = ["Pivotal"]
7
7
  spec.email = ["cf-eng@pivotallabs.com"]
8
8
  spec.description = "Library to emit data to Loggregator"
@@ -1,117 +1,128 @@
1
- require 'support/fake_loggregator_server'
2
- require 'loggregator_emitter'
1
+ require "support/fake_loggregator_server"
2
+ require "loggregator_emitter"
3
3
 
4
4
  describe LoggregatorEmitter do
5
-
6
- describe 'configuring emitter' do
7
- it 'can be configured' do
8
- expect { LoggregatorEmitter::Emitter.new('0.0.0.0:12345', LogMessage::SourceType::DEA) }.not_to raise_error
9
- end
10
-
11
- it 'raises if loggregator_server is invalid' do
12
- expect { LoggregatorEmitter::Emitter.new('0.0.0.0', LogMessage::SourceType::DEA) }.to raise_error(RuntimeError)
5
+ class FreePort
6
+ def self.next_free_port
7
+ @@next_free_port ||= 12345
8
+ @@next_free_port += 1
13
9
  end
10
+ end
11
+ let(:free_port) do
12
+ FreePort.next_free_port
13
+ end
14
14
 
15
- it 'doesnt raise if source_type is valid' do
16
- expect { LoggregatorEmitter::Emitter.new('0.0.0.0:12345', LogMessage::SourceType::DEA) }.not_to raise_error
17
- end
15
+ describe "configuring emitter" do
16
+ describe "valid configurations" do
17
+ it "is valid with IP and proper source type" do
18
+ expect { LoggregatorEmitter::Emitter.new("0.0.0.0:12345", LogMessage::SourceType::DEA) }.not_to raise_error
19
+ end
18
20
 
19
- it 'raises if source_type is invalid' do
20
- expect { LoggregatorEmitter::Emitter.new('0.0.0.0:12345', 40) }.to raise_error(RuntimeError)
21
- end
21
+ it "is valid with resolveable hostname and proper source type" do
22
+ expect { LoggregatorEmitter::Emitter.new("localhost:12345", LogMessage::SourceType::DEA) }.not_to raise_error
23
+ end
22
24
 
23
- it 'raises if host is not ip is invalid' do
24
- expect { LoggregatorEmitter::Emitter.new('localhost:12345', 40) }.to raise_error(RuntimeError)
25
+ it "is valid if a server name is given" do
26
+ expect { LoggregatorEmitter::Emitter.new("some-unknown-address:12345", LogMessage::SourceType::DEA) }.not_to raise_error
27
+ end
25
28
  end
26
29
 
27
- it 'raises if host has protocol' do
28
- expect { LoggregatorEmitter::Emitter.new('http://0.0.0.0:12345', 40) }.to raise_error(RuntimeError)
30
+ describe "invalid configurations" do
31
+ describe "error based on loggregator_server" do
32
+ it "raises if host has protocol" do
33
+ expect { LoggregatorEmitter::Emitter.new("http://0.0.0.0:12345", LogMessage::SourceType::DEA) }.to raise_error(ArgumentError)
34
+ end
35
+ end
36
+
37
+ describe "error based on source_type" do
38
+ it "raises if source_type is invalid" do
39
+ expect { LoggregatorEmitter::Emitter.new("0.0.0.0:12345", 40) }.to raise_error(ArgumentError)
40
+ end
41
+ end
29
42
  end
30
43
  end
31
44
 
32
- describe 'Sending To STDOUT' do
33
- before(:each) do
34
- @emitter = LoggregatorEmitter::Emitter.new('0.0.0.0:12345', LogMessage::SourceType::CLOUD_CONTROLLER, 42)
35
- end
45
+ {"emit" => LogMessage::MessageType::OUT, "emit_error" => LogMessage::MessageType::ERR}.each do |emit_method, message_type|
46
+ describe "##{emit_method}" do
47
+ def make_emitter(host)
48
+ LoggregatorEmitter::Emitter.new("#{host}:#{free_port}", LogMessage::SourceType::CLOUD_CONTROLLER, 42)
49
+ end
36
50
 
37
- it 'successfully writes protobuffer to a socket' do
38
- server = FakeLoggregatorServer.new(12345)
39
- server.start
51
+ before do
52
+ @server = FakeLoggregatorServer.new(free_port)
53
+ @server.start
54
+ end
40
55
 
41
- @emitter.emit("my_app_id", 'Hello there!')
42
- @emitter.emit("my_app_id", 'Hello again!')
43
- @emitter.emit(nil, 'Hello again!')
56
+ it "successfully writes protobuffers using ipv4" do
57
+ emitter = make_emitter("0.0.0.0")
58
+ emitter.send(emit_method, "my_app_id", "Hello there!")
59
+ emitter.send(emit_method, "my_app_id", "Hello again!")
60
+ emitter.send(emit_method, nil, "Hello again!")
44
61
 
45
- server.stop(2)
62
+ @server.wait_for_messages_and_stop(2)
46
63
 
47
- messages = server.messages
64
+ messages = @server.messages
48
65
 
49
- expect(messages.length).to eq 2
50
- message = messages[0]
51
- expect(message.message).to eq 'Hello there!'
52
- expect(message.app_id).to eq "my_app_id"
53
- expect(message.source_type).to eq LogMessage::SourceType::CLOUD_CONTROLLER
54
- expect(message.source_id).to eq "42"
55
- expect(message.message_type).to eq LogMessage::MessageType::OUT
66
+ expect(messages.length).to eq 2
67
+ message = messages[0]
68
+ expect(message.message).to eq "Hello there!"
69
+ expect(message.app_id).to eq "my_app_id"
70
+ expect(message.source_type).to eq LogMessage::SourceType::CLOUD_CONTROLLER
71
+ expect(message.source_id).to eq "42"
72
+ expect(message.message_type).to eq message_type
56
73
 
57
- message = messages[1]
58
- expect(message.message).to eq 'Hello again!'
59
- end
60
- end
74
+ message = messages[1]
75
+ expect(message.message).to eq "Hello again!"
76
+ end
61
77
 
62
- describe 'Sending To STDOUT' do
63
- before(:each) do
64
- @emitter = LoggregatorEmitter::Emitter.new('0.0.0.0:12345', LogMessage::SourceType::CLOUD_CONTROLLER)
65
- end
66
-
67
- it 'successfully writes protobuffer to a socket' do
68
- server = FakeLoggregatorServer.new(12345)
69
- server.start
78
+ it "successfully writes protobuffers using ipv6" do
79
+ emitter = make_emitter("::1")
80
+ emitter.send(emit_method, "my_app_id", "Hello there!")
70
81
 
71
- @emitter.emit_error("my_app_id", 'Hello there!')
72
- @emitter.emit_error("my_app_id", 'Hello again!')
73
- @emitter.emit_error(nil, 'Hello again!')
82
+ @server.wait_for_messages_and_stop(1)
74
83
 
75
- server.stop(2)
84
+ messages = @server.messages
85
+ expect(messages.length).to eq 1
86
+ expect(messages[0].message).to eq "Hello there!"
87
+ end
76
88
 
77
- messages = server.messages
89
+ it "successfully writes protobuffers using a dns name" do
90
+ emitter = make_emitter("localhost")
91
+ emitter.send(emit_method, "my_app_id", "Hello there!")
78
92
 
79
- expect(messages.length).to eq 2
80
- message = messages[0]
81
- expect(message.message).to eq 'Hello there!'
82
- expect(message.app_id).to eq "my_app_id"
83
- expect(message.source_type).to eq LogMessage::SourceType::CLOUD_CONTROLLER
84
- expect(message.message_type).to eq LogMessage::MessageType::ERR
93
+ @server.wait_for_messages_and_stop(1)
85
94
 
86
- message = messages[1]
87
- expect(message.message).to eq 'Hello again!'
95
+ messages = @server.messages
96
+ expect(messages.length).to eq 1
97
+ expect(messages[0].message).to eq "Hello there!"
98
+ end
88
99
  end
89
100
  end
90
101
 
91
102
  describe "source id" do
92
103
  let(:emit_message) do
93
- server = FakeLoggregatorServer.new(12345)
104
+ server = FakeLoggregatorServer.new(free_port)
94
105
  server.start
95
106
 
96
- @emitter.emit_error("my_app_id", 'Hello there!')
107
+ @emitter.emit_error("my_app_id", "Hello there!")
97
108
 
98
- server.stop(2)
109
+ server.wait_for_messages_and_stop(2)
99
110
 
100
111
  server.messages[0]
101
112
  end
102
113
 
103
114
  it "can be nil" do
104
- @emitter = LoggregatorEmitter::Emitter.new('0.0.0.0:12345', LogMessage::SourceType::CLOUD_CONTROLLER)
115
+ @emitter = LoggregatorEmitter::Emitter.new("0.0.0.0:#{free_port}", LogMessage::SourceType::CLOUD_CONTROLLER)
105
116
  expect(emit_message.source_id).to eq nil
106
117
  end
107
118
 
108
119
  it "can be passed in as a string" do
109
- @emitter = LoggregatorEmitter::Emitter.new('0.0.0.0:12345', LogMessage::SourceType::CLOUD_CONTROLLER, "some_source_id")
120
+ @emitter = LoggregatorEmitter::Emitter.new("0.0.0.0:#{free_port}", LogMessage::SourceType::CLOUD_CONTROLLER, "some_source_id")
110
121
  expect(emit_message.source_id).to eq "some_source_id"
111
122
  end
112
123
 
113
124
  it "can be passed in as an integer" do
114
- @emitter = LoggregatorEmitter::Emitter.new('0.0.0.0:12345', LogMessage::SourceType::CLOUD_CONTROLLER, 13)
125
+ @emitter = LoggregatorEmitter::Emitter.new("0.0.0.0:#{free_port}", LogMessage::SourceType::CLOUD_CONTROLLER, 13)
115
126
  expect(emit_message.source_id).to eq "13"
116
127
  end
117
128
  end
@@ -3,40 +3,49 @@ require 'loggregator_messages/log_message.pb'
3
3
 
4
4
  class FakeLoggregatorServer
5
5
 
6
- attr_reader :messages, :port, :sock
6
+ attr_reader :messages, :port
7
7
 
8
8
  def initialize(port)
9
9
  @messages = []
10
10
  @port = port
11
- @sock = UDPSocket.new
11
+
12
+ #this server starts listening on ipv4 and ipv6, so we make two sockets
13
+ @sockets = [UDPSocket.new, UDPSocket.new(Socket::AF_INET6)]
14
+ @threads = []
12
15
  end
13
16
 
14
17
  def start
15
- @sock.bind('localhost', port)
16
-
17
- @thread = Thread.new do
18
- while true
19
- begin
20
- stuff = @sock.recv(65536)
21
- messages << LogMessage.decode(stuff)
22
- rescue Beefcake::Message::WrongTypeError, Beefcake::Message::RequiredFieldNotSetError, Beefcake::Message::InvalidValueError => e
23
- puts "ERROR"
24
- puts e
25
- end
26
-
27
- end
28
- end
18
+ bind_and_record(0, @sockets[0], "localhost")
19
+ bind_and_record(0, @sockets[1], "::1")
29
20
  end
30
21
 
31
- def stop(number_expected_messages)
22
+ def wait_for_messages_and_stop(number_expected_messages)
32
23
  max_tries = 0
33
24
  while messages.length < number_expected_messages
34
25
  sleep 0.2
35
26
  max_tries += 1
36
27
  break if max_tries > 10
37
28
  end
38
- @sock.close
39
29
 
40
- Thread.kill(@thread)
30
+ @sockets.each { |socket| socket.close}
31
+ @threads.each { |thread| Thread.kill(thread) }
32
+ end
33
+
34
+ private
35
+
36
+ def bind_and_record(index, socket, server)
37
+ socket.bind(server, port)
38
+
39
+ @threads[index] = Thread.new do
40
+ while true
41
+ begin
42
+ stuff = socket.recv(65536)
43
+ messages << LogMessage.decode(stuff)
44
+ rescue Beefcake::Message::WrongTypeError, Beefcake::Message::RequiredFieldNotSetError, Beefcake::Message::InvalidValueError => e
45
+ puts "ERROR"
46
+ puts e
47
+ end
48
+ end
49
+ end
41
50
  end
42
51
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: loggregator_emitter
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.13.pre
4
+ version: 0.0.15.pre
5
5
  prerelease: 7
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: 2013-10-07 00:00:00.000000000 Z
12
+ date: 2013-10-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: beefcake