gelf_redux 3.1.1
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 +7 -0
- data/.gemtest +0 -0
- data/CHANGELOG +54 -0
- data/CONTRIBUTING.md +1 -0
- data/Gemfile +10 -0
- data/Gemfile.lock +24 -0
- data/LICENSE +20 -0
- data/README.md +69 -0
- data/Rakefile +41 -0
- data/VERSION +1 -0
- data/benchmarks/notifier.rb +39 -0
- data/gelf.gemspec +70 -0
- data/lib/gelf/logger.rb +64 -0
- data/lib/gelf/notifier.rb +280 -0
- data/lib/gelf/severity.rb +50 -0
- data/lib/gelf/transport/tcp.rb +79 -0
- data/lib/gelf/transport/tcp_tls.rb +129 -0
- data/lib/gelf/transport/udp.rb +41 -0
- data/lib/gelf.rb +16 -0
- data/test/helper.rb +11 -0
- data/test/test_logger.rb +247 -0
- data/test/test_notifier.rb +317 -0
- data/test/test_ruby_sender.rb +28 -0
- data/test/test_severity.rb +9 -0
- metadata +142 -0
data/test/test_logger.rb
ADDED
@@ -0,0 +1,247 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestLogger < Test::Unit::TestCase
|
4
|
+
context "with logger with mocked sender" do
|
5
|
+
setup do
|
6
|
+
Socket.stubs(:gethostname).returns('stubbed_hostname')
|
7
|
+
@logger = GELF::Logger.new
|
8
|
+
@sender = mock
|
9
|
+
@logger.instance_variable_set('@sender', @sender)
|
10
|
+
end
|
11
|
+
|
12
|
+
should "respond to #close" do
|
13
|
+
assert @logger.respond_to?(:close)
|
14
|
+
end
|
15
|
+
|
16
|
+
context "#add" do
|
17
|
+
# logger.add(Logger::INFO, nil)
|
18
|
+
should 'implement add method with level, message and facility from defaults' do
|
19
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
20
|
+
level == GELF::INFO &&
|
21
|
+
hash['short_message'] == 'gelf-rb' &&
|
22
|
+
hash['facility'] == 'gelf-rb'
|
23
|
+
end
|
24
|
+
@logger.add(GELF::INFO, nil)
|
25
|
+
end
|
26
|
+
|
27
|
+
# logger.add(Logger::INFO, 'Message')
|
28
|
+
should "implement add method with level and message from parameters, facility from defaults" do
|
29
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
30
|
+
level == GELF::INFO &&
|
31
|
+
hash['short_message'] == 'Message' &&
|
32
|
+
hash['facility'] == 'gelf-rb'
|
33
|
+
end
|
34
|
+
@logger.add(GELF::INFO, nil, 'Message')
|
35
|
+
end
|
36
|
+
|
37
|
+
# logger.add(Logger::INFO, RuntimeError.new('Boom!'))
|
38
|
+
should "implement add method with level and exception from parameters, facility from defaults" do
|
39
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
40
|
+
level == GELF::INFO &&
|
41
|
+
hash['short_message'] == 'RuntimeError: Boom!' &&
|
42
|
+
hash['full_message'] =~ /^Backtrace/ &&
|
43
|
+
hash['facility'] == 'gelf-rb'
|
44
|
+
end
|
45
|
+
@logger.add(GELF::INFO, nil, RuntimeError.new('Boom!'))
|
46
|
+
end
|
47
|
+
|
48
|
+
# logger.add(Logger::INFO) { 'Message' }
|
49
|
+
should "implement add method with level from parameter, message from block, facility from defaults" do
|
50
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
51
|
+
level == GELF::INFO &&
|
52
|
+
hash['short_message'] == 'Message' &&
|
53
|
+
hash['facility'] == 'gelf-rb'
|
54
|
+
end
|
55
|
+
@logger.add(GELF::INFO, nil, nil) { 'Message' }
|
56
|
+
end
|
57
|
+
|
58
|
+
# logger.add(Logger::INFO) { RuntimeError.new('Boom!') }
|
59
|
+
should "implement add method with level from parameter, exception from block, facility from defaults" do
|
60
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
61
|
+
level == GELF::INFO &&
|
62
|
+
hash['short_message'] == 'RuntimeError: Boom!' &&
|
63
|
+
hash['full_message'] =~ /^Backtrace/ &&
|
64
|
+
hash['facility'] == 'gelf-rb'
|
65
|
+
end
|
66
|
+
@logger.add(GELF::INFO, nil, nil) { RuntimeError.new('Boom!') }
|
67
|
+
end
|
68
|
+
|
69
|
+
# logger.add(Logger::INFO, 'Message', 'Facility')
|
70
|
+
should "implement add method with level, message and facility from parameters" do
|
71
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
72
|
+
level == GELF::INFO &&
|
73
|
+
hash['short_message'] == 'Message' &&
|
74
|
+
hash['facility'] == 'Facility'
|
75
|
+
end
|
76
|
+
@logger.add(GELF::INFO, 'Message', 'Facility')
|
77
|
+
end
|
78
|
+
|
79
|
+
# logger.add(Logger::INFO, 'Message', nil)
|
80
|
+
should "use facility from initialization if facility is nil" do
|
81
|
+
logger = GELF::Logger.new('localhost', 12202, 'WAN', :facility => 'foo-bar')
|
82
|
+
logger.expects(:notify_with_level!).with do |level, hash|
|
83
|
+
level == GELF::INFO &&
|
84
|
+
hash['short_message'] == 'Message' &&
|
85
|
+
hash['facility'] == 'foo-bar'
|
86
|
+
end
|
87
|
+
logger.add(GELF::INFO, 'Message', nil)
|
88
|
+
end
|
89
|
+
|
90
|
+
# logger.add(Logger::INFO, 'Message', nil)
|
91
|
+
should "use default facility if facility is nil" do
|
92
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
93
|
+
level == GELF::INFO &&
|
94
|
+
hash['short_message'] == 'Message' &&
|
95
|
+
hash['facility'] == 'gelf-rb'
|
96
|
+
end
|
97
|
+
@logger.add(GELF::INFO, 'Message', nil)
|
98
|
+
end
|
99
|
+
|
100
|
+
# logger.add(Logger::INFO, RuntimeError.new('Boom!'), 'Facility')
|
101
|
+
should "implement add method with level, exception and facility from parameters" do
|
102
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
103
|
+
level == GELF::INFO &&
|
104
|
+
hash['short_message'] == 'RuntimeError: Boom!' &&
|
105
|
+
hash['full_message'] =~ /^Backtrace/ &&
|
106
|
+
hash['facility'] == 'Facility'
|
107
|
+
end
|
108
|
+
@logger.add(GELF::INFO, RuntimeError.new('Boom!'), 'Facility')
|
109
|
+
end
|
110
|
+
|
111
|
+
# logger.add(Logger::INFO, nil, 'Facility') { 'Message' }
|
112
|
+
should "implement add method with level and facility from parameters, message from block" do
|
113
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
114
|
+
level == GELF::INFO &&
|
115
|
+
hash['short_message'] == 'Message' &&
|
116
|
+
hash['facility'] == 'Facility'
|
117
|
+
end
|
118
|
+
@logger.add(GELF::INFO, nil, 'Facility') { 'Message' }
|
119
|
+
end
|
120
|
+
|
121
|
+
# logger.add(Logger::INFO, nil, 'Facility') { RuntimeError.new('Boom!') }
|
122
|
+
should "implement add method with level and facility from parameters, exception from block" do
|
123
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
124
|
+
level == GELF::INFO &&
|
125
|
+
hash['short_message'] == 'RuntimeError: Boom!' &&
|
126
|
+
hash['full_message'] =~ /^Backtrace/ &&
|
127
|
+
hash['facility'] == 'Facility'
|
128
|
+
end
|
129
|
+
@logger.add(GELF::INFO, nil, 'Facility') { RuntimeError.new('Boom!') }
|
130
|
+
end
|
131
|
+
|
132
|
+
# logger.add(Logger::INFO, { :short_message => "Some message" })
|
133
|
+
should "implement add method with level and message from hash, facility from defaults" do
|
134
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
135
|
+
level == GELF::INFO &&
|
136
|
+
hash['short_message'] == 'Some message' &&
|
137
|
+
hash['facility'] == 'gelf-rb'
|
138
|
+
end
|
139
|
+
@logger.add(GELF::INFO, { :short_message => "Some message" })
|
140
|
+
end
|
141
|
+
|
142
|
+
# logger.add(Logger::INFO, { :short_message => "Some message", :_foo => "bar", "_zomg" => "wat" })
|
143
|
+
should "implement add method with level and message from hash, facility from defaults and some additional fields" do
|
144
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
145
|
+
level == GELF::INFO &&
|
146
|
+
hash['short_message'] == 'Some message' &&
|
147
|
+
hash['facility'] == 'gelf-rb' &&
|
148
|
+
hash['_foo'] == 'bar' &&
|
149
|
+
hash['_zomg'] == 'wat'
|
150
|
+
end
|
151
|
+
@logger.add(GELF::INFO, { :short_message => "Some message", :_foo => "bar", "_zomg" => "wat"})
|
152
|
+
end
|
153
|
+
|
154
|
+
# logger.add(Logger::INFO, { :short_message => "Some message", :_foo => "bar", "_zomg" => "wat" }, 'somefac')
|
155
|
+
should "implement add method with level and message from hash, facility from parameters and some additional fields" do
|
156
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
157
|
+
level == GELF::INFO &&
|
158
|
+
hash['short_message'] == 'Some message' &&
|
159
|
+
hash['facility'] == 'somefac' &&
|
160
|
+
hash['_foo'] == 'bar' &&
|
161
|
+
hash['_zomg'] == 'wat'
|
162
|
+
end
|
163
|
+
@logger.add(GELF::INFO, { :short_message => "Some message", :_foo => "bar", "_zomg" => "wat"}, "somefac")
|
164
|
+
end
|
165
|
+
|
166
|
+
should 'implement add method with level and ignore zero-length message strings' do
|
167
|
+
@logger.expects(:notify_with_level!).never
|
168
|
+
@logger.add(GELF::INFO, '')
|
169
|
+
end
|
170
|
+
|
171
|
+
should 'implement add method with level and ignore hash without short_message key' do
|
172
|
+
@logger.expects(:notify_with_level!).never
|
173
|
+
@logger.add(GELF::INFO, { :message => 'Some message' })
|
174
|
+
end
|
175
|
+
|
176
|
+
should 'implement add method with level and ignore hash with zero-length short_message entry' do
|
177
|
+
@logger.expects(:notify_with_level!).never
|
178
|
+
@logger.add(GELF::INFO, { :short_message => '' })
|
179
|
+
end
|
180
|
+
|
181
|
+
should 'implement add method with level and ignore hash with nil short_message entry' do
|
182
|
+
@logger.expects(:notify_with_level!).never
|
183
|
+
@logger.add(GELF::INFO, { :short_message => nil })
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
GELF::Levels.constants.each do |const|
|
188
|
+
# logger.error "Argument #{ @foo } mismatch."
|
189
|
+
should "call add with level #{const} from method name, message from parameter" do
|
190
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
191
|
+
level == GELF.const_get(const) &&
|
192
|
+
hash['short_message'] == 'message' &&
|
193
|
+
hash['facility'] == 'gelf-rb'
|
194
|
+
end
|
195
|
+
@logger.__send__(const.downcase, 'message')
|
196
|
+
end
|
197
|
+
|
198
|
+
# logger.fatal { "Argument 'foo' not given." }
|
199
|
+
should "call add with level #{const} from method name, message from block" do
|
200
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
201
|
+
level == GELF.const_get(const) &&
|
202
|
+
hash['short_message'] == 'message' &&
|
203
|
+
hash['facility'] == 'gelf-rb'
|
204
|
+
end
|
205
|
+
@logger.__send__(const.downcase) { 'message' }
|
206
|
+
end
|
207
|
+
|
208
|
+
# logger.info('initialize') { "Initializing..." }
|
209
|
+
should "call add with level #{const} from method name, facility from parameter, message from block" do
|
210
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
211
|
+
level == GELF.const_get(const) &&
|
212
|
+
hash['short_message'] == 'message' &&
|
213
|
+
hash['facility'] == 'facility'
|
214
|
+
end
|
215
|
+
@logger.__send__(const.downcase, 'facility') { 'message' }
|
216
|
+
end
|
217
|
+
|
218
|
+
should "respond to #{const.downcase}?" do
|
219
|
+
@logger.level = GELF.const_get(const) - 1
|
220
|
+
assert @logger.__send__(const.to_s.downcase + '?')
|
221
|
+
@logger.level = GELF.const_get(const)
|
222
|
+
assert @logger.__send__(const.to_s.downcase + '?')
|
223
|
+
@logger.level = GELF.const_get(const) + 1
|
224
|
+
assert !@logger.__send__(const.to_s.downcase + '?')
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
should "support Logger#<<" do
|
229
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
230
|
+
level == GELF::UNKNOWN &&
|
231
|
+
hash['short_message'] == "Message"
|
232
|
+
end
|
233
|
+
@logger << "Message"
|
234
|
+
end
|
235
|
+
|
236
|
+
should "have formatter attribute" do
|
237
|
+
@logger.formatter
|
238
|
+
end
|
239
|
+
|
240
|
+
context "close" do
|
241
|
+
should "close socket" do
|
242
|
+
@sender.expects(:close).once
|
243
|
+
@logger.close
|
244
|
+
end
|
245
|
+
end
|
246
|
+
end
|
247
|
+
end
|
@@ -0,0 +1,317 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
RANDOM_DATA = ('A'..'Z').to_a
|
4
|
+
|
5
|
+
class TestNotifier < Test::Unit::TestCase
|
6
|
+
should "allow access to host, port, max_chunk_size and default_options" do
|
7
|
+
Socket.expects(:gethostname).returns('default_hostname')
|
8
|
+
n = GELF::Notifier.new
|
9
|
+
assert_equal [[['localhost', 12201]], 1420], [n.addresses, n.max_chunk_size]
|
10
|
+
assert_equal( { 'version' => '1.0', 'level' => GELF::UNKNOWN, 'protocol' => 0,
|
11
|
+
'host' => 'default_hostname', 'facility' => 'gelf-rb' },
|
12
|
+
n.default_options )
|
13
|
+
n.addresses, n.max_chunk_size, n.default_options = [['graylog2.org', 7777]], :lan, {:host => 'grayhost'}
|
14
|
+
assert_equal [['graylog2.org', 7777]], n.addresses
|
15
|
+
assert_equal 8154, n.max_chunk_size
|
16
|
+
assert_equal({'host' => 'grayhost'}, n.default_options)
|
17
|
+
|
18
|
+
n.max_chunk_size = 1337.1
|
19
|
+
assert_equal 1337, n.max_chunk_size
|
20
|
+
end
|
21
|
+
|
22
|
+
context "with notifier with mocked sender" do
|
23
|
+
setup do
|
24
|
+
Socket.stubs(:gethostname).returns('stubbed_hostname')
|
25
|
+
@notifier = GELF::Notifier.new('host', 12345)
|
26
|
+
@sender = mock
|
27
|
+
@notifier.instance_variable_set('@sender', @sender)
|
28
|
+
end
|
29
|
+
|
30
|
+
context "extract_hash" do
|
31
|
+
should "check arguments" do
|
32
|
+
assert_raise(ArgumentError) { @notifier.__send__(:extract_hash) }
|
33
|
+
assert_raise(ArgumentError) { @notifier.__send__(:extract_hash, 1, 2, 3) }
|
34
|
+
end
|
35
|
+
|
36
|
+
should "work with hash" do
|
37
|
+
hash = @notifier.__send__(:extract_hash, { 'version' => '1.0', 'short_message' => 'message' })
|
38
|
+
assert_equal '1.0', hash['version']
|
39
|
+
assert_equal 'message', hash['short_message']
|
40
|
+
end
|
41
|
+
|
42
|
+
should "work with any object which responds to #to_hash" do
|
43
|
+
o = Object.new
|
44
|
+
o.expects(:to_hash).returns({ 'version' => '1.0', 'short_message' => 'message' })
|
45
|
+
hash = @notifier.__send__(:extract_hash, o)
|
46
|
+
assert_equal '1.0', hash['version']
|
47
|
+
assert_equal 'message', hash['short_message']
|
48
|
+
end
|
49
|
+
|
50
|
+
should "work with exception with backtrace" do
|
51
|
+
e = RuntimeError.new('message')
|
52
|
+
e.set_backtrace(caller)
|
53
|
+
hash = @notifier.__send__(:extract_hash, e)
|
54
|
+
assert_equal 'RuntimeError: message', hash['short_message']
|
55
|
+
assert_match(/Backtrace/, hash['full_message'])
|
56
|
+
assert_equal GELF::ERROR, hash['level']
|
57
|
+
end
|
58
|
+
|
59
|
+
should "work with exception without backtrace" do
|
60
|
+
e = RuntimeError.new('message')
|
61
|
+
hash = @notifier.__send__(:extract_hash, e)
|
62
|
+
assert_match(/Backtrace is not available/, hash['full_message'])
|
63
|
+
end
|
64
|
+
|
65
|
+
should "work with exception and hash" do
|
66
|
+
e, h = RuntimeError.new('message'), {'param' => 1, 'level' => GELF::FATAL, 'short_message' => 'will be hidden by exception'}
|
67
|
+
hash = @notifier.__send__(:extract_hash, e, h)
|
68
|
+
assert_equal 'RuntimeError: message', hash['short_message']
|
69
|
+
assert_equal GELF::FATAL, hash['level']
|
70
|
+
assert_equal 1, hash['param']
|
71
|
+
end
|
72
|
+
|
73
|
+
should "work with plain text" do
|
74
|
+
hash = @notifier.__send__(:extract_hash, 'message')
|
75
|
+
assert_equal 'message', hash['short_message']
|
76
|
+
assert_equal GELF::INFO, hash['level']
|
77
|
+
end
|
78
|
+
|
79
|
+
should "work with plain text and hash" do
|
80
|
+
hash = @notifier.__send__(:extract_hash, 'message', 'level' => GELF::WARN)
|
81
|
+
assert_equal 'message', hash['short_message']
|
82
|
+
assert_equal GELF::WARN, hash['level']
|
83
|
+
end
|
84
|
+
|
85
|
+
should "covert hash keys to strings" do
|
86
|
+
hash = @notifier.__send__(:extract_hash, :short_message => :message)
|
87
|
+
assert hash.has_key?('short_message')
|
88
|
+
assert !hash.has_key?(:short_message)
|
89
|
+
end
|
90
|
+
|
91
|
+
should "not overwrite keys on convert" do
|
92
|
+
assert_raise(ArgumentError) { @notifier.__send__(:extract_hash, :short_message => :message1, 'short_message' => 'message2') }
|
93
|
+
end
|
94
|
+
|
95
|
+
should "use default_options" do
|
96
|
+
@notifier.default_options = {:foo => 'bar', 'short_message' => 'will be hidden by explicit argument', 'host' => 'some_host'}
|
97
|
+
hash = @notifier.__send__(:extract_hash, { 'version' => '1.0', 'short_message' => 'message' })
|
98
|
+
assert_equal 'bar', hash['foo']
|
99
|
+
assert_equal 'message', hash['short_message']
|
100
|
+
end
|
101
|
+
|
102
|
+
should "be compatible with HoptoadNotifier" do
|
103
|
+
# https://github.com/thoughtbot/hoptoad_notifier/blob/master/README.rdoc, section Going beyond exceptions
|
104
|
+
hash = @notifier.__send__(:extract_hash, :error_class => 'Class', :error_message => 'Message')
|
105
|
+
assert_equal 'Class: Message', hash['short_message']
|
106
|
+
end
|
107
|
+
|
108
|
+
should "set file and line" do
|
109
|
+
line = __LINE__
|
110
|
+
hash = @notifier.__send__(:extract_hash, { 'version' => '1.0', 'short_message' => 'message' })
|
111
|
+
assert_match(/test_notifier.rb/, hash['file'])
|
112
|
+
assert_equal line + 1, hash['line']
|
113
|
+
end
|
114
|
+
|
115
|
+
should "set timestamp to current time if not set" do
|
116
|
+
hash = @notifier.__send__(:extract_hash, { 'version' => '1.0', 'short_message' => 'message' })
|
117
|
+
assert_instance_of Float, hash['timestamp']
|
118
|
+
now = Time.now.utc.to_f
|
119
|
+
assert ((now - 1)..(now + 1)).include?(hash['timestamp'])
|
120
|
+
end
|
121
|
+
|
122
|
+
should "set timestamp to specified time" do
|
123
|
+
timestamp = 1319799449.13765
|
124
|
+
hash = @notifier.__send__(:extract_hash, { 'version' => '1.0', 'short_message' => 'message', 'timestamp' => timestamp })
|
125
|
+
assert_equal timestamp, hash['timestamp']
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
context "serialize_hash" do
|
130
|
+
setup do
|
131
|
+
@notifier.level_mapping = :direct
|
132
|
+
hash = { 'level' => GELF::WARN, 'field' => 'value' }
|
133
|
+
@data = @notifier.__send__(:serialize_hash, hash)
|
134
|
+
assert @data.respond_to?(:each) # Enumerable::Enumerator in 1.8, ::Enumerator in 1.9, so...
|
135
|
+
@deserialized_hash = JSON.parse(Zlib::Inflate.inflate(@data.to_a.pack('C*')))
|
136
|
+
assert_instance_of Hash, @deserialized_hash
|
137
|
+
end
|
138
|
+
|
139
|
+
should "map level using mapping" do
|
140
|
+
assert_not_equal GELF::WARN, @deserialized_hash['level']
|
141
|
+
assert_not_equal GELF::LOGGER_MAPPING[GELF::WARN], @deserialized_hash['level']
|
142
|
+
assert_equal GELF::DIRECT_MAPPING[GELF::WARN], @deserialized_hash['level']
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
context "datagrams_from_hash" do
|
147
|
+
should "not split short data" do
|
148
|
+
hash = { 'version' => '1.0', 'short_message' => 'message' }
|
149
|
+
datagrams = @notifier.__send__(:datagrams_from_hash, hash)
|
150
|
+
assert_equal 1, datagrams.count
|
151
|
+
assert_instance_of String, datagrams[0]
|
152
|
+
|
153
|
+
asserted = "\x78\x9c"
|
154
|
+
if RUBY_VERSION[0,1].to_i >= 2
|
155
|
+
puts "I'm a Ruby > 2.0.0. Enforcing ASCII-8BIT. (#{RUBY_VERSION}/#{RUBY_VERSION[0,1].to_i})"
|
156
|
+
# lol well yeah, Rubby.
|
157
|
+
# http://stackoverflow.com/questions/15843684/binary-string-literals-in-ruby-2-0
|
158
|
+
asserted = asserted.b
|
159
|
+
end
|
160
|
+
|
161
|
+
assert_equal asserted, datagrams[0][0..1] # zlib header
|
162
|
+
end
|
163
|
+
|
164
|
+
should "split long data" do
|
165
|
+
srand(1) # for stable tests
|
166
|
+
hash = { 'version' => '1.0', 'short_message' => 'message' }
|
167
|
+
hash.merge!('something' => (0..3000).map { RANDOM_DATA[rand(RANDOM_DATA.count)] }.join) # or it will be compressed too good
|
168
|
+
datagrams = @notifier.__send__(:datagrams_from_hash, hash)
|
169
|
+
assert_equal 2, datagrams.count
|
170
|
+
datagrams.each_index do |i|
|
171
|
+
datagram = datagrams[i]
|
172
|
+
assert_instance_of String, datagram
|
173
|
+
assert datagram[0..1] == "\x1e\x0f" # chunked GELF magic number
|
174
|
+
# datagram[2..9] is a message id
|
175
|
+
assert_equal i, datagram[10].ord
|
176
|
+
assert_equal datagrams.count, datagram[11].ord
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
should "split long data when subclassed" do
|
181
|
+
class MyNotifier < GELF::Notifier; end
|
182
|
+
|
183
|
+
@notifier = MyNotifier.new('host', 1234)
|
184
|
+
@sender = mock
|
185
|
+
@notifier.instance_variable_set('@sender', @sender)
|
186
|
+
|
187
|
+
srand(1) # for stable tests
|
188
|
+
hash = { 'version' => '1.0', 'short_message' => 'message' }
|
189
|
+
hash.merge!('something' => (0..3000).map { RANDOM_DATA[rand(RANDOM_DATA.count)] }.join) # or it will be compressed too good
|
190
|
+
datagrams = @notifier.__send__(:datagrams_from_hash, hash)
|
191
|
+
assert_equal 2, datagrams.count
|
192
|
+
datagrams.each_index do |i|
|
193
|
+
datagram = datagrams[i]
|
194
|
+
assert_instance_of String, datagram
|
195
|
+
assert datagram[0..1] == "\x1e\x0f" # chunked GELF magic number
|
196
|
+
# datagram[2..9] is a message id
|
197
|
+
assert_equal i, datagram[10].ord
|
198
|
+
assert_equal datagrams.count, datagram[11].ord
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
should "throw an error if more than MAX_CHUNKS will be created" do
|
203
|
+
srand(1) # for stable tests
|
204
|
+
hash = { 'version' => '1.0', 'short_message' => 'message' }
|
205
|
+
hash.merge!('something' => (0..3000).map { RANDOM_DATA[rand(RANDOM_DATA.count)] }.join) # or it will be compressed too good
|
206
|
+
@notifier.max_chunk_size = 10
|
207
|
+
@notifier.instance_variable_set('@hash', hash)
|
208
|
+
assert_raise(ArgumentError) do
|
209
|
+
@notifier.__send__(:datagrams_from_hash)
|
210
|
+
end
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
context "level threshold" do
|
215
|
+
setup do
|
216
|
+
@notifier.level = GELF::WARN
|
217
|
+
@hash = { 'version' => '1.0', 'short_message' => 'message' }
|
218
|
+
end
|
219
|
+
|
220
|
+
['debug', 'DEBUG', :debug].each do |l|
|
221
|
+
should "allow to set threshold as #{l.inspect}" do
|
222
|
+
@notifier.level = l
|
223
|
+
assert_equal GELF::DEBUG, @notifier.level
|
224
|
+
end
|
225
|
+
end
|
226
|
+
|
227
|
+
should "not send notifications with level below threshold" do
|
228
|
+
@sender.expects(:send_datagrams).never
|
229
|
+
@notifier.notify!(@hash.merge('level' => GELF::DEBUG))
|
230
|
+
end
|
231
|
+
|
232
|
+
should "not notifications with level equal or above threshold" do
|
233
|
+
@sender.expects(:send_datagrams).once
|
234
|
+
@notifier.notify!(@hash.merge('level' => GELF::WARN))
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
context "close" do
|
239
|
+
should "close sender" do
|
240
|
+
@sender.expects(:close).once
|
241
|
+
@notifier.close
|
242
|
+
end
|
243
|
+
end
|
244
|
+
|
245
|
+
context "when disabled" do
|
246
|
+
setup do
|
247
|
+
@notifier.disable
|
248
|
+
end
|
249
|
+
|
250
|
+
should "not send datagrams" do
|
251
|
+
@sender.expects(:send_datagrams).never
|
252
|
+
@notifier.expects(:extract_hash).never
|
253
|
+
@notifier.notify!({ 'version' => '1.0', 'short_message' => 'message' })
|
254
|
+
end
|
255
|
+
|
256
|
+
context "and enabled again" do
|
257
|
+
setup do
|
258
|
+
@notifier.enable
|
259
|
+
end
|
260
|
+
|
261
|
+
should "send datagrams" do
|
262
|
+
@sender.expects(:send_datagrams)
|
263
|
+
@notifier.notify!({ 'version' => '1.0', 'short_message' => 'message' })
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
should "pass valid data to sender" do
|
269
|
+
@sender.expects(:send_datagrams).with do |datagrams|
|
270
|
+
datagrams.is_a?(Array) && datagrams[0].is_a?(String)
|
271
|
+
end
|
272
|
+
@notifier.notify!({ 'version' => '1.0', 'short_message' => 'message' })
|
273
|
+
end
|
274
|
+
|
275
|
+
should "not mutate arguments" do
|
276
|
+
data = { 'version' => '1.0', 'short_message' => 'message', foo: { bar: "BAZ" } }
|
277
|
+
original_hash = data.hash
|
278
|
+
|
279
|
+
@sender.expects(:send_datagrams)
|
280
|
+
@notifier.notify!(data)
|
281
|
+
|
282
|
+
assert_equal(data.hash, original_hash)
|
283
|
+
end
|
284
|
+
|
285
|
+
GELF::Levels.constants.each do |const|
|
286
|
+
should "call notify with level #{const} from method name" do
|
287
|
+
@notifier.expects(:notify_with_level).with(GELF.const_get(const), { 'version' => '1.0', 'short_message' => 'message' })
|
288
|
+
@notifier.__send__(const.downcase, { 'version' => '1.0', 'short_message' => 'message' })
|
289
|
+
end
|
290
|
+
end
|
291
|
+
|
292
|
+
should "not rescue from invalid invocation of #notify!" do
|
293
|
+
assert_raise(ArgumentError) { @notifier.notify!(:no_short_message => 'too bad') }
|
294
|
+
end
|
295
|
+
|
296
|
+
should "rescue from invalid invocation of #notify" do
|
297
|
+
@notifier.expects(:notify_with_level!).with(nil, instance_of(Hash)).raises(ArgumentError)
|
298
|
+
@notifier.expects(:notify_with_level!).with(GELF::UNKNOWN, instance_of(ArgumentError))
|
299
|
+
assert_nothing_raised { @notifier.notify(:no_short_message => 'too bad') }
|
300
|
+
end
|
301
|
+
end
|
302
|
+
|
303
|
+
context "with notifier with real sender" do
|
304
|
+
setup do
|
305
|
+
@notifier = GELF::Notifier.new('no_such_host_321')
|
306
|
+
end
|
307
|
+
|
308
|
+
should "raise exception" do
|
309
|
+
assert_raise(SocketError) { @notifier.notify('Hello!') }
|
310
|
+
end
|
311
|
+
|
312
|
+
should "not raise exception if asked" do
|
313
|
+
@notifier.rescue_network_errors = true
|
314
|
+
assert_nothing_raised { @notifier.notify('Hello!') }
|
315
|
+
end
|
316
|
+
end
|
317
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestRubyUdpSender < Test::Unit::TestCase
|
4
|
+
context "with ruby sender" do
|
5
|
+
setup do
|
6
|
+
@addresses = [['localhost', 12201], ['localhost', 12202]]
|
7
|
+
@sender = GELF::Transport::UDP.new(@addresses)
|
8
|
+
@datagrams1 = %w(d1 d2 d3)
|
9
|
+
@datagrams2 = %w(e1 e2 e3)
|
10
|
+
end
|
11
|
+
|
12
|
+
context "send_datagrams" do
|
13
|
+
setup do
|
14
|
+
@sender.send_datagrams(@datagrams1)
|
15
|
+
@sender.send_datagrams(@datagrams2)
|
16
|
+
end
|
17
|
+
|
18
|
+
before_should "be called 3 times with 1st and 2nd address" do
|
19
|
+
UDPSocket.any_instance.expects(:send).times(3).with do |datagram, _, host, port|
|
20
|
+
datagram.start_with?('d') && host == 'localhost' && port == 12201
|
21
|
+
end
|
22
|
+
UDPSocket.any_instance.expects(:send).times(3).with do |datagram, _, host, port|
|
23
|
+
datagram.start_with?('e') && host == 'localhost' && port == 12202
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|