Last active
May 17, 2021 20:39
-
-
Save np422/67d9cd3d5e2786a38350772d4636d342 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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