gelf 1.4.0.beta1 → 1.4.0
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/Rakefile +9 -44
- data/VERSION +1 -1
- data/benchmarks/notifier.rb +7 -19
- data/gelf.gemspec +4 -5
- data/lib/gelf.rb +0 -1
- data/lib/gelf/logger.rb +19 -2
- data/lib/gelf/notifier.rb +43 -73
- data/lib/gelf/ruby_sender.rb +5 -20
- data/test/test_logger.rb +41 -0
- data/test/test_notifier.rb +10 -23
- metadata +62 -78
- data/benchmarks/incremental.rb +0 -17
data/Rakefile
CHANGED
@@ -51,47 +51,12 @@ rescue LoadError => e
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
config.flay = { :dirs_to_flay => ['lib'],
|
65
|
-
:minimum_score => 10 }
|
66
|
-
config.flog = { :dirs_to_flog => ['lib'] }
|
67
|
-
config.reek = { :dirs_to_reek => ['lib'] }
|
68
|
-
config.roodi = { :dirs_to_roodi => ['lib'] }
|
69
|
-
config.rcov = { :environment => 'test',
|
70
|
-
:test_files => ['test/test_*.rb'],
|
71
|
-
:rcov_opts => ["-I 'lib:test'",
|
72
|
-
"--sort coverage",
|
73
|
-
"--no-html",
|
74
|
-
"--text-coverage",
|
75
|
-
"--no-color",
|
76
|
-
"--exclude /test/,/gems/"]}
|
77
|
-
config.graph_engine = :gchart
|
78
|
-
end
|
79
|
-
|
80
|
-
rescue LoadError, NameError => e
|
81
|
-
desc 'Generate all metrics reports'
|
82
|
-
task :'metrics:all' do
|
83
|
-
puts e.inspect
|
84
|
-
# puts e.backtrace
|
85
|
-
abort "metric_fu is not available. Run: gem install metric_fu"
|
86
|
-
end
|
87
|
-
end
|
88
|
-
|
89
|
-
require 'rake/rdoctask'
|
90
|
-
Rake::RDocTask.new do |rdoc|
|
91
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
92
|
-
|
93
|
-
rdoc.rdoc_dir = 'rdoc'
|
94
|
-
rdoc.title = "gelf #{version}"
|
95
|
-
rdoc.rdoc_files.include('README*')
|
96
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
97
|
-
end
|
54
|
+
#require 'rake/rdoctask'
|
55
|
+
#Rake::RDocTask.new do |rdoc|
|
56
|
+
# version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
57
|
+
#
|
58
|
+
# rdoc.rdoc_dir = 'rdoc'
|
59
|
+
# rdoc.title = "gelf #{version}"
|
60
|
+
# rdoc.rdoc_files.include('README*')
|
61
|
+
# rdoc.rdoc_files.include('lib/**/*.rb')
|
62
|
+
#end
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.4.0
|
1
|
+
1.4.0
|
data/benchmarks/notifier.rb
CHANGED
@@ -1,15 +1,13 @@
|
|
1
1
|
#! /usr/bin/env ruby
|
2
2
|
|
3
|
+
puts "Loading..."
|
4
|
+
|
3
5
|
require 'benchmark'
|
4
|
-
require 'thread'
|
5
6
|
require 'rubygems'
|
6
7
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
7
8
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
8
9
|
require 'gelf'
|
9
10
|
|
10
|
-
Thread.abort_on_exception = true
|
11
|
-
|
12
|
-
puts "Running on #{RUBY_DESCRIPTION}"
|
13
11
|
puts "Generating random data..."
|
14
12
|
srand(1)
|
15
13
|
RANDOM_DATA = ('A'..'z').to_a
|
@@ -18,21 +16,11 @@ k3_message = (1..3*1024).map { RANDOM_DATA[rand(RANDOM_DATA.count)] }.join
|
|
18
16
|
TARGET_HOST = 'localhost'
|
19
17
|
TARGET_PORT = 12201
|
20
18
|
DEFAULT_OPTIONS = { '_host' => 'localhost' }
|
21
|
-
|
22
|
-
THREADS_COUNT = 50
|
19
|
+
TIMES = 5000
|
23
20
|
|
24
21
|
SHORT_HASH = { 'short_message' => 'message' }
|
25
22
|
LONG_HASH = { 'short_message' => 'message', 'long_message' => k3_message }
|
26
23
|
|
27
|
-
def notify(n, hash)
|
28
|
-
threads = []
|
29
|
-
THREADS_COUNT.times do
|
30
|
-
threads << Thread.new do
|
31
|
-
(MESSAGES_COUNT / THREADS_COUNT).times { n.notify!(hash) }
|
32
|
-
end
|
33
|
-
end
|
34
|
-
threads.each { |t| t.join }
|
35
|
-
end
|
36
24
|
|
37
25
|
notifier_lan = GELF::Notifier.new(TARGET_HOST, TARGET_PORT, 'LAN', DEFAULT_OPTIONS)
|
38
26
|
notifier_wan = GELF::Notifier.new(TARGET_HOST, TARGET_PORT, 'WAN', DEFAULT_OPTIONS)
|
@@ -41,11 +29,11 @@ notifier_wan = GELF::Notifier.new(TARGET_HOST, TARGET_PORT, 'WAN', DEFAULT_OPTIO
|
|
41
29
|
notifier_lan.notify!(LONG_HASH)
|
42
30
|
sleep(5)
|
43
31
|
|
44
|
-
puts "Sending #{
|
32
|
+
puts "Sending #{TIMES} notifications...\n"
|
45
33
|
tms = Benchmark.bm(25) do |b|
|
46
|
-
b.report('lan, short data, 1 chunk ') { notify(
|
34
|
+
b.report('lan, short data, 1 chunk ') { TIMES.times { notifier_lan.notify!(SHORT_HASH) } }
|
47
35
|
sleep(5)
|
48
|
-
b.report('lan, long data, 1 chunk ') { notify(
|
36
|
+
b.report('lan, long data, 1 chunk ') { TIMES.times { notifier_lan.notify!(LONG_HASH) } }
|
49
37
|
sleep(5)
|
50
|
-
b.report('wan, long data, 2 chunks') { notify(
|
38
|
+
b.report('wan, long data, 2 chunks') { TIMES.times { notifier_wan.notify!(LONG_HASH) } }
|
51
39
|
end
|
data/gelf.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "gelf"
|
8
|
-
s.version = "1.4.0
|
8
|
+
s.version = "1.4.0"
|
9
9
|
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new("
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Alexey Palazhchenko", "Lennart Koopmann"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2013-01-26"
|
13
13
|
s.description = "Library to send GELF messages to Graylog2 logging server. Supports plain-text, GELF messages and exceptions."
|
14
14
|
s.email = "alexey.palazhchenko@gmail.com"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -24,7 +24,6 @@ Gem::Specification.new do |s|
|
|
24
24
|
"README.rdoc",
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
27
|
-
"benchmarks/incremental.rb",
|
28
27
|
"benchmarks/notifier.rb",
|
29
28
|
"gelf.gemspec",
|
30
29
|
"lib/gelf.rb",
|
@@ -40,7 +39,7 @@ Gem::Specification.new do |s|
|
|
40
39
|
]
|
41
40
|
s.homepage = "http://github.com/Graylog2/gelf-rb"
|
42
41
|
s.require_paths = ["lib"]
|
43
|
-
s.rubygems_version = "1.8.
|
42
|
+
s.rubygems_version = "1.8.24"
|
44
43
|
s.summary = "Library to send GELF messages to Graylog2 logging server."
|
45
44
|
|
46
45
|
if s.respond_to? :specification_version then
|
data/lib/gelf.rb
CHANGED
data/lib/gelf/logger.rb
CHANGED
@@ -1,11 +1,14 @@
|
|
1
1
|
module GELF
|
2
2
|
# Methods for compatibility with Ruby Logger.
|
3
3
|
module LoggerCompatibility
|
4
|
+
|
5
|
+
attr_accessor :formatter
|
6
|
+
|
4
7
|
# Does nothing.
|
5
8
|
def close
|
6
9
|
end
|
7
10
|
|
8
|
-
# Use it like Logger#add... or better not use
|
11
|
+
# Use it like Logger#add... or better not to use at all.
|
9
12
|
def add(level, *args)
|
10
13
|
raise ArgumentError.new('Wrong arguments.') unless (0..2).include?(args.count)
|
11
14
|
|
@@ -20,8 +23,20 @@ module GELF
|
|
20
23
|
[args[0], default_options['facility']]
|
21
24
|
end
|
22
25
|
|
23
|
-
|
26
|
+
if message.is_a?(Hash)
|
27
|
+
# Stringify keys.
|
28
|
+
hash = {}
|
29
|
+
message.each do |k,v|
|
30
|
+
hash[k.to_s] = message[k]
|
31
|
+
end
|
32
|
+
|
33
|
+
hash['facility'] = progname
|
34
|
+
else
|
35
|
+
hash = {'short_message' => message, 'facility' => progname}
|
36
|
+
end
|
37
|
+
|
24
38
|
hash.merge!(self.class.extract_hash_from_exception(message)) if message.is_a?(Exception)
|
39
|
+
|
25
40
|
notify_with_level(level, hash)
|
26
41
|
end
|
27
42
|
|
@@ -50,5 +65,7 @@ module GELF
|
|
50
65
|
# config.colorize_logging = false
|
51
66
|
class Logger < Notifier
|
52
67
|
include LoggerCompatibility
|
68
|
+
@last_chunk_id = 0
|
53
69
|
end
|
70
|
+
|
54
71
|
end
|
data/lib/gelf/notifier.rb
CHANGED
@@ -1,6 +1,11 @@
|
|
1
1
|
module GELF
|
2
2
|
# Graylog2 notifier.
|
3
3
|
class Notifier
|
4
|
+
@last_chunk_id = 0
|
5
|
+
class << self
|
6
|
+
attr_accessor :last_chunk_id
|
7
|
+
end
|
8
|
+
|
4
9
|
attr_accessor :enabled, :collect_file_and_line, :rescue_network_errors
|
5
10
|
attr_reader :max_chunk_size, :level, :default_options, :level_mapping
|
6
11
|
|
@@ -132,16 +137,14 @@ module GELF
|
|
132
137
|
|
133
138
|
def notify_with_level!(message_level, *args)
|
134
139
|
return unless @enabled
|
135
|
-
|
136
|
-
hash['level'] = message_level unless message_level.nil?
|
137
|
-
if hash['level'] >= level
|
138
|
-
@sender.send_datagrams(datagrams_from_hash
|
140
|
+
extract_hash(*args)
|
141
|
+
@hash['level'] = message_level unless message_level.nil?
|
142
|
+
if @hash['level'] >= level
|
143
|
+
@sender.send_datagrams(datagrams_from_hash)
|
139
144
|
end
|
140
145
|
end
|
141
146
|
|
142
147
|
def extract_hash(object = nil, args = {})
|
143
|
-
args = self.class.stringify_keys(args)
|
144
|
-
|
145
148
|
primary_data = if object.respond_to?(:to_hash)
|
146
149
|
object.to_hash
|
147
150
|
elsif object.is_a?(Exception)
|
@@ -152,94 +155,61 @@ module GELF
|
|
152
155
|
{ 'short_message' => object.to_s }
|
153
156
|
end
|
154
157
|
|
155
|
-
hash = self.class.stringify_keys(primary_data)
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
hash
|
158
|
+
@hash = default_options.merge(self.class.stringify_keys(args.merge(primary_data)))
|
159
|
+
convert_hoptoad_keys_to_graylog2
|
160
|
+
set_file_and_line if @collect_file_and_line
|
161
|
+
set_timestamp
|
162
|
+
check_presence_of_mandatory_attributes
|
163
|
+
@hash
|
162
164
|
end
|
163
165
|
|
164
|
-
CALLER_REGEXP = /^(.*):(\d+).*/
|
165
|
-
|
166
166
|
def self.extract_hash_from_exception(exception)
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
# always collect file and line there (ignore @collect_file_and_line)
|
171
|
-
# since we already know them, no need to call `caller`
|
172
|
-
file, line = nil, nil
|
173
|
-
bt = exception.backtrace
|
174
|
-
if bt
|
175
|
-
match = CALLER_REGEXP.match(bt[0])
|
176
|
-
if match
|
177
|
-
file = match[1]
|
178
|
-
line = match[2].to_i
|
179
|
-
end
|
180
|
-
else
|
181
|
-
bt = ["Backtrace is not available."]
|
182
|
-
end
|
183
|
-
|
184
|
-
{ 'short_message' => "#{error_class}: #{error_message}", 'full_message' => "Backtrace:\n" + bt.join("\n"),
|
185
|
-
'error_class' => error_class, 'error_message' => error_message,
|
186
|
-
'file' => file, 'line' => line }
|
167
|
+
bt = exception.backtrace || ["Backtrace is not available."]
|
168
|
+
{ 'short_message' => "#{exception.class}: #{exception.message}", 'full_message' => "Backtrace:\n" + bt.join("\n") }
|
187
169
|
end
|
188
170
|
|
189
|
-
# Converts
|
190
|
-
def
|
191
|
-
if hash['short_message'].to_s.empty?
|
192
|
-
if hash.has_key?('error_class') && hash.has_key?('error_message')
|
193
|
-
hash['short_message'] = hash
|
171
|
+
# Converts Hoptoad-specific keys in +@hash+ to Graylog2-specific.
|
172
|
+
def convert_hoptoad_keys_to_graylog2
|
173
|
+
if @hash['short_message'].to_s.empty?
|
174
|
+
if @hash.has_key?('error_class') && @hash.has_key?('error_message')
|
175
|
+
@hash['short_message'] = @hash.delete('error_class') + ': ' + @hash.delete('error_message')
|
194
176
|
end
|
195
177
|
end
|
196
|
-
hash
|
197
178
|
end
|
198
179
|
|
180
|
+
CALLER_REGEXP = /^(.*):(\d+).*/
|
199
181
|
LIB_GELF_PATTERN = File.join('lib', 'gelf')
|
200
182
|
|
201
|
-
def set_file_and_line
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
match = CALLER_REGEXP.match(frame)
|
211
|
-
if match
|
212
|
-
hash['file'] = match[1]
|
213
|
-
hash['line'] = match[2].to_i
|
214
|
-
else
|
215
|
-
hash['file'] = 'unknown'
|
216
|
-
hash['line'] = -1
|
217
|
-
end
|
218
|
-
end
|
219
|
-
|
220
|
-
hash
|
183
|
+
def set_file_and_line
|
184
|
+
stack = caller
|
185
|
+
begin
|
186
|
+
frame = stack.shift
|
187
|
+
end while frame.include?(LIB_GELF_PATTERN)
|
188
|
+
match = CALLER_REGEXP.match(frame)
|
189
|
+
@hash['file'] = match[1]
|
190
|
+
@hash['line'] = match[2].to_i
|
221
191
|
end
|
222
192
|
|
223
|
-
def set_timestamp
|
224
|
-
hash['timestamp']
|
225
|
-
hash
|
193
|
+
def set_timestamp
|
194
|
+
@hash['timestamp'] = Time.now.utc.to_f if @hash['timestamp'].nil?
|
226
195
|
end
|
227
196
|
|
228
|
-
def check_presence_of_mandatory_attributes
|
197
|
+
def check_presence_of_mandatory_attributes
|
229
198
|
%w(version short_message host).each do |attribute|
|
230
|
-
if hash[attribute].to_s.empty?
|
199
|
+
if @hash[attribute].to_s.empty?
|
231
200
|
raise ArgumentError.new("#{attribute} is missing. Options version, short_message and host must be set.")
|
232
201
|
end
|
233
202
|
end
|
234
203
|
end
|
235
204
|
|
236
|
-
def datagrams_from_hash
|
237
|
-
data = serialize_hash
|
205
|
+
def datagrams_from_hash
|
206
|
+
data = serialize_hash
|
238
207
|
datagrams = []
|
239
208
|
|
240
209
|
# Maximum total size is 8192 byte for UDP datagram. Split to chunks if bigger. (GELF v1.0 supports chunking)
|
241
210
|
if data.count > @max_chunk_size
|
242
|
-
|
211
|
+
id = self.class.last_chunk_id += 1
|
212
|
+
msg_id = Digest::MD5.digest("#{Time.now.to_f}-#{id}")[0, 8]
|
243
213
|
num, count = 0, (data.count.to_f / @max_chunk_size).ceil
|
244
214
|
data.each_slice(@max_chunk_size) do |slice|
|
245
215
|
datagrams << "\x1e\x0f" + msg_id + [num, count, *slice].pack('C*')
|
@@ -252,12 +222,12 @@ module GELF
|
|
252
222
|
datagrams
|
253
223
|
end
|
254
224
|
|
255
|
-
def serialize_hash
|
256
|
-
raise ArgumentError.new("Hash is empty.") if hash.nil? || hash.empty?
|
225
|
+
def serialize_hash
|
226
|
+
raise ArgumentError.new("Hash is empty.") if @hash.nil? || @hash.empty?
|
257
227
|
|
258
|
-
hash['level'] = @level_mapping[hash['level']]
|
228
|
+
@hash['level'] = @level_mapping[@hash['level']]
|
259
229
|
|
260
|
-
Zlib::Deflate.deflate(hash.to_json).bytes
|
230
|
+
Zlib::Deflate.deflate(@hash.to_json).bytes
|
261
231
|
end
|
262
232
|
|
263
233
|
def self.stringify_keys(hash)
|
data/lib/gelf/ruby_sender.rb
CHANGED
@@ -1,32 +1,17 @@
|
|
1
1
|
module GELF
|
2
2
|
# Plain Ruby UDP sender.
|
3
3
|
class RubyUdpSender
|
4
|
-
|
5
|
-
@mutex = ::Mutex.new
|
6
|
-
@socket = UDPSocket.open
|
7
|
-
@socket.setsockopt(Socket::SOL_SOCKET, Socket::SO_SNDBUF, 65507) # 65535 - 20 (ip header) - 8 (udp header)
|
8
|
-
self.addresses = addrs
|
9
|
-
end
|
10
|
-
|
11
|
-
def addresses
|
12
|
-
@mutex.synchronize do
|
13
|
-
@i = 0
|
14
|
-
@addresses
|
15
|
-
end
|
16
|
-
end
|
4
|
+
attr_accessor :addresses
|
17
5
|
|
18
|
-
def addresses
|
19
|
-
@
|
20
|
-
|
21
|
-
|
22
|
-
end
|
6
|
+
def initialize(addresses)
|
7
|
+
@addresses = addresses
|
8
|
+
@i = 0
|
9
|
+
@socket = UDPSocket.open
|
23
10
|
end
|
24
11
|
|
25
12
|
def send_datagrams(datagrams)
|
26
|
-
# not thread-safe, but we don't care if round-robin algo fails sometimes
|
27
13
|
host, port = @addresses[@i]
|
28
14
|
@i = (@i + 1) % @addresses.length
|
29
|
-
|
30
15
|
datagrams.each do |datagram|
|
31
16
|
@socket.send(datagram, 0, host, port)
|
32
17
|
end
|
data/test/test_logger.rb
CHANGED
@@ -97,6 +97,43 @@ class TestLogger < Test::Unit::TestCase
|
|
97
97
|
end
|
98
98
|
@logger.add(GELF::INFO, 'Facility') { RuntimeError.new('Boom!') }
|
99
99
|
end
|
100
|
+
|
101
|
+
|
102
|
+
#####################
|
103
|
+
|
104
|
+
# logger.add(Logger::INFO, { :short_message => "Some message" })
|
105
|
+
should "implement add method with level and message from hash, facility from defaults" do
|
106
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
107
|
+
level == GELF::INFO &&
|
108
|
+
hash['short_message'] == 'Some message' &&
|
109
|
+
hash['facility'] == 'gelf-rb'
|
110
|
+
end
|
111
|
+
@logger.add(GELF::INFO, { :short_message => "Some message" })
|
112
|
+
end
|
113
|
+
|
114
|
+
# logger.add(Logger::INFO, { :short_message => "Some message", :_foo => "bar", "_zomg" => "wat" })
|
115
|
+
should "implement add method with level and message from hash, facility from defaults and some additional fields" do
|
116
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
117
|
+
level == GELF::INFO &&
|
118
|
+
hash['short_message'] == 'Some message' &&
|
119
|
+
hash['facility'] == 'gelf-rb' &&
|
120
|
+
hash['_foo'] == 'bar' &&
|
121
|
+
hash['_zomg'] == 'wat'
|
122
|
+
end
|
123
|
+
@logger.add(GELF::INFO, { :short_message => "Some message", :_foo => "bar", "_zomg" => "wat"})
|
124
|
+
end
|
125
|
+
|
126
|
+
# logger.add(Logger::INFO, "somefac", { :short_message => "Some message", :_foo => "bar", "_zomg" => "wat" })
|
127
|
+
should "implement add method with level and message from hash, facility from parameters and some additional fields" do
|
128
|
+
@logger.expects(:notify_with_level!).with do |level, hash|
|
129
|
+
level == GELF::INFO &&
|
130
|
+
hash['short_message'] == 'Some message' &&
|
131
|
+
hash['facility'] == 'somefac' &&
|
132
|
+
hash['_foo'] == 'bar' &&
|
133
|
+
hash['_zomg'] == 'wat'
|
134
|
+
end
|
135
|
+
@logger.add(GELF::INFO, { :short_message => "Some message", :_foo => "bar", "_zomg" => "wat"}, "somefac")
|
136
|
+
end
|
100
137
|
end
|
101
138
|
|
102
139
|
GELF::Levels.constants.each do |const|
|
@@ -135,5 +172,9 @@ class TestLogger < Test::Unit::TestCase
|
|
135
172
|
end
|
136
173
|
@logger << "Message"
|
137
174
|
end
|
175
|
+
|
176
|
+
should "have formatter attribute" do
|
177
|
+
@logger.formatter
|
178
|
+
end
|
138
179
|
end
|
139
180
|
end
|
data/test/test_notifier.rb
CHANGED
@@ -52,30 +52,20 @@ class TestNotifier < Test::Unit::TestCase
|
|
52
52
|
e.set_backtrace(caller)
|
53
53
|
hash = @notifier.__send__(:extract_hash, e)
|
54
54
|
assert_equal 'RuntimeError: message', hash['short_message']
|
55
|
-
assert_equal 'RuntimeError', hash['error_class']
|
56
|
-
assert_equal 'message', hash['error_message']
|
57
|
-
assert_match /shoulda/, hash['file']
|
58
|
-
assert hash['line'] > 300 # 382 in shoulda 2.11.3
|
59
55
|
assert_match /Backtrace/, hash['full_message']
|
60
56
|
assert_equal GELF::ERROR, hash['level']
|
61
57
|
end
|
62
58
|
|
63
59
|
should "work with exception without backtrace" do
|
64
60
|
e = RuntimeError.new('message')
|
65
|
-
hash
|
66
|
-
assert_equal __FILE__, hash['file']
|
67
|
-
assert_equal line, hash['line']
|
61
|
+
hash = @notifier.__send__(:extract_hash, e)
|
68
62
|
assert_match /Backtrace is not available/, hash['full_message']
|
69
63
|
end
|
70
64
|
|
71
65
|
should "work with exception and hash" do
|
72
66
|
e, h = RuntimeError.new('message'), {'param' => 1, 'level' => GELF::FATAL, 'short_message' => 'will be hidden by exception'}
|
73
|
-
hash
|
67
|
+
hash = @notifier.__send__(:extract_hash, e, h)
|
74
68
|
assert_equal 'RuntimeError: message', hash['short_message']
|
75
|
-
assert_equal 'RuntimeError', hash['error_class']
|
76
|
-
assert_equal 'message', hash['error_message']
|
77
|
-
assert_equal __FILE__, hash['file']
|
78
|
-
assert_equal line, hash['line']
|
79
69
|
assert_equal GELF::FATAL, hash['level']
|
80
70
|
assert_equal 1, hash['param']
|
81
71
|
end
|
@@ -90,10 +80,6 @@ class TestNotifier < Test::Unit::TestCase
|
|
90
80
|
hash = @notifier.__send__(:extract_hash, 'message', 'level' => GELF::WARN)
|
91
81
|
assert_equal 'message', hash['short_message']
|
92
82
|
assert_equal GELF::WARN, hash['level']
|
93
|
-
|
94
|
-
hash = @notifier.__send__(:extract_hash, 'message', :level => GELF::WARN)
|
95
|
-
assert_equal 'message', hash['short_message']
|
96
|
-
assert_equal GELF::WARN, hash['level']
|
97
83
|
end
|
98
84
|
|
99
85
|
should "covert hash keys to strings" do
|
@@ -113,12 +99,10 @@ class TestNotifier < Test::Unit::TestCase
|
|
113
99
|
assert_equal 'message', hash['short_message']
|
114
100
|
end
|
115
101
|
|
116
|
-
should "be compatible with
|
117
|
-
# https://github.com/
|
102
|
+
should "be compatible with HoptoadNotifier" do
|
103
|
+
# https://github.com/thoughtbot/hoptoad_notifier/blob/master/README.rdoc, section Going beyond exceptions
|
118
104
|
hash = @notifier.__send__(:extract_hash, :error_class => 'Class', :error_message => 'Message')
|
119
105
|
assert_equal 'Class: Message', hash['short_message']
|
120
|
-
assert_equal 'Class', hash['error_class']
|
121
|
-
assert_equal 'Message', hash['error_message']
|
122
106
|
end
|
123
107
|
|
124
108
|
should "set file and line" do
|
@@ -145,7 +129,8 @@ class TestNotifier < Test::Unit::TestCase
|
|
145
129
|
context "serialize_hash" do
|
146
130
|
setup do
|
147
131
|
@notifier.level_mapping = :direct
|
148
|
-
@
|
132
|
+
@notifier.instance_variable_set('@hash', { 'level' => GELF::WARN, 'field' => 'value' })
|
133
|
+
@data = @notifier.__send__(:serialize_hash)
|
149
134
|
assert @data.respond_to?(:each) # Enumerable::Enumerator in 1.8, ::Enumerator in 1.9, so...
|
150
135
|
@deserialized_hash = JSON.parse(Zlib::Inflate.inflate(@data.to_a.pack('C*')))
|
151
136
|
assert_instance_of Hash, @deserialized_hash
|
@@ -160,7 +145,8 @@ class TestNotifier < Test::Unit::TestCase
|
|
160
145
|
|
161
146
|
context "datagrams_from_hash" do
|
162
147
|
should "not split short data" do
|
163
|
-
|
148
|
+
@notifier.instance_variable_set('@hash', { 'version' => '1.0', 'short_message' => 'message' })
|
149
|
+
datagrams = @notifier.__send__(:datagrams_from_hash)
|
164
150
|
assert_equal 1, datagrams.count
|
165
151
|
assert_instance_of String, datagrams[0]
|
166
152
|
assert_equal "\x78\x9c", datagrams[0][0..1] # zlib header
|
@@ -170,7 +156,8 @@ class TestNotifier < Test::Unit::TestCase
|
|
170
156
|
srand(1) # for stable tests
|
171
157
|
hash = { 'version' => '1.0', 'short_message' => 'message' }
|
172
158
|
hash.merge!('something' => (0..3000).map { RANDOM_DATA[rand(RANDOM_DATA.count)] }.join) # or it will be compressed too good
|
173
|
-
|
159
|
+
@notifier.instance_variable_set('@hash', hash)
|
160
|
+
datagrams = @notifier.__send__(:datagrams_from_hash)
|
174
161
|
assert_equal 2, datagrams.count
|
175
162
|
datagrams.each_index do |i|
|
176
163
|
datagram = datagrams[i]
|
metadata
CHANGED
@@ -1,77 +1,74 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: gelf
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
|
5
|
-
prerelease:
|
6
|
-
segments:
|
7
|
-
- 1
|
8
|
-
- 4
|
9
|
-
- 0
|
10
|
-
- beta
|
11
|
-
- 1
|
12
|
-
version: 1.4.0.beta1
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.4.0
|
5
|
+
prerelease:
|
13
6
|
platform: ruby
|
14
|
-
authors:
|
7
|
+
authors:
|
15
8
|
- Alexey Palazhchenko
|
16
9
|
- Lennart Koopmann
|
17
10
|
autorequire:
|
18
11
|
bindir: bin
|
19
12
|
cert_chain: []
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
- !ruby/object:Gem::Dependency
|
13
|
+
date: 2013-01-26 00:00:00.000000000 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
24
16
|
name: json
|
25
|
-
|
26
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
27
18
|
none: false
|
28
|
-
requirements:
|
29
|
-
- -
|
30
|
-
- !ruby/object:Gem::Version
|
31
|
-
|
32
|
-
segments:
|
33
|
-
- 0
|
34
|
-
version: "0"
|
19
|
+
requirements:
|
20
|
+
- - ! '>='
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: '0'
|
35
23
|
type: :runtime
|
36
|
-
version_requirements: *id001
|
37
|
-
- !ruby/object:Gem::Dependency
|
38
|
-
name: shoulda
|
39
24
|
prerelease: false
|
40
|
-
|
25
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
26
|
none: false
|
42
|
-
requirements:
|
43
|
-
- -
|
44
|
-
- !ruby/object:Gem::Version
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
27
|
+
requirements:
|
28
|
+
- - ! '>='
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
version: '0'
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: shoulda
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: '0'
|
49
39
|
type: :development
|
50
|
-
version_requirements: *id002
|
51
|
-
- !ruby/object:Gem::Dependency
|
52
|
-
name: mocha
|
53
40
|
prerelease: false
|
54
|
-
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
55
42
|
none: false
|
56
|
-
requirements:
|
57
|
-
- -
|
58
|
-
- !ruby/object:Gem::Version
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: mocha
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
63
55
|
type: :development
|
64
|
-
|
65
|
-
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ! '>='
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
description: Library to send GELF messages to Graylog2 logging server. Supports plain-text,
|
64
|
+
GELF messages and exceptions.
|
66
65
|
email: alexey.palazhchenko@gmail.com
|
67
66
|
executables: []
|
68
|
-
|
69
67
|
extensions: []
|
70
|
-
|
71
|
-
extra_rdoc_files:
|
68
|
+
extra_rdoc_files:
|
72
69
|
- LICENSE
|
73
70
|
- README.rdoc
|
74
|
-
files:
|
71
|
+
files:
|
75
72
|
- .gemtest
|
76
73
|
- .travis.yml
|
77
74
|
- CHANGELOG
|
@@ -79,7 +76,6 @@ files:
|
|
79
76
|
- README.rdoc
|
80
77
|
- Rakefile
|
81
78
|
- VERSION
|
82
|
-
- benchmarks/incremental.rb
|
83
79
|
- benchmarks/notifier.rb
|
84
80
|
- gelf.gemspec
|
85
81
|
- lib/gelf.rb
|
@@ -94,38 +90,26 @@ files:
|
|
94
90
|
- test/test_severity.rb
|
95
91
|
homepage: http://github.com/Graylog2/gelf-rb
|
96
92
|
licenses: []
|
97
|
-
|
98
93
|
post_install_message:
|
99
94
|
rdoc_options: []
|
100
|
-
|
101
|
-
require_paths:
|
95
|
+
require_paths:
|
102
96
|
- lib
|
103
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
104
98
|
none: false
|
105
|
-
requirements:
|
106
|
-
- -
|
107
|
-
- !ruby/object:Gem::Version
|
108
|
-
|
109
|
-
|
110
|
-
- 0
|
111
|
-
version: "0"
|
112
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - ! '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
104
|
none: false
|
114
|
-
requirements:
|
115
|
-
- -
|
116
|
-
- !ruby/object:Gem::Version
|
117
|
-
|
118
|
-
segments:
|
119
|
-
- 1
|
120
|
-
- 3
|
121
|
-
- 1
|
122
|
-
version: 1.3.1
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
version: '0'
|
123
109
|
requirements: []
|
124
|
-
|
125
110
|
rubyforge_project:
|
126
|
-
rubygems_version: 1.8.
|
111
|
+
rubygems_version: 1.8.24
|
127
112
|
signing_key:
|
128
113
|
specification_version: 3
|
129
114
|
summary: Library to send GELF messages to Graylog2 logging server.
|
130
115
|
test_files: []
|
131
|
-
|
data/benchmarks/incremental.rb
DELETED
@@ -1,17 +0,0 @@
|
|
1
|
-
#! /usr/bin/env ruby
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
-
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
6
|
-
require 'gelf'
|
7
|
-
|
8
|
-
TARGET_HOST = 'localhost'
|
9
|
-
TARGET_PORT = 5140
|
10
|
-
RANGE = 35000...36000
|
11
|
-
|
12
|
-
n = GELF::Notifier.new(TARGET_HOST, TARGET_PORT, 'WAN')
|
13
|
-
RANGE.each do |size|
|
14
|
-
n.notify!('a' * size)
|
15
|
-
puts size if (size % 100) == 0
|
16
|
-
sleep 0.01
|
17
|
-
end
|