loggregator_emitter 0.0.13.pre → 0.0.15.pre

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