logstash-output-sumologic 1.1.4 → 1.1.9

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,189 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "logstash/outputs/sumologic"
4
+
5
+ describe LogStash::Outputs::SumoLogic::Piler do
6
+
7
+ before :each do
8
+ piler.start()
9
+ end
10
+
11
+ after :each do
12
+ queue.drain()
13
+ piler.stop()
14
+ end
15
+
16
+ context "working in pile mode if interval > 0 && pile_max > 0" do
17
+ let(:config) { {"queue_max" => 10, "interval" => 10, "pile_max" => 100 } }
18
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
19
+ let(:queue) { LogStash::Outputs::SumoLogic::MessageQueue.new(stats, config) }
20
+ let(:piler) { LogStash::Outputs::SumoLogic::Piler.new(queue, stats, config) }
21
+ specify {
22
+ expect(piler.is_pile).to be true
23
+ }
24
+ end # context
25
+
26
+ context "working in non-pile mode if interval <= 0" do
27
+ let(:config) { {"queue_max" => 10, "interval" => 0, "pile_max" => 100 } }
28
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
29
+ let(:queue) { LogStash::Outputs::SumoLogic::MessageQueue.new(stats, config) }
30
+ let(:piler) { LogStash::Outputs::SumoLogic::Piler.new(queue, stats, config) }
31
+ specify {
32
+ expect(piler.is_pile).to be false
33
+ }
34
+ end # context
35
+
36
+ context "working in non-pile mode if pile_max <= 0" do
37
+ let(:config) { {"queue_max" => 10, "interval" => 10, "pile_max" => 0 } }
38
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
39
+ let(:queue) { LogStash::Outputs::SumoLogic::MessageQueue.new(stats, config) }
40
+ let(:piler) { LogStash::Outputs::SumoLogic::Piler.new(queue, stats, config) }
41
+ specify {
42
+ expect(piler.is_pile).to be false
43
+ }
44
+ end # context
45
+
46
+ context "in non-pile mode" do
47
+
48
+ let(:config) { {"queue_max" => 10, "interval" => 0, "pile_max" => 100 } }
49
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
50
+ let(:queue) { LogStash::Outputs::SumoLogic::MessageQueue.new(stats, config) }
51
+ let(:piler) { LogStash::Outputs::SumoLogic::Piler.new(queue, stats, config) }
52
+
53
+ it "enque immediately after input" do
54
+ expect(stats.current_pile_items.value).to be 0
55
+ expect(stats.current_queue_items.value).to be 0
56
+ piler.input("This is a log line")
57
+ expect(stats.current_pile_items.value).to be 0
58
+ expect(stats.current_queue_items.value).to be 1
59
+ expect(stats.current_queue_bytes.value).to be 18
60
+ end
61
+
62
+ it "deque correctly" do
63
+ expect(stats.current_queue_items.value).to be 0
64
+ expect(stats.total_enque_times.value).to be 0
65
+ piler.input("This is a log line")
66
+ expect(stats.total_enque_times.value).to be 1
67
+ expect(stats.current_queue_items.value).to be 1
68
+ expect(stats.current_queue_bytes.value).to be 18
69
+ expect(stats.total_deque_times.value).to be 0
70
+ expect(queue.deq()).to eq "This is a log line"
71
+ expect(stats.current_queue_items.value).to be 0
72
+ expect(stats.current_queue_bytes.value).to be 0
73
+ expect(stats.total_deque_times.value).to be 1
74
+ end
75
+
76
+ end # context
77
+
78
+ context "in pile mode" do
79
+
80
+ let(:config) { {"queue_max" => 10, "interval" => 5, "pile_max" => 25 } }
81
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
82
+ let(:queue) { LogStash::Outputs::SumoLogic::MessageQueue.new(stats, config) }
83
+ let(:piler) { LogStash::Outputs::SumoLogic::Piler.new(queue, stats, config) }
84
+
85
+ it "wait in pile before size reach pile_max" do
86
+ expect(stats.current_pile_items.value).to be 0
87
+ expect(stats.current_pile_bytes.value).to be 0
88
+ expect(stats.current_queue_items.value).to be 0
89
+ piler.input("1234567890")
90
+ expect(stats.current_pile_items.value).to be 1
91
+ expect(stats.current_pile_bytes.value).to be 10
92
+ expect(stats.current_queue_items.value).to be 0
93
+ piler.input("1234567890")
94
+ expect(stats.current_pile_items.value).to be 2
95
+ expect(stats.current_pile_bytes.value).to be 20
96
+ expect(stats.current_queue_items.value).to be 0
97
+ end
98
+
99
+ it "enqueue content from pile when reach pile_max" do
100
+ expect(stats.current_pile_items.value).to be 0
101
+ expect(stats.current_pile_bytes.value).to be 0
102
+ expect(stats.current_queue_items.value).to be 0
103
+ piler.input("1234567890")
104
+ piler.input("1234567890")
105
+ expect(stats.current_queue_items.value).to be 0
106
+ piler.input("1234567890")
107
+ expect(stats.current_pile_items.value).to be 1
108
+ expect(stats.current_pile_bytes.value).to be 10
109
+ expect(stats.current_queue_items.value).to be 1
110
+ expect(stats.current_queue_bytes.value).to be 21
111
+ end
112
+
113
+ it "enqueue content from pile when reach interval" do
114
+ expect(stats.current_pile_items.value).to be 0
115
+ expect(stats.current_pile_bytes.value).to be 0
116
+ piler.input("1234567890")
117
+ piler.input("1234567890")
118
+ expect(stats.current_queue_items.value).to be 0
119
+ sleep(8)
120
+ expect(stats.current_pile_items.value).to be 0
121
+ expect(stats.current_pile_bytes.value).to be 0
122
+ expect(stats.current_queue_items.value).to be 1
123
+ expect(stats.current_queue_bytes.value).to be 21
124
+ end
125
+
126
+ end # context
127
+
128
+ context "pile to message queue" do
129
+
130
+ let(:config) { {"queue_max" => 5, "interval" => 500, "pile_max" => 5} }
131
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
132
+ let(:queue) { LogStash::Outputs::SumoLogic::MessageQueue.new(stats, config) }
133
+ let(:piler) { LogStash::Outputs::SumoLogic::Piler.new(queue, stats, config) }
134
+
135
+ it "enqueue payloads from pile before reach queue_max" do
136
+ expect(stats.current_queue_items.value).to be 0
137
+ piler.input("1234567890")
138
+ expect(stats.current_queue_items.value).to be 0
139
+ expect(stats.current_queue_bytes.value).to be 0
140
+ piler.input("2234567890")
141
+ expect(stats.current_queue_items.value).to be 1
142
+ expect(stats.current_queue_bytes.value).to be 10
143
+ piler.input("3234567890")
144
+ expect(stats.current_queue_items.value).to be 2
145
+ expect(stats.current_queue_bytes.value).to be 20
146
+ end
147
+
148
+ it "block input thread if queue is full" do
149
+ input_t = Thread.new {
150
+ for i in 0..9 do
151
+ piler.input("#{i}234567890")
152
+ end
153
+ }
154
+ sleep(3)
155
+ expect(stats.current_queue_items.value).to be 5
156
+ expect(stats.current_queue_bytes.value).to be 50
157
+ queue.drain()
158
+ piler.stop()
159
+ input_t.join
160
+ expect(stats.total_deque_times.value).to be 5
161
+ expect(stats.total_deque_bytes.value).to be 50
162
+ end
163
+
164
+ it "resume input thread if queue is drained" do
165
+ input_t = Thread.new {
166
+ for i in 0..9 do
167
+ piler.input("#{i}234567890")
168
+ end
169
+ }
170
+ sleep(3)
171
+ expect(stats.total_deque_times.value).to be 0
172
+ expect(stats.total_enque_times.value).to be 5
173
+ queue.deq()
174
+ sleep(1)
175
+ expect(stats.total_deque_times.value).to be 1
176
+ expect(stats.total_enque_times.value).to be 6
177
+ queue.deq()
178
+ sleep(1)
179
+ expect(stats.total_deque_times.value).to be 2
180
+ expect(stats.total_enque_times.value).to be 7
181
+ queue.drain()
182
+ piler.stop()
183
+ input_t.join
184
+ end
185
+
186
+ end # context
187
+
188
+ end # describe
189
+
@@ -0,0 +1,188 @@
1
+ # encoding: utf-8
2
+ require "logstash/devutils/rspec/spec_helper"
3
+ require "rspec/eventually"
4
+ require "logstash/outputs/sumologic"
5
+
6
+ require_relative "../../test_server.rb"
7
+
8
+ describe LogStash::Outputs::SumoLogic::Sender do
9
+
10
+ before :all do
11
+ @@server = TestServer.new()
12
+ @@server.start()
13
+ end
14
+
15
+ before :each do
16
+ @@server.response = TestServer::RESPONSE_200
17
+ @@server.drain()
18
+ end
19
+
20
+ after :all do
21
+ @@server.stop()
22
+ end
23
+
24
+ context "connect()" do
25
+ let(:stats) { LogStash::Outputs::SumoLogic::Statistics.new() }
26
+ let(:queue) { LogStash::Outputs::SumoLogic::MessageQueue.new(stats, "queue_max" => 10) }
27
+ let(:sender) { LogStash::Outputs::SumoLogic::Sender.new(false, queue, stats, "url" => "http://localhost:#{TestServer::PORT}") }
28
+
29
+ it "should return true if sever response 200" do
30
+ expect(sender.connect()).to be true
31
+ result = @@server.drain()
32
+ expect(result.size).to eq(1)
33
+ end
34
+
35
+ it "should return false if sever response 429" do
36
+ @@server.response = TestServer::RESPONSE_429
37
+ expect(sender.connect()).to be false
38
+ result = @@server.drain()
39
+ expect(result.size).to eq(1)
40
+ end
41
+
42
+ it "should return false if sever cannot reach" do
43
+ sender = LogStash::Outputs::SumoLogic::Sender.new(false, queue, stats, "url" => "http://localhost:#{TestServer::PORT + 1}")
44
+ expect(sender.connect()).to be false
45
+ result = @@server.drain()
46
+ expect(result.size).to eq(0)
47
+ end
48
+
49
+ end # context
50
+
51
+ context "single sender" do
52
+ let(:plugin) { LogStash::Outputs::SumoLogic.new("url" => "http://localhost:#{TestServer::PORT}", "sender_max" => 1, "sleep_before_requeue" => 1, "request_timeout" => 3) }
53
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
54
+
55
+ it "should send message correctly" do
56
+ plugin.register
57
+ plugin.receive(event)
58
+ expect { plugin.stats.total_output_requests.value }.to eventually(eq(1)).pause_for(1)
59
+ expect { plugin.stats.total_response("200") }.to eventually(eq(1)).pause_for(1)
60
+ result = @@server.drain()
61
+ expect(result.size).to eq(2)
62
+ plugin.receive(event)
63
+ expect { plugin.stats.total_output_requests.value }.to eventually(eq(2)).pause_for(1)
64
+ expect { plugin.stats.total_response("200") }.to eventually(eq(2)).pause_for(1)
65
+ result = @@server.drain()
66
+ expect(result.size).to eq(1)
67
+ end
68
+
69
+ it "should re-enque the message if got 429" do
70
+ plugin.register
71
+ plugin.receive(event)
72
+ expect { plugin.stats.total_output_requests.value }.to eventually(eq(1)).pause_for(1)
73
+ expect { plugin.stats.total_response("200") }.to eventually(eq(1)).pause_for(1)
74
+ result = @@server.drain()
75
+ expect(result.size).to eq(2)
76
+ @@server.response = TestServer::RESPONSE_429
77
+ plugin.receive(event)
78
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 1).within(10).pause_for(1)
79
+ expect { plugin.stats.total_response("429") }.to eventually(be > 1).within(10).pause_for(1)
80
+ result = @@server.drain()
81
+ expect(result.size).to be > 0
82
+ @@server.response = TestServer::RESPONSE_200
83
+ expect { plugin.stats.total_response("200") }.to eventually(be > 1).within(10).pause_for(1)
84
+ result = @@server.drain()
85
+ expect(result.size).to be > 0
86
+ end
87
+
88
+ it "should re-enque the message if network failed" do
89
+ plugin.register
90
+ plugin.receive(event)
91
+ expect { plugin.stats.total_output_requests.value }.to eventually(eq(1)).pause_for(1)
92
+ expect { plugin.stats.total_response("200") }.to eventually(eq(1)).pause_for(1)
93
+ result = @@server.drain()
94
+ expect(result.size).to eq(2)
95
+ @@server.stop()
96
+ plugin.receive(event)
97
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 1).within(10).pause_for(1)
98
+ expect { plugin.stats.total_response("failure") }.to eventually(be > 1).within(25).pause_for(1)
99
+ result = @@server.drain()
100
+ @@server.start()
101
+ @@server.response = TestServer::RESPONSE_200
102
+ expect { plugin.stats.total_response("200") }.to eventually(be > 1).within(10).pause_for(1)
103
+ result = @@server.drain()
104
+ expect(result.size).to be > 0
105
+ end
106
+
107
+ end # context
108
+
109
+ context "multiple senders" do
110
+ let(:plugin) { LogStash::Outputs::SumoLogic.new("url" => "http://localhost:#{TestServer::PORT}", "sender_max" => 10, "sleep_before_requeue" => 1, "request_timeout" => 3) }
111
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
112
+
113
+ it "should send message correctly" do
114
+ plugin.register
115
+ plugin.receive(event)
116
+ expect { plugin.stats.total_output_requests.value }.to eventually(eq(1)).pause_for(1)
117
+ expect { plugin.stats.total_response("200") }.to eventually(eq(1)).pause_for(1)
118
+ result = @@server.drain()
119
+ expect(result.size).to eq(2)
120
+ plugin.receive(event)
121
+ expect { plugin.stats.total_output_requests.value }.to eventually(eq(2)).pause_for(1)
122
+ expect { plugin.stats.total_response("200") }.to eventually(eq(2)).pause_for(1)
123
+ result = @@server.drain()
124
+ expect(result.size).to eq(1)
125
+ end
126
+
127
+ it "should re-enque the message if got 429" do
128
+ plugin.register
129
+ plugin.receive(event)
130
+ expect { plugin.stats.total_output_requests.value }.to eventually(eq(1)).pause_for(1)
131
+ expect { plugin.stats.total_response("200") }.to eventually(eq(1)).pause_for(1)
132
+ result = @@server.drain()
133
+ expect(result.size).to eq(2)
134
+ @@server.response = TestServer::RESPONSE_429
135
+ plugin.receive(event)
136
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 1).within(10).pause_for(1)
137
+ expect { plugin.stats.total_response("429") }.to eventually(be > 1).within(10).pause_for(1)
138
+ result = @@server.drain()
139
+ expect(result.size).to be > 0
140
+ @@server.response = TestServer::RESPONSE_200
141
+ expect { plugin.stats.total_response("200") }.to eventually(be > 1).within(10).pause_for(1)
142
+ result = @@server.drain()
143
+ expect(result.size).to be > 0
144
+ end
145
+
146
+ it "should re-enque the message if network failed" do
147
+ plugin.register
148
+ plugin.receive(event)
149
+ expect { plugin.stats.total_output_requests.value }.to eventually(eq(1)).pause_for(1)
150
+ expect { plugin.stats.total_response("200") }.to eventually(eq(1)).pause_for(1)
151
+ result = @@server.drain()
152
+ expect(result.size).to eq(2)
153
+ @@server.stop()
154
+ plugin.receive(event)
155
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 1).within(10).pause_for(1)
156
+ expect { plugin.stats.total_response("failure") }.to eventually(be > 1).within(25).pause_for(1)
157
+ result = @@server.drain()
158
+ @@server.start()
159
+ @@server.response = TestServer::RESPONSE_200
160
+ expect { plugin.stats.total_response("200") }.to eventually(be > 1).within(10).pause_for(1)
161
+ result = @@server.drain()
162
+ expect(result.size).to be > 0
163
+ end
164
+
165
+ it "should reuse tokens" do
166
+ plugin.register
167
+ 30.times { plugin.receive(event) }
168
+ expect { plugin.stats.total_response("200") }.to eventually(eq 30).within(100).pause_for(1)
169
+ end
170
+
171
+ end # context
172
+
173
+ context "close()" do
174
+
175
+ let(:plugin) { LogStash::Outputs::SumoLogic.new("url" => "http://localhost:#{TestServer::PORT}", "sender_max" => 10) }
176
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
177
+
178
+ it "should drain out messages" do
179
+ plugin.register
180
+ 30.times { plugin.receive(event) }
181
+ plugin.close
182
+ expect(plugin.stats.total_response("200")).to eq 30
183
+ end
184
+
185
+ end # context
186
+
187
+ end # describe
188
+
@@ -1,406 +1,230 @@
1
-
2
1
  # encoding: utf-8
