lstash 0.2.0 → 1.0.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.
- checksums.yaml +4 -4
- data/.devcontainer/Aptfile +6 -0
- data/.devcontainer/Dockerfile +44 -0
- data/.devcontainer/devcontainer.json +36 -0
- data/.github/workflows/test.yml +67 -0
- data/CHANGELOG.md +22 -3
- data/README.md +86 -86
- data/bin/lstash +1 -3
- data/dip.yml +48 -0
- data/docker-compose.yml +28 -0
- data/lib/lstash/cli.rb +42 -29
- data/lib/lstash/client.rb +58 -37
- data/lib/lstash/query.rb +54 -77
- data/lib/lstash/version.rb +1 -1
- data/lib/lstash.rb +4 -4
- data/lstash.gemspec +14 -19
- data/spec/lstash/cli_spec.rb +21 -23
- data/spec/lstash/client_spec.rb +29 -33
- data/spec/lstash/query_spec.rb +62 -60
- data/spec/lstash_spec.rb +3 -3
- data/spec/spec_helper.rb +28 -13
- metadata +17 -58
data/lib/lstash/client.rb
CHANGED
@@ -1,49 +1,66 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require 'hashie'
|
1
|
+
require "logger"
|
2
|
+
require "date"
|
4
3
|
|
5
4
|
class NullLogger < Logger
|
6
|
-
def initialize(*args)
|
7
|
-
|
5
|
+
def initialize(*args)
|
6
|
+
end
|
7
|
+
|
8
|
+
def add(*args, &block)
|
9
|
+
end
|
8
10
|
end
|
9
11
|
|
10
12
|
module Lstash
|
11
|
-
|
12
13
|
class Client
|
13
|
-
|
14
14
|
class ConnectionError < StandardError; end
|
15
15
|
|
16
|
-
|
17
|
-
|
18
|
-
|
16
|
+
class ShardMismatchError < StandardError; end
|
17
|
+
|
18
|
+
PER_PAGE = 5000 # best time, lowest resource usage
|
19
|
+
COUNT_STEP = 3600 # 1 hours
|
20
|
+
GREP_STEP = 3600 # 1 hour
|
19
21
|
|
20
22
|
def initialize(es_client, options = {})
|
21
23
|
raise ConnectionError, "No elasticsearch client specified" if es_client.nil?
|
22
24
|
|
23
25
|
@es_client = es_client
|
24
|
-
@logger
|
26
|
+
@logger = options[:logger] || (options[:debug] ? debug_logger : NullLogger.new)
|
27
|
+
@wildcard = options[:wildcard]
|
25
28
|
end
|
26
29
|
|
27
|
-
def count(query
|
30
|
+
def count(query)
|
28
31
|
@logger.debug "count from=#{query.from} to=#{query.to}"
|
29
32
|
|
30
33
|
count = 0
|
31
|
-
|
32
|
-
|
34
|
+
use_wildcard = @wildcard.nil? ? true : @wildcard
|
35
|
+
if use_wildcard
|
36
|
+
count = count_messages(query.wildcard_indices, query)
|
37
|
+
else
|
38
|
+
count = 0
|
39
|
+
query.each_period(COUNT_STEP) do |index, hour_query|
|
40
|
+
count += count_messages(index, hour_query)
|
41
|
+
end
|
33
42
|
end
|
34
43
|
@logger.debug "total count=#{count}"
|
35
44
|
count
|
36
45
|
end
|
37
46
|
|
38
|
-
def grep(query
|
47
|
+
def grep(query)
|
39
48
|
@logger.debug "grep from=#{query.from} to=#{query.to}"
|
40
49
|
|
41
50
|
count = 0
|
42
|
-
|
43
|
-
|
51
|
+
use_wildcard = @wildcard.nil? ? false : @wildcard
|
52
|
+
if use_wildcard
|
53
|
+
grep_messages(query.wildcard_indices, query) do |message|
|
44
54
|
count += 1
|
45
55
|
yield message if block_given?
|
46
56
|
end
|
57
|
+
else
|
58
|
+
query.each_period(GREP_STEP) do |index, hour_query|
|
59
|
+
grep_messages(index, hour_query) do |message|
|
60
|
+
count += 1
|
61
|
+
yield message if block_given?
|
62
|
+
end
|
63
|
+
end
|
47
64
|
end
|
48
65
|
|
49
66
|
@logger.debug "total count=#{count}"
|
@@ -53,12 +70,10 @@ module Lstash
|
|
53
70
|
private
|
54
71
|
|
55
72
|
def count_messages(index, query)
|
56
|
-
result =
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
@logger.debug "count index=#{index} from=#{query.from} to=#{query.to} count=#{result['count']}"
|
61
|
-
result['count']
|
73
|
+
result = @es_client.count(index: index, body: {query: query.filter})
|
74
|
+
validate_shards!(result["_shards"])
|
75
|
+
@logger.debug "count index=#{index} from=#{query.from.utc} to=#{query.to.utc} count=#{result["count"]}"
|
76
|
+
result["count"]
|
62
77
|
end
|
63
78
|
|
64
79
|
def grep_messages(index, query)
|
@@ -66,37 +81,43 @@ module Lstash
|
|
66
81
|
scroll_params = {}
|
67
82
|
offset = 0
|
68
83
|
method = :search
|
69
|
-
while
|
70
|
-
result =
|
71
|
-
index:
|
72
|
-
scroll:
|
73
|
-
body:
|
74
|
-
}
|
84
|
+
while messages.nil? || messages.count > 0
|
85
|
+
result = @es_client.send(method, {
|
86
|
+
index: index,
|
87
|
+
scroll: "5m",
|
88
|
+
body: (method == :search) ? query.search(offset, PER_PAGE) : scroll_params
|
89
|
+
})
|
75
90
|
|
76
|
-
|
91
|
+
validate_shards!(result["_shards"])
|
77
92
|
|
93
|
+
messages = result["hits"]["hits"]
|
78
94
|
offset += messages.count
|
79
|
-
scroll_params = {scroll_id: result
|
95
|
+
scroll_params = {scroll_id: result["_scroll_id"]}
|
80
96
|
|
81
97
|
messages.each do |h|
|
82
|
-
next if h.
|
83
|
-
yield h
|
98
|
+
next if h["_source"].nil?
|
99
|
+
yield h["_source"]["message"] if block_given?
|
84
100
|
end
|
85
101
|
|
86
102
|
method = :scroll
|
103
|
+
|
104
|
+
@logger.debug "grep index=#{index} from=#{query.from.utc} to=#{query.to.utc} count=#{offset}"
|
87
105
|
end
|
88
|
-
@
|
89
|
-
Hashie::Mash.new @es_client.clear_scroll(scroll_params)
|
106
|
+
@es_client.clear_scroll(body: scroll_params) unless scroll_params.empty?
|
90
107
|
end
|
91
108
|
|
92
109
|
def debug_logger
|
93
|
-
logger = Logger.new(
|
110
|
+
logger = Logger.new($stderr)
|
94
111
|
logger.formatter = proc do |severity, datetime, progname, msg|
|
95
112
|
"#{datetime} #{msg}\n"
|
96
113
|
end
|
97
114
|
logger
|
98
115
|
end
|
99
116
|
|
117
|
+
def validate_shards!(shards)
|
118
|
+
if shards["total"] != shards["successful"]
|
119
|
+
raise ShardMismatchError, "Shard mismatch: total: #{shards["total"]}, successful: #{shards["successful"]}"
|
120
|
+
end
|
121
|
+
end
|
100
122
|
end
|
101
|
-
|
102
123
|
end
|
data/lib/lstash/query.rb
CHANGED
@@ -1,47 +1,50 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require
|
1
|
+
require "time"
|
2
|
+
require "date"
|
3
|
+
require "ostruct"
|
4
4
|
|
5
5
|
module Lstash
|
6
|
-
|
7
6
|
class Query
|
8
|
-
|
9
7
|
class FormatError < StandardError; end
|
8
|
+
|
10
9
|
class QueryMissing < StandardError; end
|
11
10
|
|
12
|
-
LOGSTASH_PREFIX =
|
13
|
-
WILDCARD_QUERY
|
11
|
+
LOGSTASH_PREFIX = "logstash-".freeze
|
12
|
+
WILDCARD_QUERY = "*".freeze
|
14
13
|
|
15
14
|
attr_accessor :from, :to
|
16
15
|
|
17
16
|
def initialize(query_string = nil, arguments = {})
|
18
17
|
@query_string = query_string
|
19
18
|
|
20
|
-
@anchor = time_parse(arguments[:anchor],
|
21
|
-
@from
|
22
|
-
@to
|
19
|
+
@anchor = time_parse(arguments[:anchor], "today")
|
20
|
+
@from = time_parse(arguments[:from], "yesterday")
|
21
|
+
@to = time_parse(arguments[:to], "today")
|
23
22
|
|
24
23
|
@to = Time.now if @to > Time.now # prevent accessing non-existing times / indices
|
25
24
|
end
|
26
25
|
|
27
26
|
def index_name(date)
|
28
|
-
"#{LOGSTASH_PREFIX}#{date.strftime(
|
27
|
+
"#{LOGSTASH_PREFIX}#{date.strftime("%Y.%m.%d")}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def wildcard_indices
|
31
|
+
"logstash-*"
|
29
32
|
end
|
30
33
|
|
31
34
|
def search(from, size)
|
32
35
|
{
|
33
|
-
sort:
|
34
|
-
|
35
|
-
query:
|
36
|
-
from:
|
37
|
-
size:
|
36
|
+
sort: sort_order,
|
37
|
+
_source: %w[message],
|
38
|
+
query: filter,
|
39
|
+
from: from,
|
40
|
+
size: size
|
38
41
|
}
|
39
42
|
end
|
40
43
|
|
41
44
|
def filter
|
42
45
|
{
|
43
|
-
|
44
|
-
|
46
|
+
bool: {
|
47
|
+
must: es_query,
|
45
48
|
filter: es_filter
|
46
49
|
}
|
47
50
|
}
|
@@ -52,32 +55,37 @@ module Lstash
|
|
52
55
|
time_iterate(@from.utc, @to.utc - 1, step) do |start_at|
|
53
56
|
yield index_name(start_at.to_date),
|
54
57
|
Query.new(@query_string,
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
+
anchor: @anchor,
|
59
|
+
from: start_at,
|
60
|
+
to: start_at + step)
|
58
61
|
end
|
59
62
|
end
|
60
63
|
|
61
64
|
private
|
62
65
|
|
63
66
|
def time_iterate(start_time, end_time, step, &block)
|
64
|
-
|
67
|
+
while start_time < end_time
|
65
68
|
yield(start_time)
|
66
|
-
|
69
|
+
start_time += step
|
70
|
+
end
|
67
71
|
end
|
68
72
|
|
69
73
|
def time_parse(time_or_string, default)
|
70
74
|
return time_or_string if time_or_string.is_a? Time
|
71
|
-
time_string =
|
75
|
+
time_string = begin
|
76
|
+
time_or_string.strip
|
77
|
+
rescue
|
78
|
+
nil
|
79
|
+
end
|
72
80
|
time_string ||= default
|
73
81
|
case time_string
|
74
|
-
when
|
82
|
+
when "firstday"
|
75
83
|
midnight_at_beginning_of_month
|
76
|
-
when
|
84
|
+
when "now"
|
77
85
|
Time.now
|
78
|
-
when
|
86
|
+
when "today"
|
79
87
|
midnight_today
|
80
|
-
when
|
88
|
+
when "yesterday"
|
81
89
|
midnight_yesterday
|
82
90
|
else
|
83
91
|
Time.parse(time_string)
|
@@ -87,66 +95,37 @@ module Lstash
|
|
87
95
|
end
|
88
96
|
|
89
97
|
def query_string
|
90
|
-
q =
|
98
|
+
q = begin
|
99
|
+
@query_string.dup.strip
|
100
|
+
rescue
|
101
|
+
""
|
102
|
+
end
|
91
103
|
q = WILDCARD_QUERY if q.empty?
|
92
104
|
q
|
93
105
|
end
|
94
106
|
|
95
107
|
def sort_order
|
96
108
|
# return results in order of ascending timestamp
|
97
|
-
[
|
109
|
+
[{"@timestamp" => {order: "asc"}}]
|
98
110
|
end
|
99
111
|
|
100
112
|
def es_query
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
query: query_string
|
107
|
-
}
|
108
|
-
}
|
109
|
-
]
|
113
|
+
[
|
114
|
+
{
|
115
|
+
query_string: {
|
116
|
+
query: query_string
|
117
|
+
}
|
110
118
|
}
|
111
|
-
|
119
|
+
]
|
112
120
|
end
|
113
121
|
|
114
122
|
def es_filter
|
115
123
|
{
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
lt: to_msec(to)
|
122
|
-
}
|
123
|
-
},
|
124
|
-
# fquery: {
|
125
|
-
# query: {
|
126
|
-
# query_string: {
|
127
|
-
# query: query_string
|
128
|
-
# }
|
129
|
-
# }
|
130
|
-
# }
|
131
|
-
],
|
132
|
-
# must_not: [
|
133
|
-
# fquery: {
|
134
|
-
# query: {
|
135
|
-
# query_string: {
|
136
|
-
# query: query_string
|
137
|
-
# }
|
138
|
-
# }
|
139
|
-
# }
|
140
|
-
# ],
|
141
|
-
# should: [
|
142
|
-
# fquery: {
|
143
|
-
# query: {
|
144
|
-
# query_string: {
|
145
|
-
# query: query_string
|
146
|
-
# }
|
147
|
-
# }
|
148
|
-
# }
|
149
|
-
# ]
|
124
|
+
range: {
|
125
|
+
"@timestamp" => {
|
126
|
+
gte: to_msec(from),
|
127
|
+
lt: to_msec(to)
|
128
|
+
}
|
150
129
|
}
|
151
130
|
}
|
152
131
|
end
|
@@ -161,7 +140,7 @@ module Lstash
|
|
161
140
|
end
|
162
141
|
|
163
142
|
def midnight_yesterday
|
164
|
-
(Date.today-1).to_time
|
143
|
+
(Date.today - 1).to_time
|
165
144
|
end
|
166
145
|
|
167
146
|
def anchor_time
|
@@ -171,7 +150,5 @@ module Lstash
|
|
171
150
|
def to_msec(time)
|
172
151
|
time.to_i * 1000
|
173
152
|
end
|
174
|
-
|
175
153
|
end
|
176
|
-
|
177
154
|
end
|
data/lib/lstash/version.rb
CHANGED
data/lib/lstash.rb
CHANGED
data/lstash.gemspec
CHANGED
@@ -1,23 +1,21 @@
|
|
1
|
-
|
2
|
-
lib = File.expand_path('../lib', __FILE__)
|
1
|
+
lib = File.expand_path("../lib", __FILE__)
|
3
2
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require
|
3
|
+
require "lstash/version"
|
5
4
|
|
6
5
|
Gem::Specification.new do |spec|
|
7
|
-
spec.name
|
8
|
-
spec.version
|
9
|
-
spec.authors
|
10
|
-
spec.email
|
11
|
-
spec.description
|
12
|
-
spec.summary
|
13
|
-
spec.homepage
|
14
|
-
spec.license
|
6
|
+
spec.name = "lstash"
|
7
|
+
spec.version = Lstash::VERSION
|
8
|
+
spec.authors = ["Klaas Jan Wierenga"]
|
9
|
+
spec.email = ["k.j.wierenga@kerkdienstgemist.nl"]
|
10
|
+
spec.description = "Count or grep log messages in a specified time range from a Logstash Elasticsearch server."
|
11
|
+
spec.summary = "The lstash gem allows you to count or grep log messages in a specific time range from a Logstash Elasticsearch server. "
|
12
|
+
spec.homepage = "https://github.com/kdgm/lstash"
|
13
|
+
spec.license = "MIT"
|
15
14
|
|
16
|
-
spec.files
|
17
|
-
spec.executables
|
18
|
-
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
15
|
+
spec.files = `git ls-files`.split($/)
|
16
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
19
17
|
spec.require_paths = ["lib"]
|
20
|
-
spec.extra_rdoc_files = [
|
18
|
+
spec.extra_rdoc_files = ["LICENSE.txt", "README.md", "CHANGELOG.md"]
|
21
19
|
|
22
20
|
spec.add_development_dependency "bundler", "~> 1.3"
|
23
21
|
spec.add_development_dependency "rake", "~> 10.3.2"
|
@@ -25,9 +23,6 @@ Gem::Specification.new do |spec|
|
|
25
23
|
spec.add_development_dependency "rspec-its", "~> 1.0.1"
|
26
24
|
spec.add_development_dependency "timecop", "~> 0.7.1"
|
27
25
|
|
28
|
-
spec.add_dependency "
|
29
|
-
spec.add_dependency "elasticsearch", "~> 0.4"
|
30
|
-
spec.add_dependency "hashie", "~> 4.1.0"
|
26
|
+
spec.add_dependency "elasticsearch", "~> 7.17.7"
|
31
27
|
spec.add_dependency "thor", "~> 0.20.3"
|
32
|
-
spec.add_dependency "faraday", "~> 0.17.4"
|
33
28
|
end
|
data/spec/lstash/cli_spec.rb
CHANGED
@@ -1,16 +1,15 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "lstash/cli"
|
3
3
|
|
4
|
-
class Lstash::CLI <
|
4
|
+
class Lstash::CLI < Lstash::CLIBase
|
5
5
|
def self.exit_on_failure?
|
6
6
|
false
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
10
|
describe Lstash::CLI do
|
11
|
-
|
12
11
|
before(:all) do
|
13
|
-
Timecop.freeze(
|
12
|
+
Timecop.freeze("2014-08-01 14:58")
|
14
13
|
end
|
15
14
|
after(:all) do
|
16
15
|
Timecop.return
|
@@ -19,17 +18,16 @@ describe Lstash::CLI do
|
|
19
18
|
context "options" do
|
20
19
|
subject { Lstash::CLI.options(args) }
|
21
20
|
|
22
|
-
let(:args) { %w
|
21
|
+
let(:args) { %w[extract --time from --to to --one --two --three --four] }
|
23
22
|
|
24
23
|
its(:keys) { should eq args }
|
25
24
|
end
|
26
25
|
|
27
26
|
context "count" do
|
28
|
-
|
29
27
|
context "with full URI" do
|
30
|
-
let(:args) { %w
|
28
|
+
let(:args) { %w[count "*" --es-url http://localhost:9200] }
|
31
29
|
it "should succeed" do
|
32
|
-
client = double(
|
30
|
+
client = double("client")
|
33
31
|
|
34
32
|
allow(Lstash::Client).to receive(:new).and_return(client)
|
35
33
|
allow(client).to receive(:count).and_return(1000)
|
@@ -42,10 +40,10 @@ describe Lstash::CLI do
|
|
42
40
|
end
|
43
41
|
|
44
42
|
context "with valid arguments" do
|
45
|
-
let(:args) { %w
|
43
|
+
let(:args) { %w[count "program:haproxy" --es-url localhost] }
|
46
44
|
|
47
45
|
it "should succeed" do
|
48
|
-
client = double(
|
46
|
+
client = double("client")
|
49
47
|
|
50
48
|
allow(Lstash::Client).to receive(:new).and_return(client)
|
51
49
|
allow(client).to receive(:count).and_return(100)
|
@@ -57,7 +55,7 @@ describe Lstash::CLI do
|
|
57
55
|
end
|
58
56
|
|
59
57
|
context "with invalid --es-url" do
|
60
|
-
let(:args) { %w
|
58
|
+
let(:args) { %w[count "program:haproxy" --es-url ''] }
|
61
59
|
|
62
60
|
it "should print error message" do
|
63
61
|
output = capture_stderr { Lstash::CLI.start(args) }
|
@@ -67,7 +65,7 @@ describe Lstash::CLI do
|
|
67
65
|
end
|
68
66
|
|
69
67
|
context "without query" do
|
70
|
-
let(:args) { %w
|
68
|
+
let(:args) { %w[] }
|
71
69
|
it "should print help message" do
|
72
70
|
output = capture_stdout { Lstash::CLI.start(args) }
|
73
71
|
|
@@ -76,35 +74,35 @@ describe Lstash::CLI do
|
|
76
74
|
end
|
77
75
|
|
78
76
|
context "with anchor date" do
|
79
|
-
let(:args) { %w
|
77
|
+
let(:args) { %w[count program:haproxy --from firstday --to today --anchor yesterday --no-wildcard] }
|
80
78
|
|
81
79
|
it "should return correct count" do
|
82
|
-
es_client = double(
|
80
|
+
es_client = double("es_client")
|
83
81
|
|
84
82
|
allow(Elasticsearch::Client).to receive(:new) { es_client }
|
83
|
+
allow_any_instance_of(Lstash::Client).to receive(:validate_shards!).and_return(true)
|
85
84
|
|
86
|
-
expect(es_client).to receive(:count).exactly(31 * 24).times.and_return(count
|
85
|
+
expect(es_client).to receive(:count).exactly(31 * 24).times.and_return("count" => 100)
|
87
86
|
|
88
87
|
output = capture_stdout { Lstash::CLI.start(args) }
|
89
|
-
expect(output).to match(
|
88
|
+
expect(output).to match((31 * 24 * 100).to_s)
|
90
89
|
end
|
91
90
|
end
|
92
91
|
|
93
92
|
context "without anchor date" do
|
94
|
-
let(:args) { %w
|
93
|
+
let(:args) { %w[count program:haproxy --from yesterday --to today --no-wildcard] }
|
95
94
|
|
96
95
|
it "should return correct count" do
|
97
|
-
es_client = double(
|
96
|
+
es_client = double("es_client")
|
98
97
|
|
99
98
|
allow(Elasticsearch::Client).to receive(:new) { es_client }
|
99
|
+
allow_any_instance_of(Lstash::Client).to receive(:validate_shards!).and_return(true)
|
100
100
|
|
101
|
-
expect(es_client).to receive(:count).exactly(24).times.and_return(count
|
101
|
+
expect(es_client).to receive(:count).exactly(24).times.and_return("count" => 100)
|
102
102
|
|
103
103
|
output = capture_stdout { Lstash::CLI.start(args) }
|
104
|
-
expect(output).to match(
|
104
|
+
expect(output).to match((24 * 100).to_s)
|
105
105
|
end
|
106
106
|
end
|
107
|
-
|
108
107
|
end
|
109
|
-
|
110
108
|
end
|
data/spec/lstash/client_spec.rb
CHANGED
@@ -1,30 +1,30 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "spec_helper"
|
2
|
+
require "lstash/client"
|
3
3
|
|
4
4
|
describe Lstash::Client do
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
let(:es_client) { double("es_client") }
|
6
|
+
subject { Lstash::Client.new(es_client, wildcard: false) }
|
7
|
+
before do
|
8
|
+
allow(subject).to receive(:validate_shards!).and_return(true)
|
9
|
+
end
|
8
10
|
|
9
11
|
it "should initialize properly" do
|
10
12
|
expect(subject).not_to be nil
|
11
13
|
end
|
12
14
|
|
13
15
|
context "with query" do
|
14
|
-
|
15
16
|
context "count" do
|
16
17
|
it "should return number of messages matching query" do
|
17
|
-
|
18
|
-
query = Lstash::Query.new("*", from: Time.parse("2014-10-10 00:00"), to: Time.parse("2014-10-10 07:00"))
|
18
|
+
query = Lstash::Query.new("*", from: "2014-10-10 00:00", to: "2014-10-10 07:00")
|
19
19
|
|
20
20
|
allow(es_client).to receive(:count).and_return(
|
21
|
-
{
|
22
|
-
{
|
23
|
-
{
|
24
|
-
{
|
25
|
-
{
|
26
|
-
{
|
27
|
-
{
|
21
|
+
{"count" => 100},
|
22
|
+
{"count" => 200},
|
23
|
+
{"count" => 300},
|
24
|
+
{"count" => 400},
|
25
|
+
{"count" => 500},
|
26
|
+
{"count" => 600},
|
27
|
+
{"count" => 700}
|
28
28
|
)
|
29
29
|
|
30
30
|
expect(subject.count(query)).to eq 2800
|
@@ -33,35 +33,31 @@ describe Lstash::Client do
|
|
33
33
|
|
34
34
|
context "grep" do
|
35
35
|
it "should return the messages matching the query" do
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
hits(%w
|
41
|
-
hits(%w
|
42
|
-
hits(%w
|
43
|
-
hits(%w
|
44
|
-
hits(%w
|
45
|
-
hits(%w
|
46
|
-
hits(%w(7 7 7 7 7 7 7))
|
36
|
+
query = Lstash::Query.new("*", from: "2014-10-10 00:00", to: "2014-10-10 07:00")
|
37
|
+
|
38
|
+
allow(es_client).to receive(:search).and_return(
|
39
|
+
hits(%w[1]),
|
40
|
+
hits(%w[2 2]),
|
41
|
+
hits(%w[3 3 3]),
|
42
|
+
hits(%w[4 4 4 4]),
|
43
|
+
hits(%w[5 5 5 5 5]),
|
44
|
+
hits(%w[6 6 6 6 6 6]),
|
45
|
+
hits(%w[7 7 7 7 7 7 7])
|
47
46
|
)
|
48
47
|
|
49
48
|
allow(es_client).to receive(:scroll).and_return(hits([]))
|
50
49
|
|
51
|
-
|
52
|
-
|
53
|
-
expect(subject.grep(query, 3600)).to eq 28
|
50
|
+
expect(es_client).to receive(:clear_scroll).exactly(7).times
|
51
|
+
expect(subject.grep(query)).to eq 28
|
54
52
|
end
|
55
53
|
end
|
56
|
-
|
57
54
|
end
|
58
55
|
|
59
56
|
def hits(messages)
|
60
57
|
{
|
61
|
-
hits
|
62
|
-
hits
|
58
|
+
"hits" => {
|
59
|
+
"hits" => messages.map { |m| {"_source" => {"message" => m}} }
|
63
60
|
}
|
64
61
|
}
|
65
62
|
end
|
66
|
-
|
67
63
|
end
|