lumbersexual 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/.travis.yml +1 -1
- data/README.md +27 -7
- data/exe/lumbersexual +17 -83
- data/lib/lumbersexual/plugin/latency.rb +58 -0
- data/lib/lumbersexual/plugin/load_generator.rb +101 -0
- data/lib/lumbersexual/version.rb +1 -1
- data/lumbersexual.gemspec +1 -0
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
MWY2OWU3ZjAyOWE1NTE1NzY0MDhhNWFmYmI0MjA0OTJiZjUwOTVlOA==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
MjhlMjY1M2I5OGJjNDY0MDZmNmNjMzE5YjFlZWEwNzMwZWM3YzQzOQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YWQwNDYyNzk5YjhjZGVmZjljZWJkNTgzY2RhNTFjZTU4N2EyMzQwZTM3MWQw
|
10
|
+
NGRmOTllYjc2MGE1MzllNjIzY2Q0ZTk4M2E4MDc1YmEzMGZlMTM0NTM4NWU1
|
11
|
+
YzZkNDQ3Y2E3NjFiNTFiZjA4Zjc1M2EyODEzZDJjN2Q0ZGMwOWY=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YTk1ZGVjYjdlOTZhNTI5YjI1NTk0NzkwNTRhMDM0OTk5YmU5ZTJmNjk4NTY0
|
14
|
+
YTI0YmI4ZTY1YWI4YTdhYTUzZDdlZGI3MWNiMDM2NzFlZWIxY2Q2MjA0OTVi
|
15
|
+
NGRkOTU4NjAwMjRjMzRkYmM3OTU3YjlhNTE5MjVkOTVmNTMyMjg=
|
data/.travis.yml
CHANGED
@@ -6,7 +6,7 @@ rvm:
|
|
6
6
|
before_install: gem install bundler -v 1.10.6
|
7
7
|
deploy:
|
8
8
|
provider: rubygems
|
9
|
-
ruby:
|
9
|
+
ruby: jruby-9.0.5.0
|
10
10
|
api_key:
|
11
11
|
secure: qpkX3I/j5aXJvD5pBdiddZ63uCxMsQFeTsWkingDkLsxV/DPAiTn9orwmU3XnYfZfr7tU2z8UztHzqPtIfFmTD/v6FLDqLUzYL8SpfZIuu4BgzbFhQ7fpw2me6a1ISOGz5wkMQ34klZMuPZjX2x9KjrkDh8ZSsZziHi2cpkbj0JLW91ezW+W8yrQvOm/dch0uXMLEOlbxbjPjHr76bFQqvkc2Z0YprxK2j525t3+SEnVN51DiVGimPlUrIQ+mtjGOqbZYCMw4rBex+BdQS9T4as6pG/BT1Tk92MFE/gRMJg9QO/DqwolB3mGNBEYR+3skGktz2UBMSGu6XDFxEOqOgK0joe+ehfiL1Oq2hnp482vHODl06HjYIjVlsXGT7aD7C4TcA2yrRW5hg8UaYoVkIbiZz26GrXX8vEZ4C4HgRruQkyt31cLvhdRPJvStkXzgQQXbwmS6P3lkRE3gxwYyeuzblpbprg2Nolmt9GO//1yQ497YUsY18tK9fOZr8vz/xiCuDMQRuJcheA9C27Z9nJZB2iH4xTNwNl53eFYhWMVYdkw16JYWJ17xMg+VnWUwkA/jODU0GlXEvNHNFRaDA9qyedIk5ainAnzGJpExCsWuKFJvJl1Qn2bD3/neruCIBoCaxQOdBrGd/579ALyjkujRmgZTOiaqRh4DaYHGrg=
|
12
12
|
gem: lumbersexual
|
data/README.md
CHANGED
@@ -1,28 +1,40 @@
|
|
1
1
|
# Lumbersexual [![Build Status](https://travis-ci.org/sampointer/lumbersexual.svg?branch=master)](https://travis-ci.org/sampointer/lumbersexual) [![Gem Version](https://badge.fury.io/rb/lumbersexual.svg)](https://badge.fury.io/rb/lumbersexual)
|
2
2
|
|
3
|
-
<img align="right" width="158" height="144" src="
|
4
|
-
|
3
|
+
<img align="right" width="158" height="144" src="etc/assets/lumber-156795_960_720.png" alt="Lumbersexual" />
|
4
|
+
Benchmarking tool for the purposes of testing syslog throughput, ELK stacks, aggregated logging infrastructures and log index performance.
|
5
|
+
|
6
|
+
## Introduction
|
7
|
+
Lumbersexual provides both a means of generating load in order to test log aggregation infrastructures, and the means of measuring the latency of log ingestion by that infrastructure under load.
|
8
|
+
|
9
|
+
In its default form `lumbersexual` will generate random-enough syslog entries to generate various types of load against a log aggregation infrastructure: volume, breadth, syslog configuration, indexing performance. Run across many nodes it can be used to tune and test syslog ELK-like infrastructures.
|
10
|
+
|
11
|
+
It can also be used to measure latency in a manner familiar to those who remember Maakit for MySQL. This can be used both for benchmarking and, by dint of generating telemetry, as a monitoring component.
|
12
|
+
|
13
|
+
Together these two modes enable a logging infrastructure to be placed under stress, the ingestion latency measured and then the ongoing latency sampled and alerted upon.
|
5
14
|
|
6
15
|
## Requirements
|
7
16
|
|
8
|
-
Whilst `lumbersexual` will run correctly under MRI 2.
|
17
|
+
Whilst `lumbersexual` will run correctly under MRI 2.2.0 and later the best performance at scale can be obtained by using jruby-9.0.5.0 or later under Java 7. Furthermore throughput is greatest and most accurate with machines with 2 cores or more. By default twice as many threads as cores will be used.
|
9
18
|
|
10
19
|
A dictionary file is needed from which to generate the randomized messages. Under Debian-derived distributions `apt-get install wamerican; apt-get install dictionaries-common` is not a bad place to start.
|
11
20
|
|
12
21
|
## Usage
|
22
|
+
### Load Generation, The Default Mode
|
23
|
+
In the default mode Lumbersexual will generate random-enough syslog entries. Without passing additional options you may find the defaults to be extremely aggressive. A real-word example might be:
|
13
24
|
|
14
25
|
```bash
|
15
|
-
$ lumbersexual --
|
26
|
+
$ lumbersexual --maxwords 50 --minwords 4 --rate 100 --statsdhost localhost
|
16
27
|
```
|
17
28
|
|
18
|
-
|
19
|
-
|
29
|
+
On a 2 core host `lumbersexual` will attempt to generate 200 syslog entries per second and produce statsd telemetry about the distribution across facilities and priorities of that load. Each log entry will be between 4 and 50 random words.
|
30
|
+
|
31
|
+
By supplying the switch `--statsdhost` with a hostname statsd metric generation is enabled. Lumbersexual will assume it can write to a statsd-like daemon on UDP 8125 and will supply 2 types of telemetry.
|
20
32
|
|
21
33
|
* During a run each thread will increment a counter at the path
|
22
34
|
```
|
23
35
|
lumbersexual.thread.<UUID>.<facility>.<priority>.messages_sent
|
24
36
|
```
|
25
|
-
(where UUID is a randomized string for each thread) each time a message is successfully sent. The facility and priority are reported in their numeric form to save the overhead of a lookup for each write.
|
37
|
+
(where `<UUID>` is a randomized string for each thread) each time a message is successfully sent. The facility and priority are reported in their numeric form to save the overhead of a lookup for each write.
|
26
38
|
* At the end of a run the following metric paths will be produced:
|
27
39
|
```
|
28
40
|
lumbersexual.run.messages_total # gauge
|
@@ -32,6 +44,14 @@ lumbersexual.run.rate # gauge
|
|
32
44
|
|
33
45
|
It is up to you to use the aggregation functions of your telemetry system to combine these into a form you find acceptable.
|
34
46
|
|
47
|
+
### Ingestion Latency
|
48
|
+
Ingestion latency mode generates a syslog message with a unique identifier and then repeatedly queries the supplied ElasticSearch endpoint until that message is returned. With the addition of the `--statsdhost` switch telemetry about this timing is generated. This is both useful for understanding the performance of a logging infrastructure under load and as a component in a telemetery-based monitoring system.
|
49
|
+
```bash
|
50
|
+
$ lumbersexual --latency --uri https://my.elasticsearch.cluster:9200 --statsdhost localhost
|
51
|
+
```
|
52
|
+
|
53
|
+
The `--all` switch can be used to choose between searching today's index only (be careful around midnight!), or across all indices. The latter is useful if you've a rolling online retention period and want to observe the effect on search latency by changes to that.
|
54
|
+
|
35
55
|
## Development
|
36
56
|
|
37
57
|
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec lumbersexual` to use the gem in this directory, ignoring other installed copies of this gem.
|
data/exe/lumbersexual
CHANGED
@@ -2,17 +2,15 @@
|
|
2
2
|
|
3
3
|
require "lumbersexual"
|
4
4
|
require "slop"
|
5
|
-
require "syslog"
|
6
|
-
require "thread"
|
7
|
-
require "timeout"
|
8
5
|
require "etc"
|
9
|
-
require "
|
10
|
-
require "securerandom"
|
6
|
+
require "uri"
|
11
7
|
|
12
8
|
options = Slop.parse do |o|
|
9
|
+
o.bool '-a', '--all', 'search all indices rather than today\'s in latency mode', default: nil
|
13
10
|
o.string '-D', '--dictionaryfile', 'path to dictionary file (default: /etc/dictionaries-common/words)', default: '/etc/dictionaries-common/words'
|
14
11
|
o.array '-f', '--facilities', 'additional comma-seperated facilities', default: []
|
15
12
|
o.bool '-h', '--help', 'print this message'
|
13
|
+
o.bool '-l', '--latency', 'run in latency rather than generation mode (default: no)', default: nil
|
16
14
|
o.integer '-M', '--maxwords', 'maximum number of words per message (default: 20)', default: 20
|
17
15
|
o.integer '-m', '--minwords', 'minimum number of words per message (default: 3)', default: 3
|
18
16
|
o.array '-p', '--priorities', 'additional comma-seperated priorities', default: []
|
@@ -20,6 +18,7 @@ options = Slop.parse do |o|
|
|
20
18
|
o.string '-s', '--statsdhost', 'send statsd telemetry to the named host (default: off)', default: nil
|
21
19
|
o.integer '-T', '--threads', 'number of threads (defaults to number of cores * 2)', default: Etc.nprocessors * 2
|
22
20
|
o.integer '-t', '--timeout', 'length of execution. 0 for forever (default: 0)', default: 0
|
21
|
+
o.string '-u', '--uri', 'elasticsearch uri when run in latency mode (default: http://localhost:9200/)', default: URI::parse("http://localhost:9200/")
|
23
22
|
end
|
24
23
|
|
25
24
|
if options.help?
|
@@ -27,91 +26,26 @@ if options.help?
|
|
27
26
|
exit
|
28
27
|
end
|
29
28
|
|
29
|
+
options[:uri] = URI.parse(options[:uri].to_s)
|
30
|
+
|
30
31
|
trap('INT') {
|
31
32
|
raise Interrupt
|
32
33
|
}
|
33
34
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
priorities = [ Syslog::LOG_AUTHPRIV, Syslog::LOG_CRON, Syslog::LOG_DAEMON, Syslog::LOG_FTP, Syslog::LOG_LPR, Syslog::LOG_MAIL, Syslog::LOG_NEWS, Syslog::LOG_SYSLOG, Syslog::LOG_USER, Syslog::LOG_UUCP]
|
39
|
-
0..7.times { |n| priorities << Object.const_get('Syslog').const_get("LOG_LOCAL#{n}")}
|
40
|
-
options[:priorities].each { |p| priorities << Object.const_get('Syslog').const_get("LOG_#{p.upcase}") }
|
41
|
-
|
42
|
-
words = []
|
43
|
-
raise "Unable to find dictionary file at #{options[:dictionaryfile]}" unless File.exist?(options[:dictionaryfile])
|
44
|
-
File.open(options[:dictionaryfile]).each_line { |l| words << l.chomp }
|
45
|
-
|
46
|
-
case options[:rate]
|
47
|
-
when 0
|
48
|
-
pause = 0.0
|
35
|
+
case options[:latency]
|
36
|
+
when true
|
37
|
+
require 'lumbersexual/plugin/latency'
|
38
|
+
plugin = Lumbersexual::Plugin::Latency.new(options)
|
49
39
|
else
|
50
|
-
|
40
|
+
require 'lumbersexual/plugin/load_generator'
|
41
|
+
plugin = Lumbersexual::Plugin::LoadGenerator.new(options)
|
51
42
|
end
|
52
43
|
|
53
|
-
puts "Runtime: #{RUBY_VERSION} #{RUBY_PLATFORM}"
|
54
|
-
puts "Loaded #{words.size} words"
|
55
|
-
puts "Timeout: #{options[:timeout]}"
|
56
|
-
puts "Threads: #{options[:threads]}"
|
57
|
-
puts "Rate per thread: #{options[:rate]}/s"
|
58
|
-
puts "Total rate: #{options[:rate] * options[:threads]}/s"
|
59
|
-
puts "Minimum words per message: #{options[:minwords]}"
|
60
|
-
puts "Maximum words per message: #{options[:maxwords]}"
|
61
|
-
puts "Statsd host: #{options[:statsdhost]}" if options[:statsdhost]
|
62
|
-
puts "Running ..."
|
63
|
-
|
64
|
-
# Run until we're done
|
65
|
-
global_count = 0
|
66
|
-
threads = []
|
67
|
-
mutex = Mutex.new
|
68
|
-
statsd_global = Statsd.new if options[:statsdhost]
|
69
|
-
start_time = Time.now
|
70
|
-
|
71
44
|
begin
|
72
|
-
|
73
|
-
threads << Thread.new {
|
74
|
-
# Configure telemetry
|
75
|
-
statsd = Statsd.new(options[:statsdhost]).tap { |s| s.namespace = "lumbersexual.thread.#{SecureRandom.uuid}" } if options[:statsdhost]
|
76
|
-
|
77
|
-
while true do
|
78
|
-
# Connect to syslog with some sane options and log a message
|
79
|
-
message = String.new
|
80
|
-
number_of_words = rand(options[:minwords]..options[:maxwords])
|
81
|
-
words.sample(number_of_words).each { |w| message << "#{w} " }
|
82
|
-
ident = "lumbersexual-#{words.sample}"
|
83
|
-
facility = facilities.sample
|
84
|
-
priority = priorities.sample
|
85
|
-
|
86
|
-
sleep pause
|
87
|
-
mutex.synchronize {
|
88
|
-
syslog = Syslog.open(ident, Syslog::LOG_CONS | Syslog::LOG_NDELAY | Syslog::LOG_PID, priority)
|
89
|
-
syslog.log(facility, message)
|
90
|
-
global_count += 1
|
91
|
-
statsd.increment [ facility, priority, 'messages_sent' ].join('.') if options[:statsdhost]
|
92
|
-
syslog.close
|
93
|
-
}
|
94
|
-
|
95
|
-
end
|
96
|
-
}
|
97
|
-
|
98
|
-
end
|
99
|
-
|
100
|
-
Timeout::timeout(options[:timeout]) {
|
101
|
-
threads.each {|t| t.join}
|
102
|
-
}
|
103
|
-
|
45
|
+
plugin.perform
|
104
46
|
rescue Timeout::Error, Interrupt
|
105
|
-
|
106
|
-
elapsed = end_time - start_time
|
107
|
-
rate = global_count / elapsed
|
108
|
-
statsd_global = Statsd.new(options[:statsdhost]).tap { |s| s.namespace = "lumbersexual.run" } if options[:statsdhost]
|
109
|
-
puts "Sent: #{global_count}"
|
110
|
-
statsd_global.gauge 'messages_total', global_count if options[:statsdhost]
|
111
|
-
puts "Elapsed time: #{elapsed}"
|
112
|
-
statsd_global.timing 'elapsed', elapsed if options[:statsdhost]
|
113
|
-
puts "Messages per second: #{rate}"
|
114
|
-
statsd_global.gauge 'rate', rate if options[:statsdhost]
|
115
|
-
puts "Complete"
|
116
|
-
exit 0
|
47
|
+
plugin.report
|
117
48
|
end
|
49
|
+
|
50
|
+
puts "Complete"
|
51
|
+
exit 0
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "statsd-ruby"
|
4
|
+
require "securerandom"
|
5
|
+
require "uri"
|
6
|
+
require "syslog"
|
7
|
+
require "timeout"
|
8
|
+
require "elasticsearch"
|
9
|
+
|
10
|
+
module Lumbersexual
|
11
|
+
module Plugin
|
12
|
+
class Latency
|
13
|
+
def initialize(options, *args)
|
14
|
+
@options = options
|
15
|
+
@found = false
|
16
|
+
end
|
17
|
+
|
18
|
+
def perform
|
19
|
+
elastic = Elasticsearch::Client.new url: @options[:uri], log: true
|
20
|
+
|
21
|
+
if @options[:all]
|
22
|
+
index_name = '_all'
|
23
|
+
else
|
24
|
+
index_name = Time.now.strftime('logstash-%Y.%m.%d')
|
25
|
+
end
|
26
|
+
|
27
|
+
unique = "PING: #{SecureRandom.uuid}"
|
28
|
+
@start_time = Time.now
|
29
|
+
Timeout::timeout(@options[:timeout]) {
|
30
|
+
syslog = Syslog.open('lumbersexual-ping', Syslog::LOG_CONS | Syslog::LOG_NDELAY | Syslog::LOG_PID, Syslog::LOG_INFO)
|
31
|
+
syslog.log(Syslog::LOG_WARNING, unique)
|
32
|
+
syslog.close
|
33
|
+
|
34
|
+
until @found do
|
35
|
+
result = elastic.search index: index_name, q: unique
|
36
|
+
@found = true if result['hits']['total'] == 1
|
37
|
+
end
|
38
|
+
}
|
39
|
+
|
40
|
+
@end_time = Time.now
|
41
|
+
raise Interrupt
|
42
|
+
end
|
43
|
+
|
44
|
+
def report
|
45
|
+
statsd = Statsd.new(@options[:statsdhost]).tap { |s| s.namespace = "lumbersexual.latency" } if @options[:statsdhost]
|
46
|
+
|
47
|
+
if @found
|
48
|
+
puts "Latency: #{@end_time - @start_time}"
|
49
|
+
statsd.gauge 'runs.successful', 1 if @options[:statsdhost]
|
50
|
+
statsd.gauge 'rtt', @end_time - @start_time if @options[:statsdhost] if @options[:statsdhost]
|
51
|
+
else
|
52
|
+
statsd.gauge 'runs.failed', 1 if @options[:statsdhost]
|
53
|
+
puts "Latency: unknown, message not found"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "syslog"
|
4
|
+
require "thread"
|
5
|
+
require "timeout"
|
6
|
+
require "statsd-ruby"
|
7
|
+
require "securerandom"
|
8
|
+
require "uri"
|
9
|
+
|
10
|
+
module Lumbersexual
|
11
|
+
module Plugin
|
12
|
+
class LoadGenerator
|
13
|
+
def initialize(options, *args)
|
14
|
+
@options = options
|
15
|
+
end
|
16
|
+
|
17
|
+
def perform
|
18
|
+
# Get our word corpus and define the priorities and facilities we can use
|
19
|
+
facilities = [ Syslog::LOG_ALERT, Syslog::LOG_CRIT, Syslog::LOG_ERR, Syslog::LOG_WARNING, Syslog::LOG_NOTICE, Syslog::LOG_INFO ]
|
20
|
+
@options[:facilities].each { |f| facilities << Object.const_get('Syslog').const_get("LOG_#{f.upcase}") }
|
21
|
+
|
22
|
+
priorities = [ Syslog::LOG_AUTHPRIV, Syslog::LOG_CRON, Syslog::LOG_DAEMON, Syslog::LOG_FTP, Syslog::LOG_LPR, Syslog::LOG_MAIL, Syslog::LOG_NEWS, Syslog::LOG_SYSLOG, Syslog::LOG_USER, Syslog::LOG_UUCP]
|
23
|
+
0..7.times { |n| priorities << Object.const_get('Syslog').const_get("LOG_LOCAL#{n}")}
|
24
|
+
@options[:priorities].each { |p| priorities << Object.const_get('Syslog').const_get("LOG_#{p.upcase}") }
|
25
|
+
|
26
|
+
words = []
|
27
|
+
raise "Unable to find dictionary file at #{@options[:dictionaryfile]}" unless File.exist?(@options[:dictionaryfile])
|
28
|
+
File.open(@options[:dictionaryfile]).each_line { |l| words << l.chomp }
|
29
|
+
|
30
|
+
case @options[:rate]
|
31
|
+
when 0
|
32
|
+
pause = 0.0
|
33
|
+
else
|
34
|
+
pause = 1.0 / @options[:rate]
|
35
|
+
end
|
36
|
+
|
37
|
+
puts "Runtime: #{RUBY_VERSION} #{RUBY_PLATFORM}"
|
38
|
+
puts "Loaded #{words.size} words"
|
39
|
+
puts "Timeout: #{@options[:timeout]}"
|
40
|
+
puts "Threads: #{@options[:threads]}"
|
41
|
+
puts "Rate per thread: #{@options[:rate]}/s"
|
42
|
+
puts "Total rate: #{@options[:rate] * @options[:threads]}/s"
|
43
|
+
puts "Minimum words per message: #{@options[:minwords]}"
|
44
|
+
puts "Maximum words per message: #{@options[:maxwords]}"
|
45
|
+
puts "Statsd host: #{@options[:statsdhost]}" if @options[:statsdhost]
|
46
|
+
puts "Running ..."
|
47
|
+
|
48
|
+
# Run until we're done
|
49
|
+
@global_count = 0
|
50
|
+
threads = []
|
51
|
+
mutex = Mutex.new
|
52
|
+
@start_time = Time.now
|
53
|
+
|
54
|
+
@options[:threads].times do
|
55
|
+
threads << Thread.new {
|
56
|
+
# Configure telemetry
|
57
|
+
statsd = Statsd.new(@options[:statsdhost]).tap { |s| s.namespace = "lumbersexual.thread.#{SecureRandom.uuid}" } if @options[:statsdhost]
|
58
|
+
|
59
|
+
while true do
|
60
|
+
# Connect to syslog with some sane @options and log a message
|
61
|
+
message = String.new
|
62
|
+
number_of_words = rand(@options[:minwords]..@options[:maxwords])
|
63
|
+
words.sample(number_of_words).each { |w| message << "#{w} " }
|
64
|
+
ident = "lumbersexual-#{words.sample}"
|
65
|
+
facility = facilities.sample
|
66
|
+
priority = priorities.sample
|
67
|
+
|
68
|
+
sleep pause
|
69
|
+
mutex.synchronize {
|
70
|
+
syslog = Syslog.open(ident, Syslog::LOG_CONS | Syslog::LOG_NDELAY | Syslog::LOG_PID, priority)
|
71
|
+
syslog.log(facility, message)
|
72
|
+
@global_count += 1
|
73
|
+
statsd.increment [ facility, priority, 'messages_sent' ].join('.') if @options[:statsdhost]
|
74
|
+
syslog.close
|
75
|
+
}
|
76
|
+
|
77
|
+
end
|
78
|
+
}
|
79
|
+
|
80
|
+
end
|
81
|
+
|
82
|
+
Timeout::timeout(@options[:timeout]) {
|
83
|
+
threads.each {|t| t.join}
|
84
|
+
}
|
85
|
+
end
|
86
|
+
|
87
|
+
def report
|
88
|
+
end_time = Time.now
|
89
|
+
elapsed = end_time - @start_time
|
90
|
+
rate = @global_count / elapsed
|
91
|
+
statsd_global = Statsd.new(@options[:statsdhost]).tap { |s| s.namespace = "lumbersexual.run" } if @options[:statsdhost]
|
92
|
+
puts "Sent: #{@global_count}"
|
93
|
+
statsd_global.gauge 'messages_total', @global_count if @options[:statsdhost]
|
94
|
+
puts "Elapsed time: #{elapsed}"
|
95
|
+
statsd_global.timing 'elapsed', elapsed if @options[:statsdhost]
|
96
|
+
puts "Messages per second: #{rate}"
|
97
|
+
statsd_global.gauge 'rate', rate if @options[:statsdhost]
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
101
|
+
end
|
data/lib/lumbersexual/version.rb
CHANGED
data/lumbersexual.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: lumbersexual
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Pointer
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-04-
|
11
|
+
date: 2016-04-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - ~>
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: 1.3.0
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: elasticsearch
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ~>
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: 1.0.17
|
90
|
+
type: :runtime
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ~>
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: 1.0.17
|
83
97
|
description: This gem generates random-enough syslog entries for the purposes of testing
|
84
98
|
syslog throughput, ELK stacks, aggregated logging infrastructures and log index
|
85
99
|
performance.
|
@@ -103,6 +117,8 @@ files:
|
|
103
117
|
- etc/assets/lumber-156795_960_720.png
|
104
118
|
- exe/lumbersexual
|
105
119
|
- lib/lumbersexual.rb
|
120
|
+
- lib/lumbersexual/plugin/latency.rb
|
121
|
+
- lib/lumbersexual/plugin/load_generator.rb
|
106
122
|
- lib/lumbersexual/version.rb
|
107
123
|
- lumbersexual.gemspec
|
108
124
|
homepage: https://github.com/sampointer/lumbersexual
|