lstash 0.0.9 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,7 @@
1
1
  ---
2
- !binary "U0hBMQ==":
3
- metadata.gz: !binary |-
4
- NTgxYmI5NWQ2ZmE3OGY1NDE0ZGNjN2M1ZGQ2ZWYxNGI5ODY0MGY1NQ==
5
- data.tar.gz: !binary |-
6
- ZTgzZmQ0YTU3MTAwZDA1MWI1MjNmMjM0M2M5NWY1Mjk5NWRmMTM4OA==
2
+ SHA256:
3
+ metadata.gz: 0f41d0f4233ebb92ad410bbc04a55f8b39d7205e576283677ca2de977c24aea5
4
+ data.tar.gz: f038956a733448fa7902e9e9c8aaed5a893881ec3154fa39a936c467a58e8e00
7
5
  SHA512:
8
- metadata.gz: !binary |-
9
- YThlNDM0OTNjZTNhYWI3ODc4MDc5ZjUyOGJhMTBmZTc4YjI3Nzc2YTZiMjFl
10
- ZDk0YTQ3NGNkZDNmMThhN2Y2ODVmOWY5NTliYzQ3MTZmNzc2YzEzZTNmZjU4
11
- YjAzMTMxNzEwZDgzNDdjMTM2ZTRlYjZjNjZmM2VlMzJkMTE0NDY=
12
- data.tar.gz: !binary |-
13
- N2Y5NWI5ZDdiNGNjOTFhMTJkMjJjMzVmZmExZTQ1NjFhZjMzNGU3MDdjMDFi
14
- ZDE4Y2U5MGUyYzY3NTI5N2MyMDE5MDY2NjVhYWVhZTY2Mzk5YmFmNmVkM2Rm
15
- ZjI2ZmYwOTE5NWMxNmI5YTlmYTdjMjRkY2QxZDRlOWNmMjAzNDU=
6
+ metadata.gz: d0a803e99283cf78ccceb1f24ab266cb2ac6b650574c9272f2a13a760a9ea021a3c7be54de3e6c68c5ffa9b9ec22a1afc5aa262502c2a45f98b8aaf1eced27a2
7
+ data.tar.gz: 68209058f27b409c9d2804431cbf7e7426445e084854a26c49640aaf7b5a466f7019804458338bf73fb14ccebf1c7302bc4014fa7abe48c9501900fa2ab475d7
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ *.log
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- ruby-1.9.3
1
+ 2.4.6
data/CHANGELOG.md CHANGED
@@ -1,3 +1,34 @@
1
+ ## Release 0.2.0
2
+ Merge branch 'feature/fix/hashie-warnings' into develop
3
+ - [fix] pin faraday to a compatible version
4
+ - [enh] upgrade to ruby 2.4(.6)
5
+ - [fix] suppress Hashie warnings; it would generate a warning for each log line (on stdout) leading to very large output
6
+
7
+ ### 0.1.4 / 2015-05-29
8
+
9
+ Enhancements
10
+
11
+ * Change default time steps from 1 hour to 120 seconds to aid in grepping from datasets with many events per minute.
12
+
13
+ ### 0.1.3 / 2015-05-28
14
+
15
+ Enhancements
16
+
17
+ * Remove troublesome development dependencies (autotest).
18
+
19
+ ### 0.1.2 / 2015-01-02
20
+
21
+ Enhancements
22
+
23
+ * Double Elasticsearch::Client request timeout to 120 seconds to prevent Timeout::Error (Faraday::TimeoutError).
24
+
25
+ ### 0.1.1 / 2014-10-13
26
+
27
+ Enhancements
28
+
29
+ * Refactor to iterate over hour periods instead of full indices. This improves the performance a lot.
30
+ * Increase timeout to prevent Faraday::TimeoutError exceptions.
31
+
1
32
  ### 0.0.9 / 2014-09-22
2
33
 
3
34
  Enhancements
data/README.md CHANGED
@@ -24,7 +24,7 @@ Or install it yourself as:
24
24
  lstash count QUERY
25
25
 
26
26
  Description:
27
- Count log messages matching the QUERY from Logstash and output this count to stdout. QUERY can use Apache Lucene query
27
+ Count log messages matching the QUERY from Logstash and output this count to stdout. QUERY can use Apache Lucene query
28
28
  parser syntax.
29
29
 
30
30
  Example to count the number of HAProxy log messages in yesterdays month.
@@ -82,38 +82,38 @@ Assuming today is Sep 1 2014. Count all haproxy log messages in the previous mon
82
82
 
83
83
  lstash count program:haproxy --anchor yesterday --from firstday --to today -d
84
84
  time range: [2014-08-01 00:00:00 +0200..2014-09-01 00:00:00 +0200]
85
- logstash-2014.07.31: 1
86
- logstash-2014.08.01: 13
87
- logstash-2014.08.02: 14
88
- logstash-2014.08.03: 1654
89
- logstash-2014.08.04: 6
90
- logstash-2014.08.05: 20
91
- logstash-2014.08.06: 219
92
- logstash-2014.08.07: 32
93
- logstash-2014.08.08: 14
94
- logstash-2014.08.09: 28
95
- logstash-2014.08.10: 799
96
- logstash-2014.08.11: 18
97
- logstash-2014.08.12: 8
98
- logstash-2014.08.13: 23
99
- logstash-2014.08.14: 25
100
- logstash-2014.08.15: 69
101
- logstash-2014.08.16: 19
102
- logstash-2014.08.17: 1160
103
- logstash-2014.08.18: 284
104
- logstash-2014.08.19: 61
105
- logstash-2014.08.20: 26
106
- logstash-2014.08.21: 16
107
- logstash-2014.08.22: 145
108
- logstash-2014.08.23: 72
109
- logstash-2014.08.24: 792
110
- logstash-2014.08.25: 31
111
- logstash-2014.08.26: 33
112
- logstash-2014.08.27: 51
113
- logstash-2014.08.28: 8
114
- logstash-2014.08.29: 23
115
- logstash-2014.08.30: 25
116
- logstash-2014.08.31: 69
85
+ logstash-2014.07.31: 1
86
+ logstash-2014.08.01: 13
87
+ logstash-2014.08.02: 14
88
+ logstash-2014.08.03: 1654
89
+ logstash-2014.08.04: 6
90
+ logstash-2014.08.05: 20
91
+ logstash-2014.08.06: 219
92
+ logstash-2014.08.07: 32
93
+ logstash-2014.08.08: 14
94
+ logstash-2014.08.09: 28
95
+ logstash-2014.08.10: 799
96
+ logstash-2014.08.11: 18
97
+ logstash-2014.08.12: 8
98
+ logstash-2014.08.13: 23
99
+ logstash-2014.08.14: 25
100
+ logstash-2014.08.15: 69
101
+ logstash-2014.08.16: 19
102
+ logstash-2014.08.17: 1160
103
+ logstash-2014.08.18: 284
104
+ logstash-2014.08.19: 61
105
+ logstash-2014.08.20: 26
106
+ logstash-2014.08.21: 16
107
+ logstash-2014.08.22: 145
108
+ logstash-2014.08.23: 72
109
+ logstash-2014.08.24: 792
110
+ logstash-2014.08.25: 31
111
+ logstash-2014.08.26: 33
112
+ logstash-2014.08.27: 51
113
+ logstash-2014.08.28: 8
114
+ logstash-2014.08.29: 23
115
+ logstash-2014.08.30: 25
116
+ logstash-2014.08.31: 69
117
117
  5633
118
118
 
119
119
  ## Using lstash as a gem in your project
@@ -145,6 +145,28 @@ Usage:
145
145
  puts message
146
146
  end
147
147
 
148
+ ## Publishing the gem to RubyGems.org
149
+
150
+ 1. Build the gem
151
+
152
+ ```
153
+ $ gem build lstash.gem
154
+ Successfully built RubyGem
155
+ Name: lstash
156
+ Version: 0.2.0
157
+ File: lstash-0.2.0.gem
158
+ ```
159
+
160
+ 2. Pushing your gem to RubyGems.org
161
+
162
+ ```
163
+ gem push lstash-0.2.0.gem
164
+ Pushing gem to RubyGems.org...
165
+ Successfully registered gem: lstash (0.2.0)
166
+ ```
167
+
168
+ See [RubyGems.org documention](https://guides.rubygems.org/) for more info.
169
+
148
170
  ## Contributing
149
171
 
150
172
  1. Fork it
data/bin/lstash CHANGED
@@ -2,4 +2,6 @@
2
2
 
3
3
  require 'lstash/cli'
4
4
 
5
+ # Suppress Hashie warnings
6
+ Hashie.logger = Logger.new(nil)
5
7
  Lstash::CLI.start(ARGV)
data/lib/lstash/cli.rb CHANGED
@@ -9,6 +9,8 @@ require 'lstash/client'
9
9
 
10
10
  module Lstash
11
11
 
12
+ TRANSPORT_REQUEST_TIMEOUT = 120.freeze # 2 minute request timeout
13
+
12
14
  class CLI < Thor
13
15
 
14
16
  class_option :from, :banner => 'start of time range', :aliases => '-f', :desc => "date/time, 'now', 'today', 'yesterday', or 'firstday'"
@@ -45,7 +47,7 @@ module Lstash
45
47
  desc "count QUERY", "count number of log messages matching the QUERY"
46
48
  def count(query_string)
47
49
  run_command(query_string) do |es_client, query|
48
- count = Lstash::Client.new(es_client, options).count(query)
50
+ count = Lstash::Client.new(es_client, options).count(query)
49
51
  puts count
50
52
  end
51
53
  end
@@ -55,14 +57,15 @@ module Lstash
55
57
  def run_command(query_string)
56
58
  es_client = ::Elasticsearch::Client.new(
57
59
  url: options[:es_url] || ENV['ES_URL'] || 'localhost',
58
- log: !!ENV['DEBUG']
60
+ log: !!ENV['DEBUG'],
61
+ transport_options: { request: { timeout: TRANSPORT_REQUEST_TIMEOUT } }
59
62
  )
60
63
  query = Lstash::Query.new(query_string, options)
61
64
 
62
65
  yield es_client, query
63
66
 
64
67
  rescue Exception => e
65
- raise Thor::Error.new(e.message)
68
+ options[:debug] ? raise(e) : raise(Thor::Error.new(e.message))
66
69
  end
67
70
 
68
71
  protected
data/lib/lstash/client.rb CHANGED
@@ -13,7 +13,9 @@ module Lstash
13
13
 
14
14
  class ConnectionError < StandardError; end
15
15
 
16
- PER_PAGE = 5000 # best time, lowest resource usage
16
+ PER_PAGE = 5000.freeze # best time, lowest resource usage
17
+ DEFAULT_COUNT_STEP = 3600.freeze # 1 hour
18
+ DEFAULT_GREP_STEP = 120.freeze # 2 minutes
17
19
 
18
20
  def initialize(es_client, options = {})
19
21
  raise ConnectionError, "No elasticsearch client specified" if es_client.nil?
@@ -22,25 +24,30 @@ module Lstash
22
24
  @logger = options[:logger] || (options[:debug] ? debug_logger : NullLogger.new)
23
25
  end
24
26
 
25
- def count(query)
26
- @logger.debug "time range: [%s..%s]" % [query.time_range.from, query.time_range.to]
27
+ def count(query, step = DEFAULT_COUNT_STEP)
28
+ @logger.debug "count from=#{query.from} to=#{query.to}"
27
29
 
28
30
  count = 0
29
- query.indices.each do |index|
30
- count += count_messages(index, query)
31
+ query.each_period(step) do |index, hour_query|
32
+ count += count_messages(index, hour_query)
31
33
  end
32
-
34
+ @logger.debug "total count=#{count}"
33
35
  count
34
36
  end
35
37
 
36
- def grep(query)
37
- @logger.debug "time range: [%s..%s]" % [query.time_range.from, query.time_range.to]
38
+ def grep(query, step = DEFAULT_GREP_STEP)
39
+ @logger.debug "grep from=#{query.from} to=#{query.to}"
38
40
 
39
- query.indices.each do |index|
40
- grep_messages(index, query) do |message|
41
+ count = 0
42
+ query.each_period(step) do |index, hour_query|
43
+ grep_messages(index, hour_query) do |message|
44
+ count += 1
41
45
  yield message if block_given?
42
46
  end
43
47
  end
48
+
49
+ @logger.debug "total count=#{count}"
50
+ count
44
51
  end
45
52
 
46
53
  private
@@ -48,9 +55,9 @@ module Lstash
48
55
  def count_messages(index, query)
49
56
  result = Hashie::Mash.new @es_client.send(:count,
50
57
  index: index,
51
- body: query.body[:query]
58
+ body: query.filter
52
59
  )
53
- @logger.debug "count #{index}: #{result['count']} "
60
+ @logger.debug "count index=#{index} from=#{query.from} to=#{query.to} count=#{result['count']}"
54
61
  result['count']
55
62
  end
56
63
 
@@ -61,9 +68,9 @@ module Lstash
61
68
  method = :search
62
69
  while (messages.nil? || messages.count > 0) do
63
70
  result = Hashie::Mash.new @es_client.send(method, {
64
- index: index,
65
- scroll: '10m',
66
- body: query.body.merge(from: offset, size: PER_PAGE),
71
+ index: index,
72
+ scroll: '5m',
73
+ body: query.search(offset, PER_PAGE),
67
74
  }.merge(scroll_params))
68
75
 
69
76
  messages = result.hits.hits
@@ -72,19 +79,20 @@ module Lstash
72
79
  scroll_params = {scroll_id: result._scroll_id}
73
80
 
74
81
  messages.each do |h|
82
+ next if h.fields.nil?
75
83
  yield h.fields.message if block_given?
76
84
  end
77
85
 
78
86
  method = :scroll
79
87
  end
80
- @logger.debug "grep #{index}: #{offset}"
88
+ @logger.debug "grep index=#{index} from=#{query.from} to=#{query.to} count=#{offset}"
81
89
  Hashie::Mash.new @es_client.clear_scroll(scroll_params)
82
90
  end
83
91
 
84
92
  def debug_logger
85
93
  logger = Logger.new(STDERR)
86
94
  logger.formatter = proc do |severity, datetime, progname, msg|
87
- "#{msg}\n"
95
+ "#{datetime} #{msg}\n"
88
96
  end
89
97
  logger
90
98
  end
data/lib/lstash/query.rb CHANGED
@@ -9,11 +9,13 @@ module Lstash
9
9
  class FormatError < StandardError; end
10
10
  class QueryMissing < StandardError; end
11
11
 
12
- LOGSTASH_PREFIX = 'logstash-'
13
- WILDCARD_QUERY = '*'
12
+ LOGSTASH_PREFIX = 'logstash-'.freeze
13
+ WILDCARD_QUERY = '*'.freeze
14
14
 
15
- def initialize(query = nil, arguments = {})
16
- @query = query
15
+ attr_accessor :from, :to
16
+
17
+ def initialize(query_string = nil, arguments = {})
18
+ @query_string = query_string
17
19
 
18
20
  @anchor = time_parse(arguments[:anchor], 'today')
19
21
  @from = time_parse(arguments[:from], 'today')
@@ -22,38 +24,51 @@ module Lstash
22
24
  @to = Time.now if @to > Time.now # prevent accessing non-existing times / indices
23
25
  end
24
26
 
25
- def time_range
26
- OpenStruct.new(from: @from, to: @to)
27
- end
28
-
29
- def date_range
30
- (@from.utc.to_date .. @to.utc.to_date)
27
+ def index_name(date)
28
+ "#{LOGSTASH_PREFIX}#{date.strftime('%Y.%m.%d')}"
31
29
  end
32
30
 
33
- def indices
34
- date_range.map { |d| "#{LOGSTASH_PREFIX}#{d.strftime('%Y.%m.%d')}" }
35
- end
36
-
37
- def body
31
+ def search(from, size)
38
32
  {
39
- sort: sort_order,
40
-
33
+ sort: sort_order,
41
34
  fields: %w(message),
35
+ query: filter,
36
+ from: from,
37
+ size: size
38
+ }
39
+ end
42
40
 
43
- # return in order of ascending timestamp
44
- query: {
45
- filtered: {
46
- query: es_query,
47
- filter: es_filter
48
- }
41
+ def filter
42
+ {
43
+ filtered: {
44
+ query: es_query,
45
+ filter: es_filter
49
46
  }
50
47
  }
51
48
  end
52
49
 
50
+ def each_period(step, &block)
51
+ # iterate over the whole range in blocks of the specified period
52
+ time_iterate(@from.utc, @to.utc - 1, step) do |start_at|
53
+ yield index_name(start_at.to_date),
54
+ Query.new(@query_string,
55
+ anchor: @anchor,
56
+ from: start_at,
57
+ to: start_at + step)
58
+ end
59
+ end
60
+
53
61
  private
54
62
 
55
- def time_parse(time_string, default)
56
- time_string = time_string.strip rescue nil
63
+ def time_iterate(start_time, end_time, step, &block)
64
+ begin
65
+ yield(start_time)
66
+ end while (start_time += step) < end_time
67
+ end
68
+
69
+ def time_parse(time_or_string, default)
70
+ return time_or_string if time_or_string.is_a? Time
71
+ time_string = time_or_string.strip rescue nil
57
72
  time_string ||= default
58
73
  case time_string
59
74
  when 'firstday'
@@ -71,13 +86,14 @@ module Lstash
71
86
  raise FormatError, "Invalid time format: #{time_string}"
72
87
  end
73
88
 
74
- def query
75
- q = @query.dup.strip rescue ''
89
+ def query_string
90
+ q = @query_string.dup.strip rescue ''
76
91
  q = WILDCARD_QUERY if q.empty?
77
92
  q
78
93
  end
79
94
 
80
95
  def sort_order
96
+ # return results in order of ascending timestamp
81
97
  [ { '@timestamp' => { order: 'asc' } } ]
82
98
  end
83
99
 
@@ -87,7 +103,7 @@ module Lstash
87
103
  should: [
88
104
  {
89
105
  query_string: {
90
- query: query
106
+ query: query_string
91
107
  }
92
108
  }
93
109
  ]
@@ -101,14 +117,14 @@ module Lstash
101
117
  must: [
102
118
  range: {
103
119
  '@timestamp' => {
104
- from: to_msec(time_range.from),
105
- to: to_msec(time_range.to)
120
+ gte: to_msec(from),
121
+ lt: to_msec(to)
106
122
  }
107
123
  },
108
124
  # fquery: {
109
125
  # query: {
110
126
  # query_string: {
111
- # query: query
127
+ # query: query_string
112
128
  # }
113
129
  # }
114
130
  # }
@@ -117,7 +133,7 @@ module Lstash
117
133
  # fquery: {
118
134
  # query: {
119
135
  # query_string: {
120
- # query: query
136
+ # query: query_string
121
137
  # }
122
138
  # }
123
139
  # }
@@ -126,7 +142,7 @@ module Lstash
126
142
  # fquery: {
127
143
  # query: {
128
144
  # query_string: {
129
- # query: query
145
+ # query: query_string
130
146
  # }
131
147
  # }
132
148
  # }
@@ -1,3 +1,3 @@
1
1
  module Lstash
2
- VERSION = "0.0.9"
2
+ VERSION = "0.2.0"
3
3
  end
data/lstash.gemspec CHANGED
@@ -10,7 +10,7 @@ Gem::Specification.new do |spec|
10
10
  spec.email = ["k.j.wierenga@gmail.com"]
11
11
  spec.description = %q{Count or grep log messages in a specified time range from a Logstash Elasticsearch server.}
12
12
  spec.summary = %q{The lstash gem allows you to count or grep log messages in a specific time range from a Logstash Elasticsearch server. }
13
- spec.homepage = "http://bitbucket.org/kjwierenga/lstash"
13
+ spec.homepage = "https://github.com/kjwierenga/lstash"
14
14
  spec.license = "MIT"
15
15
 
16
16
  spec.files = `git ls-files`.split($/)
@@ -20,16 +20,14 @@ Gem::Specification.new do |spec|
20
20
  spec.extra_rdoc_files = [ 'LICENSE.txt', 'README.md', 'CHANGELOG.md' ]
21
21
 
22
22
  spec.add_development_dependency "bundler", "~> 1.3"
23
- spec.add_development_dependency "rake"
24
- spec.add_development_dependency "rspec"
25
- spec.add_development_dependency "rspec-its"
26
- spec.add_development_dependency "rspec-autotest"
27
- spec.add_development_dependency "autotest-standalone"
28
- spec.add_development_dependency "autotest-fsevent"
29
- spec.add_development_dependency "timecop"
23
+ spec.add_development_dependency "rake", "~> 10.3.2"
24
+ spec.add_development_dependency "rspec", "~> 3.0.0"
25
+ spec.add_development_dependency "rspec-its", "~> 1.0.1"
26
+ spec.add_development_dependency "timecop", "~> 0.7.1"
30
27
 
31
- spec.add_dependency "typhoeus"
28
+ spec.add_dependency "typhoeus", "~> 1.4.0"
32
29
  spec.add_dependency "elasticsearch", "~> 0.4"
33
- spec.add_dependency "hashie"
34
- spec.add_dependency "thor"
30
+ spec.add_dependency "hashie", "~> 4.1.0"
31
+ spec.add_dependency "thor", "~> 0.20.3"
32
+ spec.add_dependency "faraday", "~> 0.17.4"
35
33
  end
@@ -9,6 +9,13 @@ end
9
9
 
10
10
  describe Lstash::CLI do
11
11
 
12
+ before(:all) do
13
+ Timecop.freeze('2014-08-01 14:58')
14
+ end
15
+ after(:all) do
16
+ Timecop.return
17
+ end
18
+
12
19
  context "options" do
13
20
  subject { Lstash::CLI.options(args) }
14
21
 
@@ -25,9 +32,12 @@ describe Lstash::CLI do
25
32
  client = double('client')
26
33
 
27
34
  allow(Lstash::Client).to receive(:new).and_return(client)
28
- allow(client).to receive(:count).and_return(100)
35
+ allow(client).to receive(:count).and_return(1000)
29
36
 
30
- expect { Lstash::CLI.start(args) }.not_to raise_error
37
+ expect {
38
+ output = capture_stdout { Lstash::CLI.start(args) }
39
+ expect(output).to eq "1000\n"
40
+ }.not_to raise_error
31
41
  end
32
42
  end
33
43
 
@@ -52,7 +62,7 @@ describe Lstash::CLI do
52
62
  it "should print error message" do
53
63
  output = capture_stderr { Lstash::CLI.start(args) }
54
64
 
55
- expect(output).to eq "the scheme http does not accept registry part: '':9200 (or bad hostname?)\n"
65
+ expect(output).to include("Failed to open TCP connection to '':9200")
56
66
  end
57
67
  end
58
68
 
@@ -68,52 +78,33 @@ describe Lstash::CLI do
68
78
  context "with anchor date" do
69
79
  let(:args) { %w(count program:haproxy --from firstday --to today --anchor yesterday) }
70
80
 
71
- it "should succeed" do
72
- Timecop.freeze('2014-08-01 14:58') do
73
- es_client = double('es_client')
81
+ it "should return correct count" do
82
+ es_client = double('es_client')
74
83
 
75
- allow(Elasticsearch::Client).to receive(:new) { es_client }
84
+ allow(Elasticsearch::Client).to receive(:new) { es_client }
76
85
 
77
- expect(es_client).to receive(:count).with(satisfy { |args|
78
- expect_time_range(args, [
79
- Time.parse('2014-07-01').to_i*1000,
80
- Time.parse('2014-08-01').to_i*1000
81
- ])
82
- }).exactly(32).times.and_return({count:1})
86
+ expect(es_client).to receive(:count).exactly(31 * 24).times.and_return(count:100)
83
87
 
84
- Lstash::CLI.start(args)
85
- end
88
+ output = capture_stdout { Lstash::CLI.start(args) }
89
+ expect(output).to match("#{31 * 24 * 100}")
86
90
  end
87
91
  end
88
92
 
89
93
  context "without anchor date" do
90
94
  let(:args) { %w(count program:haproxy --from yesterday --to today) }
91
95
 
92
- it "should succeed" do
93
- Timecop.freeze('2014-08-01 14:58') do
94
- es_client = double('es_client')
96
+ it "should return correct count" do
97
+ es_client = double('es_client')
95
98
 
96
- allow(Elasticsearch::Client).to receive(:new) { es_client }
99
+ allow(Elasticsearch::Client).to receive(:new) { es_client }
97
100
 
98
- expect(es_client).to receive(:count).with(satisfy { |args|
99
- expect_time_range(args, [
100
- Time.parse('2014-07-31').to_i*1000,
101
- Time.parse('2014-08-01').to_i*1000
102
- ])
103
- }).exactly(2).times.and_return({count:1})
101
+ expect(es_client).to receive(:count).exactly(24).times.and_return(count:100)
104
102
 
105
- Lstash::CLI.start(args)
106
- end
103
+ output = capture_stdout { Lstash::CLI.start(args) }
104
+ expect(output).to match("#{24 * 100}")
107
105
  end
108
106
  end
109
107
 
110
108
  end
111
109
 
112
- private
113
-
114
- def expect_time_range(args, time_range)
115
- expect(args[:body][:filtered][:filter][:bool][:must].first[:range]['@timestamp'][:from]).to eq time_range.first
116
- expect(args[:body][:filtered][:filter][:bool][:must].first[:range]['@timestamp'][:to]).to eq time_range.last
117
- end
118
-
119
110
  end
@@ -12,38 +12,45 @@ describe Lstash::Client do
12
12
 
13
13
  context "with query" do
14
14
 
15
- let(:query) { double('query', time_range: OpenStruct.new) }
16
-
17
15
  context "count" do
18
16
  it "should return number of messages matching query" do
19
- allow(query).to receive(:indices).and_return (['logstash-2014-08-01', 'logstash-2014-08-02'])
20
- allow(query).to receive(:body).and_return ({})
21
17
 
22
- allow(es_client).to receive(:count).and_return({'count' => 100},{'count' => 100})
18
+ query = Lstash::Query.new("*", from: Time.parse("2014-10-10 00:00"), to: Time.parse("2014-10-10 07:00"))
19
+
20
+ allow(es_client).to receive(:count).and_return(
21
+ { 'count' => 100 },
22
+ { 'count' => 200 },
23
+ { 'count' => 300 },
24
+ { 'count' => 400 },
25
+ { 'count' => 500 },
26
+ { 'count' => 600 },
27
+ { 'count' => 700 }
28
+ )
23
29
 
24
- expect(subject.count(query)).to eq 200
30
+ expect(subject.count(query)).to eq 2800
25
31
  end
26
32
  end
27
33
 
28
34
  context "grep" do
29
- let(:query) { double('query', time_range: OpenStruct.new) }
30
-
31
35
  it "should return the messages matching the query" do
32
- allow(query).to receive(:indices).and_return (['logstash-2014-08-01', 'logstash-2014-08-02'])
33
- allow(query).to receive(:body).and_return ({})
34
-
35
- allow(es_client).to receive(:search).and_return(
36
- hits([
37
- 'this is the first log line',
38
- 'this is the second log line'
39
- ])
36
+
37
+ query = Lstash::Query.new("*", from: Time.parse("2014-10-10 00:00"), to: Time.parse("2014-10-10 07:00"))
38
+
39
+ expect(es_client).to receive(:search).and_return(
40
+ hits(%w(1)),
41
+ hits(%w(2 2)),
42
+ hits(%w(3 3 3)),
43
+ hits(%w(4 4 4 4)),
44
+ hits(%w(5 5 5 5 5)),
45
+ hits(%w(6 6 6 6 6 6)),
46
+ hits(%w(7 7 7 7 7 7 7))
40
47
  )
41
48
 
42
49
  allow(es_client).to receive(:scroll).and_return(hits([]))
43
50
 
44
51
  allow(es_client).to receive(:clear_scroll)
45
52
 
46
- subject.grep(query)
53
+ expect(subject.grep(query, 3600)).to eq 28
47
54
  end
48
55
  end
49
56
 
@@ -5,10 +5,10 @@ describe Lstash::Query do
5
5
 
6
6
  context "running on 2014-08-03" do
7
7
  let(:time) { '2014-08-03 15:54:33' }
8
- let(:query) { nil }
8
+ let(:query_string) { nil }
9
9
  let(:options) { {} }
10
10
 
11
- subject { Lstash::Query.new(query, options) }
11
+ subject { Lstash::Query.new(query_string, options) }
12
12
 
13
13
  before { Timecop.freeze(Time.parse(time)) }
14
14
  after { Timecop.return }
@@ -18,110 +18,171 @@ describe Lstash::Query do
18
18
  # expect(subject).not_to be nil
19
19
  # end
20
20
 
21
- its('time_range.from') { should eq Time.parse('2014-08-03 00:00:00.000000000 +0200') }
22
- its('time_range.to') { should eq Time.parse('2014-08-03 15:54:33.000000000 +0200') }
21
+ its('from') { should eq Time.parse('2014-08-03 00:00:00.000000000 +0200') }
22
+ its('to') { should eq Time.parse('2014-08-03 15:54:33.000000000 +0200') }
23
23
 
24
- its(:date_range) { should eq (Date.parse('2014-08-02')..Date.parse('2014-08-03')) }
24
+ # its(:date_range) { should eq (Date.parse('2014-08-02')..Date.parse('2014-08-03')) }
25
25
 
26
- its(:indices) { should eq [ "logstash-2014.08.02", "logstash-2014.08.03" ] }
26
+ # its(:indices) { should eq [ "logstash-2014.08.02", "logstash-2014.08.03" ] }
27
27
 
28
28
  context "with specific query" do
29
- let(:query) { 'program:haproxy' }
30
- its(:query) { should eq query }
29
+ let(:query_string) { 'program:haproxy' }
30
+ its(:query_string) { should eq query_string }
31
31
  end
32
32
 
33
33
  context "without query" do
34
- let(:query) { nil }
35
- its(:query) { should eql '*' }
34
+ let(:query_string) { nil }
35
+ its(:query_string) { should eql '*' }
36
36
  end
37
37
 
38
38
  context "from 'yesterday'" do
39
39
  let(:options) { { from: 'yesterday' }}
40
- its('time_range.from') { should eq Time.parse('2014-08-02 00:00:00.000000000 +0200') }
40
+ its('from') { should eq Time.parse('2014-08-02 00:00:00.000000000 +0200') }
41
41
  end
42
42
 
43
43
  context "from 'today'" do
44
44
  let(:options) { { from: 'today' }}
45
- its('time_range.from') { should eq Time.parse('2014-08-03 00:00:00.000000000 +0200') }
45
+ its('from') { should eq Time.parse('2014-08-03 00:00:00.000000000 +0200') }
46
46
  end
47
47
 
48
48
  context "from 'now'" do
49
49
  let(:options) { { from: 'now' }}
50
- its('time_range.from') { should eq Time.parse('2014-08-03 15:54:33.000000000 +0200') }
50
+ its('from') { should eq Time.parse('2014-08-03 15:54:33.000000000 +0200') }
51
51
  end
52
52
 
53
53
  context "to 'yesterday'" do
54
54
  let(:options) { { to: 'yesterday' }}
55
- its('time_range.to') { should eq Time.parse('2014-08-02 00:00:00.000000000 +0200') }
55
+ its('to') { should eq Time.parse('2014-08-02 00:00:00.000000000 +0200') }
56
56
  end
57
57
 
58
58
  context "to 'today'" do
59
59
  let(:options) { { to: 'today' }}
60
- its('time_range.to') { should eq Time.parse('2014-08-03 00:00:00.000000000 +0200') }
60
+ its('to') { should eq Time.parse('2014-08-03 00:00:00.000000000 +0200') }
61
61
  end
62
62
 
63
63
  context "to 'now'" do
64
64
  let(:options) { { to: 'now' }}
65
- its('time_range.to') { should eq Time.parse('2014-08-03 15:54:33.000000000 +0200') }
65
+ its('to') { should eq Time.parse('2014-08-03 15:54:33.000000000 +0200') }
66
66
  end
67
67
 
68
68
  context "from 'firstday'" do
69
69
 
70
70
  let(:options) { { from: 'firstday' } }
71
- its('time_range.from') { should eq Time.parse('2014-08-01 00:00:00.000000000 +0200') }
71
+ its('from') { should eq Time.parse('2014-08-01 00:00:00.000000000 +0200') }
72
72
 
73
73
  context "anchor 'yesterday'" do
74
74
  let(:anchor) { 'yesterday' }
75
- its('time_range.from') { should eq Time.parse('2014-08-01 00:00:00.000000000 +0200') }
75
+ its('from') { should eq Time.parse('2014-08-01 00:00:00.000000000 +0200') }
76
76
  end
77
77
 
78
78
  context "anchor 'today'" do
79
79
  let(:anchor) { 'today' }
80
- its('time_range.from') { should eq Time.parse('2014-08-01 00:00:00.000000000 +0200') }
80
+ its('from') { should eq Time.parse('2014-08-01 00:00:00.000000000 +0200') }
81
81
  end
82
82
 
83
83
  context "anchor '2014-07-17'" do
84
84
  let(:options) { { from: 'firstday', anchor: '2014-07-17' } }
85
- its('time_range.from') { should eq Time.parse('2014-07-01 00:00:00.000000000 +0200') }
85
+ its('from') { should eq Time.parse('2014-07-01 00:00:00.000000000 +0200') }
86
86
  end
87
87
 
88
88
  context "date range" do
89
89
  let(:options) { { from: 'firstday', anchor: 'yesterday' } }
90
- its(:date_range) { should eq (Date.parse('2014-07-31')..Date.parse('2014-08-03')) }
90
+ its('from') { should eq Time.parse('2014-08-01 00:00:00.000000000 +0200') }
91
+ its('to') { should eq Time.parse('2014-08-03 15:54:33.000000000 +0200') }
91
92
  end
92
93
 
93
- context "indices" do
94
- let(:options) { { from: 'firstday', anchor: 'yesterday' } }
95
- its(:indices) {
96
- should eq [
97
- "logstash-2014.07.31",
98
- "logstash-2014.08.01",
99
- "logstash-2014.08.02",
100
- "logstash-2014.08.03",
101
- ]
102
- }
94
+ context "each_period" do
95
+ let(:options) { { from: 'firstday', anchor: 'yesterday', to: 'today' } }
96
+ it "should iterate over range by hour" do
97
+ indices = []
98
+ queries = []
99
+ subject.each_period(3600) do |index, query|
100
+ indices << index
101
+ queries << query
102
+ end
103
+ expect(indices.count).to eq ((subject.to - subject.from)/3600).round
104
+ expect(indices.uniq).to eq %w(
105
+ logstash-2014.07.31
106
+ logstash-2014.08.01
107
+ logstash-2014.08.02
108
+ )
109
+ expect(queries.map(&:from).map(&:to_s)).to eq ([
110
+ "2014-07-31 22:00:00 UTC",
111
+ "2014-07-31 23:00:00 UTC",
112
+ "2014-08-01 00:00:00 UTC",
113
+ "2014-08-01 01:00:00 UTC",
114
+ "2014-08-01 02:00:00 UTC",
115
+ "2014-08-01 03:00:00 UTC",
116
+ "2014-08-01 04:00:00 UTC",
117
+ "2014-08-01 05:00:00 UTC",
118
+ "2014-08-01 06:00:00 UTC",
119
+ "2014-08-01 07:00:00 UTC",
120
+ "2014-08-01 08:00:00 UTC",
121
+ "2014-08-01 09:00:00 UTC",
122
+ "2014-08-01 10:00:00 UTC",
123
+ "2014-08-01 11:00:00 UTC",
124
+ "2014-08-01 12:00:00 UTC",
125
+ "2014-08-01 13:00:00 UTC",
126
+ "2014-08-01 14:00:00 UTC",
127
+ "2014-08-01 15:00:00 UTC",
128
+ "2014-08-01 16:00:00 UTC",
129
+ "2014-08-01 17:00:00 UTC",
130
+ "2014-08-01 18:00:00 UTC",
131
+ "2014-08-01 19:00:00 UTC",
132
+ "2014-08-01 20:00:00 UTC",
133
+ "2014-08-01 21:00:00 UTC",
134
+ "2014-08-01 22:00:00 UTC",
135
+ "2014-08-01 23:00:00 UTC",
136
+ "2014-08-02 00:00:00 UTC",
137
+ "2014-08-02 01:00:00 UTC",
138
+ "2014-08-02 02:00:00 UTC",
139
+ "2014-08-02 03:00:00 UTC",
140
+ "2014-08-02 04:00:00 UTC",
141
+ "2014-08-02 05:00:00 UTC",
142
+ "2014-08-02 06:00:00 UTC",
143
+ "2014-08-02 07:00:00 UTC",
144
+ "2014-08-02 08:00:00 UTC",
145
+ "2014-08-02 09:00:00 UTC",
146
+ "2014-08-02 10:00:00 UTC",
147
+ "2014-08-02 11:00:00 UTC",
148
+ "2014-08-02 12:00:00 UTC",
149
+ "2014-08-02 13:00:00 UTC",
150
+ "2014-08-02 14:00:00 UTC",
151
+ "2014-08-02 15:00:00 UTC",
152
+ "2014-08-02 16:00:00 UTC",
153
+ "2014-08-02 17:00:00 UTC",
154
+ "2014-08-02 18:00:00 UTC",
155
+ "2014-08-02 19:00:00 UTC",
156
+ "2014-08-02 20:00:00 UTC",
157
+ "2014-08-02 21:00:00 UTC"
158
+ ])
159
+ end
103
160
  end
104
161
 
105
162
  end
106
163
 
107
- context "body" do
108
- its(:body) { should eq ({
109
- :sort => [{"@timestamp"=>{:order=>"asc"}}],
110
- :fields => %w(message),
111
- :query => {:filtered=>{
112
- :query => { :bool => { :should => [ { :query_string => { :query=>"*" }}]}},
113
- :filter=> { :bool => { :must => [ { :range => { "@timestamp" => { :from => 1407016800000, :to => 1407074073000}}}]}}}}
114
- })}
164
+ context "search" do
165
+ it "should produce the correct elasticsearch search request attributes" do
166
+ expect(subject.search(0, 10)).to eq ({
167
+ :sort => [{"@timestamp"=>{:order=>"asc"}}],
168
+ :fields => %w(message),
169
+ :query => {:filtered=>{
170
+ :query => { :bool => { :should => [ { :query_string => { :query=>"*" }}]}},
171
+ :filter=> { :bool => { :must => [ { :range => { "@timestamp" => { :gte => 1407016800000, :lt => 1407074073000}}}]}}}},
172
+ :from => 0,
173
+ :size => 10
174
+ })
175
+ end
115
176
  end
116
177
 
117
178
  end
118
179
 
119
180
  context "running on 2014-08-01" do
120
181
  let(:time) { '2014-08-01 12:53:03' }
121
- let(:query) { nil }
182
+ let(:query_string) { nil }
122
183
  let(:options) { {} }
123
184
 
124
- subject { Lstash::Query.new(query, options) }
185
+ subject { Lstash::Query.new(query_string, options) }
125
186
 
126
187
  before { Timecop.freeze(Time.parse(time)) }
127
188
  after { Timecop.return }
@@ -129,15 +190,15 @@ describe Lstash::Query do
129
190
  context "from 'firstday' with 'yesterday' anchor" do
130
191
  let(:options) { { anchor: 'yesterday', from: 'firstday' } }
131
192
 
132
- its('time_range.from') { should eq Time.parse('2014-07-01 00:00:00.000000000 +0200') }
133
- its('time_range.to') { should eq Time.parse('2014-08-01 12:53:03.000000000 +0200') }
193
+ its('from') { should eq Time.parse('2014-07-01 00:00:00.000000000 +0200') }
194
+ its('to') { should eq Time.parse('2014-08-01 12:53:03.000000000 +0200') }
134
195
  end
135
196
 
136
197
  context "from 'firstday' with default 'today' anchor" do
137
198
  let(:options) { { from: 'firstday', to: 'now' } }
138
199
 
139
- its('time_range.from') { should eq Time.parse('2014-08-01 00:00:00.000000000 +0200') }
140
- its('time_range.to') { should eq Time.parse('2014-08-01 12:53:03.000000000 +0200') }
200
+ its('from') { should eq Time.parse('2014-08-01 00:00:00.000000000 +0200') }
201
+ its('to') { should eq Time.parse('2014-08-01 12:53:03.000000000 +0200') }
141
202
  end
142
203
 
143
204
  end
metadata CHANGED
@@ -1,183 +1,155 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lstash
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.9
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Klaas Jan Wierenga
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-09-22 00:00:00.000000000 Z
11
+ date: 2021-02-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ~>
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.3'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ~>
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.3'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - ! '>='
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0'
33
+ version: 10.3.2
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - ! '>='
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0'
40
+ version: 10.3.2
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: rspec
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
- - - ! '>='
45
+ - - "~>"
46
46
  - !ruby/object:Gem::Version
47
- version: '0'
47
+ version: 3.0.0
48
48
  type: :development
49
49
  prerelease: false
50
50
  version_requirements: !ruby/object:Gem::Requirement
51
51
  requirements:
52
- - - ! '>='
52
+ - - "~>"
53
53
  - !ruby/object:Gem::Version
54
- version: '0'
54
+ version: 3.0.0
55
55
  - !ruby/object:Gem::Dependency
56
56
  name: rspec-its
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ! '>='
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: 1.0.1
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ! '>='
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: 1.0.1
69
69
  - !ruby/object:Gem::Dependency
70
- name: rspec-autotest
71
- requirement: !ruby/object:Gem::Requirement
72
- requirements:
73
- - - ! '>='
74
- - !ruby/object:Gem::Version
75
- version: '0'
76
- type: :development
77
- prerelease: false
78
- version_requirements: !ruby/object:Gem::Requirement
79
- requirements:
80
- - - ! '>='
81
- - !ruby/object:Gem::Version
82
- version: '0'
83
- - !ruby/object:Gem::Dependency
84
- name: autotest-standalone
85
- requirement: !ruby/object:Gem::Requirement
86
- requirements:
87
- - - ! '>='
88
- - !ruby/object:Gem::Version
89
- version: '0'
90
- type: :development
91
- prerelease: false
92
- version_requirements: !ruby/object:Gem::Requirement
93
- requirements:
94
- - - ! '>='
95
- - !ruby/object:Gem::Version
96
- version: '0'
97
- - !ruby/object:Gem::Dependency
98
- name: autotest-fsevent
70
+ name: timecop
99
71
  requirement: !ruby/object:Gem::Requirement
100
72
  requirements:
101
- - - ! '>='
73
+ - - "~>"
102
74
  - !ruby/object:Gem::Version
103
- version: '0'
75
+ version: 0.7.1
104
76
  type: :development
105
77
  prerelease: false
106
78
  version_requirements: !ruby/object:Gem::Requirement
107
79
  requirements:
108
- - - ! '>='
80
+ - - "~>"
109
81
  - !ruby/object:Gem::Version
110
- version: '0'
82
+ version: 0.7.1
111
83
  - !ruby/object:Gem::Dependency
112
- name: timecop
84
+ name: typhoeus
113
85
  requirement: !ruby/object:Gem::Requirement
114
86
  requirements:
115
- - - ! '>='
87
+ - - "~>"
116
88
  - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
89
+ version: 1.4.0
90
+ type: :runtime
119
91
  prerelease: false
120
92
  version_requirements: !ruby/object:Gem::Requirement
121
93
  requirements:
122
- - - ! '>='
94
+ - - "~>"
123
95
  - !ruby/object:Gem::Version
124
- version: '0'
96
+ version: 1.4.0
125
97
  - !ruby/object:Gem::Dependency
126
- name: typhoeus
98
+ name: elasticsearch
127
99
  requirement: !ruby/object:Gem::Requirement
128
100
  requirements:
129
- - - ! '>='
101
+ - - "~>"
130
102
  - !ruby/object:Gem::Version
131
- version: '0'
103
+ version: '0.4'
132
104
  type: :runtime
133
105
  prerelease: false
134
106
  version_requirements: !ruby/object:Gem::Requirement
135
107
  requirements:
136
- - - ! '>='
108
+ - - "~>"
137
109
  - !ruby/object:Gem::Version
138
- version: '0'
110
+ version: '0.4'
139
111
  - !ruby/object:Gem::Dependency
140
- name: elasticsearch
112
+ name: hashie
141
113
  requirement: !ruby/object:Gem::Requirement
142
114
  requirements:
143
- - - ~>
115
+ - - "~>"
144
116
  - !ruby/object:Gem::Version
145
- version: '0.4'
117
+ version: 4.1.0
146
118
  type: :runtime
147
119
  prerelease: false
148
120
  version_requirements: !ruby/object:Gem::Requirement
149
121
  requirements:
150
- - - ~>
122
+ - - "~>"
151
123
  - !ruby/object:Gem::Version
152
- version: '0.4'
124
+ version: 4.1.0
153
125
  - !ruby/object:Gem::Dependency
154
- name: hashie
126
+ name: thor
155
127
  requirement: !ruby/object:Gem::Requirement
156
128
  requirements:
157
- - - ! '>='
129
+ - - "~>"
158
130
  - !ruby/object:Gem::Version
159
- version: '0'
131
+ version: 0.20.3
160
132
  type: :runtime
161
133
  prerelease: false
162
134
  version_requirements: !ruby/object:Gem::Requirement
163
135
  requirements:
164
- - - ! '>='
136
+ - - "~>"
165
137
  - !ruby/object:Gem::Version
166
- version: '0'
138
+ version: 0.20.3
167
139
  - !ruby/object:Gem::Dependency
168
- name: thor
140
+ name: faraday
169
141
  requirement: !ruby/object:Gem::Requirement
170
142
  requirements:
171
- - - ! '>='
143
+ - - "~>"
172
144
  - !ruby/object:Gem::Version
173
- version: '0'
145
+ version: 0.17.4
174
146
  type: :runtime
175
147
  prerelease: false
176
148
  version_requirements: !ruby/object:Gem::Requirement
177
149
  requirements:
178
- - - ! '>='
150
+ - - "~>"
179
151
  - !ruby/object:Gem::Version
180
- version: '0'
152
+ version: 0.17.4
181
153
  description: Count or grep log messages in a specified time range from a Logstash
182
154
  Elasticsearch server.
183
155
  email:
@@ -190,12 +162,12 @@ extra_rdoc_files:
190
162
  - README.md
191
163
  - CHANGELOG.md
192
164
  files:
193
- - .autotest
194
- - .gitignore
195
- - .rspec
196
- - .ruby-gemset
197
- - .ruby-version
198
- - .travis.yml
165
+ - ".autotest"
166
+ - ".gitignore"
167
+ - ".rspec"
168
+ - ".ruby-gemset"
169
+ - ".ruby-version"
170
+ - ".travis.yml"
199
171
  - CHANGELOG.md
200
172
  - Gemfile
201
173
  - LICENSE.txt
@@ -213,28 +185,27 @@ files:
213
185
  - spec/lstash/query_spec.rb
214
186
  - spec/lstash_spec.rb
215
187
  - spec/spec_helper.rb
216
- homepage: http://bitbucket.org/kjwierenga/lstash
188
+ homepage: https://github.com/kjwierenga/lstash
217
189
  licenses:
218
190
  - MIT
219
191
  metadata: {}
220
- post_install_message:
192
+ post_install_message:
221
193
  rdoc_options: []
222
194
  require_paths:
223
195
  - lib
224
196
  required_ruby_version: !ruby/object:Gem::Requirement
225
197
  requirements:
226
- - - ! '>='
198
+ - - ">="
227
199
  - !ruby/object:Gem::Version
228
200
  version: '0'
229
201
  required_rubygems_version: !ruby/object:Gem::Requirement
230
202
  requirements:
231
- - - ! '>='
203
+ - - ">="
232
204
  - !ruby/object:Gem::Version
233
205
  version: '0'
234
206
  requirements: []
235
- rubyforge_project:
236
- rubygems_version: 2.4.1
237
- signing_key:
207
+ rubygems_version: 3.0.8
208
+ signing_key:
238
209
  specification_version: 4
239
210
  summary: The lstash gem allows you to count or grep log messages in a specific time
240
211
  range from a Logstash Elasticsearch server.