3
2
  require "logstash/devutils/rspec/spec_helper"
3
+ require "rspec/eventually"
4
4
  require "logstash/outputs/sumologic"
5
- require "logstash/event"
6
-
7
- require_relative '../spec_helper'
8
5
 
9
- describe LogStash::Outputs::SumoLogic do
6
+ describe LogStash::Outputs::SumoLogic, :unless => (ENV["sumo_url"].to_s.empty?) do
10
7
 
11
- let(:server) { subject.server }
12
-
13
8
  before :each do
14
- subject.register
15
- subject.receive(event)
16
- end
17
-
18
- # For log
19
- context "log sent in default format" do
20
-
21
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234") }
22
- let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
23
-
24
- it "generate one element" do
25
- expect(server.size).to eq(1)
26
- end
27
-
28
- it "include all content" do
29
- expect(server.pop).to include("myHost Hello world")
30
- end
31
-
32
- end
33
-
34
- context "log sent as @json" do
35
-
36
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "format" => "%{@json}") }
37
- let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
38
-
39
- it "generate one element" do
40
- expect(server.size).to eq(1)
41
- end
42
-
43
- it "include all content" do
44
- received = server.pop
45
- expect(received).to include("\"host\":\"myHost\"")
46
- expect(received).to include("\"message\":\"Hello world\"")
47
- end
48
-
49
- end
50
-
51
- context "log sent in customized format" do
52
-
53
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "format" => "%{foo} %{bar}" ) }
54
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
55
-
56
- it "generate one element" do
57
- expect(server.size).to eq(1)
58
- end
59
-
60
- it "include all content" do
61
- expect(server.pop).to eq("fancy 24")
62
- end
63
-
64
- end
65
-
66
- context "log sent with customized json_mapping" do
67
-
68
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
69
- "format" => "%{host} %{@json}",
70
- "json_mapping" => { "foo" => "%{foo}", "bar" => "%{bar}", "%{foo}" => "%{bar}" } ) }
71
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
72
-
73
- it "generate one element" do
74
- expect(server.size).to eq(1)
75
- end
76
-
77
- it "include all content" do
78
- expect(server.pop).to eq("myHost {\"foo\":\"fancy\",\"bar\":\"24\",\"fancy\":\"24\"}")
79
- end
80
-
81
- end
82
-
83
- # For headers
84
- context "check default headers" do
85
-
86
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234") }
87
- let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
88
-
89
- it "check header" do
90
- expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain"})
91
- end
92
-
93
- end
94
-
95
- context "override source_category" do
96
-
97
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "source_category" => "my source category") }
98
- let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
99
-
100
- it "check header" do
101
- expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip,
102
- "X-Sumo-Client"=>"logstash-output-sumologic",
103
- "Content-Type"=>"text/plain",
104
- "X-Sumo-Category"=>"my source category"})
105
- end
106
-
107
- end
108
-
109
- context "override source_name" do
110
-
111
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "source_name" => "my source name") }
112
- let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
113
-
114
- it "check header" do
115
- expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip,
116
- "X-Sumo-Client"=>"logstash-output-sumologic",
117
- "Content-Type"=>"text/plain",
118
- "X-Sumo-Name"=>"my source name"})
119
- end
120
-
121
- end
122
-
123
- context "override source_host" do
124
-
125
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "source_host" => "my source host") }
126
- let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
127
-
128
- it "check header" do
129
- expect(server.header).to eq({"X-Sumo-Host"=>"my source host", "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain"})
130
- end
131
-
132
- end
133
-
134
- context "with extra_headers" do
135
-
136
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "extra_headers" => {"foo" => "bar"}) }
137
- let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
138
-
139
- it "check header" do
140
- expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain", "foo"=>"bar"})
141
- end
142
-
143
- end
144
-
145
- context "with compress" do
146
-
147
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "compress" => true) }
148
- let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
149
-
150
- it "check header" do
151
- expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip,
152
- "X-Sumo-Client"=>"logstash-output-sumologic",
153
- "Content-Type"=>"text/plain",
154
- "Content-Encoding"=>"deflate"})
155
- end
156
-
157
- end
158
-
159
- context "with gzip" do
160
-
161
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "compress" => true, "compress_encoding"=>"gzip") }
162
- let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
163
-
164
- it "check header" do
165
- expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip,
166
- "X-Sumo-Client"=>"logstash-output-sumologic",
167
- "Content-Type"=>"text/plain",
168
- "Content-Encoding"=>"gzip"})
169
- end
170
-
171
- end
172
-
173
- # For metrics
174
- context "with metrics sent in graphite" do
175
-
176
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
177
- "metrics" => { "hurray.%{foo}" => "%{bar}"},
178
- "metrics_format" => "graphite") }
179
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
180
-
181
- it "generate one element" do
182
- expect(server.size).to eq(1)
183
- end
184
-
185
- it "check header" do
186
- expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip,
187
- "X-Sumo-Client"=>"logstash-output-sumologic",
188
- "Content-Type"=>"application/vnd.sumologic.graphite"})
189
- end
190
-
191
- it "include all content" do
192
- expect(server.pop).to match(/^hurray.fancy 24 \d{10,}$/)
193
- end
194
-
195
- end
196
-
197
- context "with metrics sent in carbon2" do
198
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "metrics" => { "hurray.%{foo}" => "%{bar}" }) }
199
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
200
-
201
- it "generate one element" do
202
- expect(server.size).to eq(1)
203
- end
204
-
205
- it "check header" do
206
- expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip,
207
- "X-Sumo-Client"=>"logstash-output-sumologic",
208
- "Content-Type"=>"application/vnd.sumologic.carbon2"})
209
- end
210
-
211
- it "include all content" do
212
- expect(server.pop).to match(/^metric=hurray.fancy 24 \d{10,}$/)
213
- end
214
- end
215
-
216
- context "with metrics_name override" do
217
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
218
- "metrics" => { "hurray.%{foo}" => "%{bar}" },
219
- "metrics_name" => "mynamespace.*") }
220
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
221
-
222
- it "include all content" do
223
- expect(server.pop).to match(/^metric=mynamespace.hurray.fancy 24 \d{10,}$/)
224
- end
225
- end
226
-
227
- context "with intrinsic_tags override" do
228
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
229
- "metrics" => { "bar" => "%{bar}" },
230
- "intrinsic_tags" => {"host"=>"%{host}"}) }
231
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
232
-
233
- it "include all content" do
234
- expect(server.pop).to match(/^host=myHost metric=bar 24 \d{10,}$/)
235
- end
236
- end
237
-
238
- context "with meta_tags override" do
239
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
240
- "metrics" => { "bar" => "%{bar}" },
241
- "intrinsic_tags" => {"host"=>"%{host}"},
242
- "meta_tags" => {"foo" => "%{foo}"}) }
243
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
244
-
245
- it "include all content" do
246
- expect(server.pop).to match(/^host=myHost metric=bar foo=fancy 24 \d{10,}$/)
247
- end
248
- end
249
-
250
- context "with multiple metrics mapping" do
251
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
252
- "metrics" => { "cpu1" => "%{cpu1}", "cpu2" => "%{cpu2}" },
253
- "intrinsic_tags" => {"host"=>"%{host}"},
254
- "meta_tags" => {"foo" => "%{foo}"}) }
255
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => 0.11) }
256
-
257
- it "include content" do
258
- sorted = server.all_sorted
259
- expect(sorted.pop).to match(/^host=myHost metric=cpu1 foo=fancy 0\.24 \d{10,}$/)
260
- expect(sorted.pop).to match(/^host=myHost metric=cpu2 foo=fancy 0\.11 \d{10,}$/)
261
- end
262
- end
263
-
264
- context "metrics with non-number value should be dropped (carbon2)" do
265
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
266
- "metrics" => { "cpu1" => "%{cpu1}", "cpu2" => "%{cpu2}", "cpu3" => "%{cpu3}" },
267
- "intrinsic_tags" => {"host"=>"%{host}"}, "meta_tags" => {"foo" => "%{foo}"}) }
268
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => "abc", "cpu3" => 0.11) }
269
-
270
- it "include content" do
271
- sorted = server.all_sorted
272
- expect(sorted.pop).to match(/^host=myHost metric=cpu1 foo=fancy 0\.24 \d{10,}$/)
273
- expect(sorted.pop).to match(/^host=myHost metric=cpu3 foo=fancy 0\.11 \d{10,}$/)
274
- expect(sorted.empty?).to eq(true)
275
- end
276
- end
277
-
278
- context "metrics with non-number value should be dropped (graphite)" do
279
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
280
- "metrics" => { "cpu1" => "%{cpu1}", "cpu2" => "%{cpu2}", "cpu3" => "%{cpu3}" },
281
- "metrics_format" => "graphite") }
282
- let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => "abc", "cpu3" => 0.11) }
283
-
284
- it "include content" do
285
- sorted = server.all_sorted
286
- expect(sorted.pop).to match(/^cpu1 0\.24 \d{10,}$/)
287
- expect(sorted.pop).to match(/^cpu3 0\.11 \d{10,}$/)
288
- expect(sorted.empty?).to eq(true)
289
- end
290
- end
291
-
292
- context "fields_as_metrics (carbon2)" do
293
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
294
- "fields_as_metrics" => true,
295
- "intrinsic_tags" => {"host"=>"%{host}"},
296
- "meta_tags" => {"foo" => "%{foo}"}) }
297
- let(:event) { LogStash::Event.new(
298
- "host" => "myHost",
299
- "foo" => "fancy",
300
- "cpu" => [0.24, 0.11, 0.75, 0.28],
301
- "storageRW" => 51,
302
- "bar" => "blahblah",
303
- "blkio" => {
304
- "write_ps" => 5,
305
- "read_ps" => 2,
306
- "total_ps" => 0
307
- })}
308
-
309
- it "include content" do
310
- sorted = server.all_sorted
311
- expect(sorted.pop).to match(/^host=myHost metric=blkio\.read_ps foo=fancy 2 \d{10,}$/)
312
- expect(sorted.pop).to match(/^host=myHost metric=blkio\.total_ps foo=fancy 0 \d{10,}$/)
313
- expect(sorted.pop).to match(/^host=myHost metric=blkio\.write_ps foo=fancy 5 \d{10,}$/)
314
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.0 foo=fancy 0\.24 \d{10,}$/)
315
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.1 foo=fancy 0\.11 \d{10,}$/)
316
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.2 foo=fancy 0\.75 \d{10,}$/)
317
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.3 foo=fancy 0\.28 \d{10,}$/)
318
- expect(sorted.pop).to match(/^host=myHost metric=storageRW foo=fancy 51 \d{10,}$/)
319
- expect(sorted.empty?).to eq(true)
320
- end
321
- end
322
-
323
- context "fields_as_metrics (graphite)" do
324
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "fields_as_metrics" => true, "metrics_format" => "graphite") }
325
- let(:event) { LogStash::Event.new(
326
- "host" => "myHost",
327
- "foo" => "fancy",
328
- "cpu" => [0.24, 0.11, 0.75, 0.28],
329
- "storageRW" => 51,
330
- "bar" => "blahblah",
331
- "blkio" => {
332
- "write_ps" => 0,
333
- "read_ps" => 0,
334
- "total_ps" => 0
335
- })}
336
-
337
- it "include content" do
338
- sorted = server.all_sorted
339
- expect(sorted.pop).to match(/^blkio\.read_ps 0 \d{10,}$/)
340
- expect(sorted.pop).to match(/^blkio\.total_ps 0 \d{10,}$/)
341
- expect(sorted.pop).to match(/^blkio\.write_ps 0 \d{10,}$/)
342
- expect(sorted.pop).to match(/^cpu\.0 0\.24 \d{10,}$/)
343
- expect(sorted.pop).to match(/^cpu\.1 0\.11 \d{10,}$/)
344
- expect(sorted.pop).to match(/^cpu\.2 0\.75 \d{10,}$/)
345
- expect(sorted.pop).to match(/^cpu\.3 0\.28 \d{10,}$/)
346
- expect(sorted.pop).to match(/^storageRW 51 \d{10,}$/)
347
- end
348
- end
349
-
350
- context "fields_include is honored when fields_as_metrics (carbon2)" do
351
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
352
- "fields_as_metrics" => true,
353
- "intrinsic_tags" => {"host"=>"%{host}"},
354
- "meta_tags" => {"foo" => "%{foo}"},
355
- "fields_include" => ["cpu*"]) }
356
- let(:event) { LogStash::Event.new(
357
- "host" => "myHost",
358
- "foo" => "fancy",
359
- "cpu" => [0.24, 0.11, 0.75, 0.28],
360
- "storageRW" => 51,
361
- "bar" => "blahblah",
362
- "blkio" => {
363
- "write_ps" => 5,
364
- "read_ps" => 2,
365
- "total_ps" => 0
366
- })}
367
-
368
- it "include content" do
369
- sorted = server.all_sorted
370
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.0 foo=fancy 0\.24 \d{10,}$/)
371
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.1 foo=fancy 0\.11 \d{10,}$/)
372
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.2 foo=fancy 0\.75 \d{10,}$/)
373
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.3 foo=fancy 0\.28 \d{10,}$/)
374
- expect(sorted.empty?).to eq(true)
375
- end
376
- end
377
-
378
- context "fields_exclude is honored when fields_as_metrics (carbon2)" do
379
- subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234",
380
- "fields_as_metrics" => true,
381
- "intrinsic_tags" => {"host"=>"%{host}"},
382
- "meta_tags" => {"foo" => "%{foo}"},
383
- "fields_include" => ["cpu*"],
384
- "fields_exclude" => [".*1"]) }
385
- let(:event) { LogStash::Event.new(
386
- "host" => "myHost",
387
- "foo" => "fancy",
388
- "cpu" => [0.24, 0.11, 0.75, 0.28],
389
- "storageRW" => 51,
390
- "bar" => "blahblah",
391
- "blkio" => {
392
- "write_ps" => 5,
393
- "read_ps" => 2,
394
- "total_ps" => 0
395
- })}
396
-
397
- it "include content" do
398
- sorted = server.all_sorted
399
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.0 foo=fancy 0\.24 \d{10,}$/)
400
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.2 foo=fancy 0\.75 \d{10,}$/)
401
- expect(sorted.pop).to match(/^host=myHost metric=cpu\.3 foo=fancy 0\.28 \d{10,}$/)
402
- expect(sorted.empty?).to eq(true)
403
- end
404
- end
405
-
406
- end
9
+ plugin.register()
10
+ end
11
+
12
+ after :each do
13
+ plugin.close()
14
+ end
15
+
16
+ context "no pile" do
17
+ context "single sender" do
18
+ context "send log in json" do
19
+ let(:plugin) {
20
+ LogStash::Outputs::SumoLogic.new(
21
+ "url" => ENV["sumo_url"],
22
+ "sender_max" => 1,
23
+ "format" => "%{@json}")
24
+ }
25
+ specify {
26
+ event = LogStash::Event.new("host" => "myHost", "message" => "Hello world")
27
+ plugin.receive(event)
28
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 0).within(10).pause_for(1)
29
+ expect { plugin.stats.total_response("200") }.to eventually(be > 0).within(10).pause_for(1)
30
+ }
31
+ end
32
+ context "send fields as metrics" do
33
+ let(:plugin) {
34
+ LogStash::Outputs::SumoLogic.new(
35
+ "url" => ENV["sumo_url"],
36
+ "sender_max" => 1,
37
+ "fields_as_metrics" => true,
38
+ "intrinsic_tags" => {
39
+ "host"=>"%{host}"
40
+ },
41
+ "meta_tags" => {
42
+ "foo" => "%{foo}"
43
+ })
44
+ }
45
+
46
+ specify {
47
+ event = LogStash::Event.new(
48
+ "host" => "myHost",
49
+ "foo" => "fancy",
50
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
51
+ "storageRW" => 51,
52
+ "bar" => "blahblah",
53
+ "blkio" => {
54
+ "write_ps" => 5,
55
+ "read_ps" => 2,
56
+ "total_ps" => 0
57
+ })
58
+
59
+ plugin.receive(event)
60
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 0).within(10).pause_for(1)
61
+ expect { plugin.stats.total_response("200") }.to eventually(be > 0).within(10).pause_for(1)
62
+ }
63
+ end
64
+ end
65
+ context "multiple senders" do
66
+ context "send log in json" do
67
+ let(:plugin) {
68
+ LogStash::Outputs::SumoLogic.new(
69
+ "url" => ENV["sumo_url"],
70
+ "sender_max" => 5,
71
+ "format" => "%{@json}")
72
+ }
73
+
74
+ specify {
75
+ 5.times { |t|
76
+ event = LogStash::Event.new("host" => "myHost", "message" => "Hello world - #{t}")
77
+ plugin.receive(event)
78
+ }
79
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 0).within(10).pause_for(1)
80
+ expect { plugin.stats.total_response("200") }.to eventually(be > 0).within(10).pause_for(1)
81
+ }
82
+ end
83
+
84
+ context "send multiple log in json" do
85
+ let(:plugin) {
86
+ LogStash::Outputs::SumoLogic.new(
87
+ "url" => ENV["sumo_url"],
88
+ "sender_max" => 5,
89
+ "format" => "%{@json}"
90
+ )
91
+ }
92
+
93
+ specify {
94
+ 5.times { |t|
95
+ events = 10.times.map { |r|
96
+ LogStash::Event.new("host" => "myHost", "message" => "Hello world - #{t} - #{r}")
97
+ }
98
+ plugin.multi_receive(events)
99
+ }
100
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 0).within(10).pause_for(1)
101
+ expect { plugin.stats.total_response("200") }.to eventually(be > 0).within(10).pause_for(1)
102
+ }
103
+ end
104
+ end
105
+ end
106
+ context "has pile" do
107
+ context "single sender" do
108
+ context "send log in json" do
109
+ let(:plugin) {
110
+ LogStash::Outputs::SumoLogic.new(
111
+ "url" => ENV["sumo_url"],
112
+ "sender_max" => 1,
113
+ "interval" => 3,
114
+ "format" => "%{@json}")
115
+ }
116
+
117
+ specify {
118
+ 5.times { |t|
119
+ event = LogStash::Event.new("host" => "myHost", "message" => "Hello world - #{t}")
120
+ plugin.receive(event)
121
+ }
122
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 0).within(10).pause_for(1)
123
+ expect { plugin.stats.total_response("200") }.to eventually(be > 0).within(10).pause_for(1)
124
+ }
125
+ end
126
+
127
+ context "send multiple log in json" do
128
+ let(:plugin) {
129
+ LogStash::Outputs::SumoLogic.new(
130
+ "url" => ENV["sumo_url"],
131
+ "sender_max" => 1,
132
+ "interval" => 3,
133
+ "format" => "%{@json}"
134
+ )
135
+ }
136
+
137
+ specify {
138
+ 5.times { |t|
139
+ events = 10.times.map { |r|
140
+ LogStash::Event.new("host" => "myHost", "message" => "Hello world - #{t} - #{r}")
141
+ }
142
+ plugin.multi_receive(events)
143
+ }
144
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 0).within(10).pause_for(1)
145
+ expect { plugin.stats.total_response("200") }.to eventually(be > 0).within(10).pause_for(1)
146
+ }
147
+ end
148
+ end
149
+ context "multi senders" do
150
+ context "send log in json" do
151
+
152
+ let(:plugin) {
153
+ LogStash::Outputs::SumoLogic.new(
154
+ "url" => ENV["sumo_url"],
155
+ "sender_max" => 5,
156
+ "interval" => 3,
157
+ "format" => "%{@json}")
158
+ }
159
+
160
+ specify {
161
+ 5.times { |t|
162
+ event = LogStash::Event.new("host" => "myHost", "message" => "Hello world - #{t}")
163
+ plugin.receive(event)
164
+ }
165
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 0).within(10).pause_for(1)
166
+ expect { plugin.stats.total_response("200") }.to eventually(be > 0).within(10).pause_for(1)
167
+ }
168
+ end
169
+ context "send multiple log in json" do
170
+ let(:plugin) {
171
+ LogStash::Outputs::SumoLogic.new(
172
+ "url" => ENV["sumo_url"],
173
+ "sender_max" => 5,
174
+ "interval" => 3,
175
+ "format" => "%{@json}"
176
+ )
177
+ }
178
+
179
+ specify {
180
+ 5.times { |t|
181
+ events = 10.times.map { |r|
182
+ LogStash::Event.new("host" => "myHost", "message" => "Hello world - #{t} - #{r}")
183
+ }
184
+ plugin.multi_receive(events)
185
+ }
186
+ expect { plugin.stats.total_output_requests.value }.to eventually(be > 0).within(10).pause_for(1)
187
+ expect { plugin.stats.total_response("200") }.to eventually(be > 0).within(10).pause_for(1)
188
+ }
189
+ end
190
+ end
191
+ end
192
+
193
+ @@map = [('a'..'z'), ('A'..'Z')].map(&:to_a).flatten
194
+ def get_line(length)
195
+ length.times.map { @@map[rand(@@map.length)] }.join
196
+ end
197
+
198
+ context "throughput baseline" do
199
+ let(:plugin) {
200
+ LogStash::Outputs::SumoLogic.new(
201
+ "url" => ENV["sumo_url"],
202
+ "source_category" => "logstash_ci_baseline",
203
+ "sender_max" => 100,
204
+ "interval" => 30,
205
+ "format" => "%{@timestamp} %{message}",
206
+ "compress" => true,
207
+ "compress_encoding" => "gzip",
208
+ "stats_enabled" => true,
209
+ "stats_interval" => 1
210
+ )
211
+ }
212
+
213
+ log_length = 5000 + rand(1000)
214
+ log_count = 50000 + rand(10000)
215
+
216
+ specify {
217
+ log_count.times { |t|
218
+ event = LogStash::Event.new("message" => "#{t} - #{get_line(log_length)}")
219
+ plugin.receive(event)
220
+ }
221
+ expect { plugin.stats.total_log_lines.value }.to eventually(be >= log_count).within(60).pause_for(1)
222
+ bytes = plugin.stats.total_output_bytes.value
223
+ spend = (Time.now - plugin.stats.initialize_time) * 1000
224
+ rate = bytes / spend * 1000
225
+ puts "Sent #{plugin.stats.total_log_lines.value} log lines with #{bytes} bytes in #{'%.2f' % spend} ms, rate #{'%.2f' % (rate/1024/1024) } MB/s."
226
+ expect(rate).to be > 2_000_000
227
+ }
228
+ end
229
+
230
+ end # describe