Skip to content

Instantly share code, notes, and snippets.

@np422
Last active May 17, 2021 20:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save np422/67d9cd3d5e2786a38350772d4636d342 to your computer and use it in GitHub Desktop.
Save np422/67d9cd3d5e2786a38350772d4636d342 to your computer and use it in GitHub Desktop.
#!/usr/bin/env ruby
# frozen_string_literal: true
require 'time'
require 'gelf'
require 'optparse'
def banner
puts 'Usage: gelf_sender -k kmsg -r rate -s msg_size -d dest_ip -p dest_port -b batch_size -t'
puts ''
puts ' kmsg: Number of thousand messages to send, ie kmsg = 2 => send 2000 msgs'
puts ' Default value: 2'
puts ' rate: Target sending rate in msg/s'
puts ' Default value: 200'
puts ' msg_size: Intended average size of full_message in gelf logmesg, in chars, max 1024'
puts ' Default value: 250 chars'
puts ' dest_ip: IP address of graylog server'
puts ' No default value'
puts ' dest_port: Port for gelf UDP listener'
puts ' Default value: 12201'
puts ' batch_size: Number of msg to send before measuring rate'
puts ' Default value: 10'
puts ' -t Use tcp instead of udp to connect'
puts ' -m Send as fast as possible, can not be combined with -r rate'
end
def add_switches!(parser)
options = {}
parser.on('-?', '--help', 'Display usage info') { options[:help] = true }
parser.on('-k KMSG', '--kmsg=KMSG', 'KMSG thousands of messages') { |k| options[:kmsg] = k.to_i }
parser.on('-r RATE', '--rate=RATE', 'Send RATE msg per second') { |r| options[:rate] = r.to_i }
parser.on('-s SIZE', '--size=SIZE', 'Average SIZE per msg') { |s| options[:size] = s.to_i }
parser.on('-d IP', '--ip=IP', 'Graylog server IP') { |i| options[:ip] = i }
parser.on('-p PORT', '--port=PORT', 'Graylog server PORT') { |p| options[:port] = p.to_i }
parser.on('-b BATCH', '--batch=BATCH', 'BATCH number of msgs') { |b| options[:batch] = b.to_i }
parser.on('-m', '--max', 'Send as fast as possible') { options[:max] = true }
parser.on('-t', '--tcp', 'Use tcp connection') { options[:tcp] = true }
options
end
spinner = Enumerator.new do |e|
loop do
e.yield '|'
e.yield '/'
e.yield '-'
e.yield '\\'
end
end
def switch_please
optparser = OptionParser.new
options = add_switches!(optparser)
optparser.parse!
rescue OptionParser::InvalidOption
puts optparser
exit 1
else
[optparser, options]
end
(_parser, options) = switch_please
if options[:help]
banner
exit
end
if options[:ip].nil?
puts 'IP address of graylog server required.'
banner
exit
end
if options[:size].to_i > 1024
puts 'Max average size is 1024 chars'
banner
exit
end
if options[:max] && !options[:rate].nil?
puts 'Only one of -m/--max and -r/--rate can be used'
banner
exit
end
options[:kmsg] ||= 1
options[:rate] ||= 200
options[:batch] ||= 10
options[:size] ||= 250
options[:port] ||= 12_201
options[:max] ||= false
data = DATA.read
notifier = if options[:tcp]
GELF::Notifier.new(options[:ip], options[:port], 'LAN', protocol: GELF::Protocol::TCP)
else
GELF::Notifier.new(options[:ip], options[:port])
end
nsent = 0
size_sent = 0
actual_sleep = 0
progress = 0
# All vars named o_ is an "overall" value
o_start = Process.clock_gettime(Process::CLOCK_MONOTONIC)
while nsent + 1 <= (options[:kmsg].to_i * 1000)
start_t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
options[:batch].times do
cur_size = rand(options[:size].to_i * 2).to_i
size_sent += cur_size
notifier.notify!(short_message: 'GELF stress test',
full_message: data[0..cur_size],
foo: 'bar')
end
end_t = Process.clock_gettime(Process::CLOCK_MONOTONIC)
send_time = end_t - start_t
sleep_time = (options[:batch].to_i - options[:rate].to_i * send_time) / options[:rate].to_i
actual_sleep += sleep sleep_time if sleep_time.positive? && !options[:max]
nsent += options[:batch]
progress = (nsent.to_f / (options[:kmsg] * 1000) * 100).to_i
progress_str = '=' * (progress / 5) unless progress < 5
printf("\rSent: [%<str>-20s] %<percent>d%% %<spinner>s",
str: progress_str, percent: progress, spinner: spinner.next)
end
o_end = Process.clock_gettime(Process::CLOCK_MONOTONIC)
o_time = o_end - o_start
o_rate = nsent / o_time
o_data_rate = size_sent / o_time / 1024
o_msg_size = size_sent / nsent
printf "\nMessages sent = %<n>i\nActual time spent= %<t>.2f\nActual msg rate = %<r>.2f msg/s\nActual data rate = %<dr>.2f kb/s\nActual msg avg size: %<s>i bytes\n",
t: o_time, r: o_rate, dr: o_data_rate, n: nsent, s: o_msg_size
__END__
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment