logstash-output-sumologic 1.0.4 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,187 @@
1
+ # encoding: utf-8
2
+ require "logstash/config/mixin"
3
+
4
+ # This module makes it easy to add a very fully configured HTTP client to logstash
5
+ # based on [Manticore](https://github.com/cheald/manticore).
6
+ # For an example of its usage see https://github.com/logstash-plugins/logstash-input-http_poller
7
+ module LogStash::PluginMixins::HttpClient
8
+ class InvalidHTTPConfigError < StandardError; end
9
+
10
+ def self.included(base)
11
+ require 'manticore'
12
+ base.extend(self)
13
+ base.setup_http_client_config
14
+ end
15
+
16
+ public
17
+ def setup_http_client_config
18
+ # Timeout (in seconds) for the entire request
19
+ config :request_timeout, :validate => :number, :default => 60
20
+
21
+ # Timeout (in seconds) to wait for data on the socket. Default is `10s`
22
+ config :socket_timeout, :validate => :number, :default => 10
23
+
24
+ # Timeout (in seconds) to wait for a connection to be established. Default is `10s`
25
+ config :connect_timeout, :validate => :number, :default => 10
26
+
27
+ # Should redirects be followed? Defaults to `true`
28
+ config :follow_redirects, :validate => :boolean, :default => true
29
+
30
+ # Max number of concurrent connections. Defaults to `50`
31
+ config :pool_max, :validate => :number, :default => 50
32
+
33
+ # Max number of concurrent connections to a single host. Defaults to `25`
34
+ config :pool_max_per_route, :validate => :number, :default => 25
35
+
36
+ # Turn this on to enable HTTP keepalive support. We highly recommend setting `automatic_retries` to at least
37
+ # one with this to fix interactions with broken keepalive implementations.
38
+ config :keepalive, :validate => :boolean, :default => true
39
+
40
+ # How many times should the client retry a failing URL. We highly recommend NOT setting this value
41
+ # to zero if keepalive is enabled. Some servers incorrectly end keepalives early requiring a retry!
42
+ # Note: if `retry_non_idempotent` is set only GET, HEAD, PUT, DELETE, OPTIONS, and TRACE requests will be retried.
43
+ config :automatic_retries, :validate => :number, :default => 1
44
+
45
+ # If `automatic_retries` is enabled this will cause non-idempotent HTTP verbs (such as POST) to be retried.
46
+ config :retry_non_idempotent, :validate => :boolean, :default => false
47
+
48
+ # How long to wait before checking if the connection is stale before executing a request on a connection using keepalive.
49
+ # # You may want to set this lower, possibly to 0 if you get connection errors regularly
50
+ # Quoting the Apache commons docs (this client is based Apache Commmons):
51
+ # 'Defines period of inactivity in milliseconds after which persistent connections must be re-validated prior to being leased to the consumer. Non-positive value passed to this method disables connection validation. This check helps detect connections that have become stale (half-closed) while kept inactive in the pool.'
52
+ # See https://hc.apache.org/httpcomponents-client-ga/httpclient/apidocs/org/apache/http/impl/conn/PoolingHttpClientConnectionManager.html#setValidateAfterInactivity(int)[these docs for more info]
53
+ config :validate_after_inactivity, :validate => :number, :default => 200
54
+
55
+ config :ssl_certificate_validation, :deprecated => "This never worked correctly and is now deprecated and a noop"
56
+
57
+ # If you need to use a custom X.509 CA (.pem certs) specify the path to that here
58
+ config :cacert, :validate => :path
59
+
60
+ # If you'd like to use a client certificate (note, most people don't want this) set the path to the x509 cert here
61
+ config :client_cert, :validate => :path
62
+ # If you're using a client certificate specify the path to the encryption key here
63
+ config :client_key, :validate => :path
64
+
65
+ # If you need to use a custom keystore (`.jks`) specify that here. This does not work with .pem keys!
66
+ config :keystore, :validate => :path
67
+
68
+ # Specify the keystore password here.
69
+ # Note, most .jks files created with keytool require a password!
70
+ config :keystore_password, :validate => :password
71
+
72
+ # Specify the keystore type here. One of `JKS` or `PKCS12`. Default is `JKS`
73
+ config :keystore_type, :validate => :string, :default => "JKS"
74
+
75
+ # If you need to use a custom truststore (`.jks`) specify that here. This does not work with .pem certs!
76
+ config :truststore, :validate => :path
77
+
78
+ # Specify the truststore password here.
79
+ # Note, most .jks files created with keytool require a password!
80
+ config :truststore_password, :validate => :password
81
+
82
+ # Specify the truststore type here. One of `JKS` or `PKCS12`. Default is `JKS`
83
+ config :truststore_type, :validate => :string, :default => "JKS"
84
+
85
+ # Enable cookie support. With this enabled the client will persist cookies
86
+ # across requests as a normal web browser would. Enabled by default
87
+ config :cookies, :validate => :boolean, :default => true
88
+
89
+ # If you'd like to use an HTTP proxy . This supports multiple configuration syntaxes:
90
+ #
91
+ # 1. Proxy host in form: `http://proxy.org:1234`
92
+ # 2. Proxy host in form: `{host => "proxy.org", port => 80, scheme => 'http', user => 'username@host', password => 'password'}`
93
+ # 3. Proxy host in form: `{url => 'http://proxy.org:1234', user => 'username@host', password => 'password'}`
94
+ config :proxy
95
+
96
+ # Username to use for HTTP auth.
97
+ config :user, :validate => :string
98
+
99
+ # Password to use for HTTP auth
100
+ config :password, :validate => :password
101
+ end
102
+
103
+ public
104
+ def client_config
105
+ c = {
106
+ connect_timeout: @connect_timeout,
107
+ socket_timeout: @socket_timeout,
108
+ request_timeout: @request_timeout,
109
+ follow_redirects: @follow_redirects,
110
+ automatic_retries: @automatic_retries,
111
+ retry_non_idempotent: @retry_non_idempotent,
112
+ check_connection_timeout: @validate_after_inactivity,
113
+ pool_max: @pool_max,
114
+ pool_max_per_route: @pool_max_per_route,
115
+ cookies: @cookies,
116
+ keepalive: @keepalive
117
+ }
118
+
119
+ if @proxy
120
+ # Symbolize keys if necessary
121
+ c[:proxy] = @proxy.is_a?(Hash) ?
122
+ @proxy.reduce({}) {|memo,(k,v)| memo[k.to_sym] = v; memo} :
123
+ @proxy
124
+ end
125
+
126
+ if @user
127
+ if !@password || !@password.value
128
+ raise ::LogStash::ConfigurationError, "User '#{@user}' specified without password!"
129
+ end
130
+
131
+ # Symbolize keys if necessary
132
+ c[:auth] = {
133
+ :user => @user,
134
+ :password => @password.value,
135
+ :eager => true
136
+ }
137
+ end
138
+
139
+ c[:ssl] = {}
140
+ if @cacert
141
+ c[:ssl][:ca_file] = @cacert
142
+ end
143
+
144
+ if @truststore
145
+ c[:ssl].merge!(
146
+ :truststore => @truststore,
147
+ :truststore_type => @truststore_type,
148
+ :truststore_password => @truststore_password.value
149
+ )
150
+
151
+ if c[:ssl][:truststore_password].nil?
152
+ raise LogStash::ConfigurationError, "Truststore declared without a password! This is not valid, please set the 'truststore_password' option"
153
+ end
154
+ end
155
+
156
+ if @keystore
157
+ c[:ssl].merge!(
158
+ :keystore => @keystore,
159
+ :keystore_type => @keystore_type,
160
+ :keystore_password => @keystore_password.value
161
+ )
162
+
163
+ if c[:ssl][:keystore_password].nil?
164
+ raise LogStash::ConfigurationError, "Keystore declared without a password! This is not valid, please set the 'keystore_password' option"
165
+ end
166
+ end
167
+
168
+ if @client_cert && @client_key
169
+ c[:ssl][:client_cert] = @client_cert
170
+ c[:ssl][:client_key] = @client_key
171
+ elsif !!@client_cert ^ !!@client_key
172
+ raise InvalidHTTPConfigError, "You must specify both client_cert and client_key for an HTTP client, or neither!"
173
+ end
174
+
175
+ c
176
+ end
177
+
178
+ private
179
+ def make_client
180
+ Manticore::Client.new(client_config)
181
+ end
182
+
183
+ public
184
+ def client
185
+ @client ||= make_client
186
+ end
187
+ end
@@ -1,11 +1,11 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "logstash-output-sumologic"
3
- s.version = "1.0.4"
3
+ s.version = "1.1.0"
4
4
  s.licenses = ["Apache-2.0"]
5
5
  s.summary = "Deliever the log to Sumo Logic cloud service."
6
- s.description = "This gem is a Logstash output plugin to deliver the log to Sumo Logic cloud service. Go to https://github.com/SumoLogic/logstash-output-sumologic for getting help, reporting issues, etc."
6
+ s.description = "This gem is a Logstash output plugin to deliver the log or metrics to Sumo Logic cloud service. Go to https://github.com/SumoLogic/logstash-output-sumologic for getting help, reporting issues, etc."
7
7
  s.authors = ["Sumo Logic"]
8
- s.email = "byi@sumologic.com"
8
+ s.email = "collection@sumologic.com "
9
9
  s.homepage = "https://github.com/SumoLogic/logstash-output-sumologic"
10
10
  s.require_paths = ["lib"]
11
11
 
@@ -19,6 +19,6 @@ Gem::Specification.new do |s|
19
19
 
20
20
  # Gem dependencies
21
21
  s.add_runtime_dependency "logstash-core-plugin-api", "~> 2.0"
22
- s.add_runtime_dependency "logstash-codec-plain"
23
- s.add_development_dependency "logstash-devutils"
22
+ s.add_runtime_dependency "logstash-codec-plain", "~> 0"
23
+ s.add_development_dependency "logstash-devutils", "~> 0"
24
24
  end
@@ -1,22 +1,353 @@
1
+
1
2
  # encoding: utf-8
2
3
  require "logstash/devutils/rspec/spec_helper"
3
4
  require "logstash/outputs/sumologic"
4
- require "logstash/codecs/plain"
5
5
  require "logstash/event"
6
6
 
7
+ require_relative '../spec_helper'
8
+
7
9
  describe LogStash::Outputs::SumoLogic do
8
- let(:sample_event) { LogStash::Event.new }
9
- let(:output) { LogStash::Outputs::SumoLogic.new }
10
10
 
11
- before do
12
- output.register
11
+ let(:server) { subject.server }
12
+
13
+ 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
+
13
64
  end
14
65
 
15
- describe "receive message" do
16
- subject { output.receive(sample_event) }
66
+ context "log sent with customized json_mapping" do
67
+
68
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "format" => "%{host} %{@json}", "json_mapping" => { "foo" => "%{foo}", "bar" => "%{bar}", "%{foo}" => "%{bar}" } ) }
69
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
70
+
71
+ it "generate one element" do
72
+ expect(server.size).to eq(1)
73
+ end
17
74
 
18
- it "returns a string" do
19
- expect(subject).to eq("Event received")
75
+ it "include all content" do
76
+ expect(server.pop).to eq("myHost {\"foo\":\"fancy\",\"bar\":\"24\",\"fancy\":\"24\"}")
20
77
  end
78
+
21
79
  end
80
+
81
+ # For headers
82
+ context "check default headers" do
83
+
84
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234") }
85
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
86
+
87
+ it "check header" do
88
+ expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain"})
89
+ end
90
+
91
+ end
92
+
93
+ context "override source_category" do
94
+
95
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "source_category" => "my source category") }
96
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
97
+
98
+ it "check header" do
99
+ expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain", "X-Sumo-Category"=>"my source category"})
100
+ end
101
+
102
+ end
103
+
104
+ context "override source_name" do
105
+
106
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "source_name" => "my source name") }
107
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
108
+
109
+ it "check header" do
110
+ expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain", "X-Sumo-Name"=>"my source name"})
111
+ end
112
+
113
+ end
114
+
115
+ context "override source_host" do
116
+
117
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "source_host" => "my source host") }
118
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
119
+
120
+ it "check header" do
121
+ expect(server.header).to eq({"X-Sumo-Host"=>"my source host", "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain"})
122
+ end
123
+
124
+ end
125
+
126
+ context "with extra_headers" do
127
+
128
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "extra_headers" => {"foo" => "bar"}) }
129
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
130
+
131
+ it "check header" do
132
+ expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain", "foo"=>"bar"})
133
+ end
134
+
135
+ end
136
+
137
+ context "with compress" do
138
+
139
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "compress" => true) }
140
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
141
+
142
+ it "check header" do
143
+ expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain", "Content-Encoding"=>"deflate"})
144
+ end
145
+
146
+ end
147
+
148
+ context "with gzip" do
149
+
150
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "compress" => true, "compress_encoding"=>"gzip") }
151
+ let(:event) { LogStash::Event.new("host" => "myHost", "message" => "Hello world") }
152
+
153
+ it "check header" do
154
+ expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"text/plain", "Content-Encoding"=>"gzip"})
155
+ end
156
+
157
+ end
158
+
159
+ # For metrics
160
+ context "with metrics sent in graphite" do
161
+
162
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "metrics" => { "hurray.%{foo}" => "%{bar}"}, "metrics_format" => "graphite") }
163
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
164
+
165
+ it "generate one element" do
166
+ expect(server.size).to eq(1)
167
+ end
168
+
169
+ it "check header" do
170
+ expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"application/vnd.sumologic.graphite"})
171
+ end
172
+
173
+ it "include all content" do
174
+ expect(server.pop).to match(/^hurray.fancy 24 \d{10,}$/)
175
+ end
176
+
177
+ end
178
+
179
+ context "with metrics sent in carbon2" do
180
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "metrics" => { "hurray.%{foo}" => "%{bar}" }) }
181
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
182
+
183
+ it "generate one element" do
184
+ expect(server.size).to eq(1)
185
+ end
186
+
187
+ it "check header" do
188
+ expect(server.header).to eq({"X-Sumo-Host"=>`hostname`.strip, "X-Sumo-Client"=>"logstash-output-sumologic", "Content-Type"=>"application/vnd.sumologic.carbon2"})
189
+ end
190
+
191
+ it "include all content" do
192
+ expect(server.pop).to match(/^metric=hurray.fancy 24 \d{10,}$/)
193
+ end
194
+ end
195
+
196
+ context "with metrics_name override" do
197
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "metrics" => { "hurray.%{foo}" => "%{bar}" }, "metrics_name" => "mynamespace.*") }
198
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
199
+
200
+ it "include all content" do
201
+ expect(server.pop).to match(/^metric=mynamespace.hurray.fancy 24 \d{10,}$/)
202
+ end
203
+ end
204
+
205
+ context "with intrinsic_tags override" do
206
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "metrics" => { "bar" => "%{bar}" }, "intrinsic_tags" => {"host"=>"%{host}"}) }
207
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
208
+
209
+ it "include all content" do
210
+ expect(server.pop).to match(/^host=myHost metric=bar 24 \d{10,}$/)
211
+ end
212
+ end
213
+
214
+ context "with meta_tags override" do
215
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "metrics" => { "bar" => "%{bar}" }, "intrinsic_tags" => {"host"=>"%{host}"}, "meta_tags" => {"foo" => "%{foo}"}) }
216
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "bar" => 24) }
217
+
218
+ it "include all content" do
219
+ expect(server.pop).to match(/^host=myHost metric=bar foo=fancy 24 \d{10,}$/)
220
+ end
221
+ end
222
+
223
+ context "with multiple metrics mapping" do
224
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "metrics" => { "cpu1" => "%{cpu1}", "cpu2" => "%{cpu2}" }, "intrinsic_tags" => {"host"=>"%{host}"}, "meta_tags" => {"foo" => "%{foo}"}) }
225
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => 0.11) }
226
+
227
+ it "include content" do
228
+ expect(server.pop).to match(/^host=myHost metric=cpu1 foo=fancy 0\.24 \d{10,}$/)
229
+ expect(server.pop).to match(/^host=myHost metric=cpu2 foo=fancy 0\.11 \d{10,}$/)
230
+ end
231
+ end
232
+
233
+ context "metrics with non-number value should be dropped (carbon2)" do
234
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "metrics" => { "cpu1" => "%{cpu1}", "cpu2" => "%{cpu2}", "cpu3" => "%{cpu3}" }, "intrinsic_tags" => {"host"=>"%{host}"}, "meta_tags" => {"foo" => "%{foo}"}) }
235
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => "abc", "cpu3" => 0.11) }
236
+
237
+ it "include content" do
238
+ expect(server.pop).to match(/^host=myHost metric=cpu1 foo=fancy 0\.24 \d{10,}$/)
239
+ expect(server.pop).to match(/^host=myHost metric=cpu3 foo=fancy 0\.11 \d{10,}$/)
240
+ expect(server.empty?).to eq(true)
241
+ end
242
+ end
243
+
244
+ context "metrics with non-number value should be dropped (graphite)" do
245
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "metrics" => { "cpu1" => "%{cpu1}", "cpu2" => "%{cpu2}", "cpu3" => "%{cpu3}" }, "metrics_format" => "graphite") }
246
+ let(:event) { LogStash::Event.new("host" => "myHost", "foo" => "fancy", "cpu1" => 0.24, "cpu2" => "abc", "cpu3" => 0.11) }
247
+
248
+ it "include content" do
249
+ expect(server.pop).to match(/^cpu1 0\.24 \d{10,}$/)
250
+ expect(server.pop).to match(/^cpu3 0\.11 \d{10,}$/)
251
+ expect(server.empty?).to eq(true)
252
+ end
253
+ end
254
+
255
+ context "fields_as_metrics (carbon2)" do
256
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "fields_as_metrics" => true, "intrinsic_tags" => {"host"=>"%{host}"}, "meta_tags" => {"foo" => "%{foo}"}) }
257
+ let(:event) { LogStash::Event.new(
258
+ "host" => "myHost",
259
+ "foo" => "fancy",
260
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
261
+ "storageRW" => 51,
262
+ "bar" => "blahblah",
263
+ "blkio" => {
264
+ "write_ps" => 5,
265
+ "read_ps" => 2,
266
+ "total_ps" => 0
267
+ })}
268
+
269
+ it "include content" do
270
+ expect(server.pop).to match(/^host=myHost metric=blkio\.write_ps foo=fancy 5 \d{10,}$/)
271
+ expect(server.pop).to match(/^host=myHost metric=blkio\.read_ps foo=fancy 2 \d{10,}$/)
272
+ expect(server.pop).to match(/^host=myHost metric=blkio\.total_ps foo=fancy 0 \d{10,}$/)
273
+ expect(server.pop).to match(/^host=myHost metric=cpu\.0 foo=fancy 0\.24 \d{10,}$/)
274
+ expect(server.pop).to match(/^host=myHost metric=cpu\.1 foo=fancy 0\.11 \d{10,}$/)
275
+ expect(server.pop).to match(/^host=myHost metric=cpu\.2 foo=fancy 0\.75 \d{10,}$/)
276
+ expect(server.pop).to match(/^host=myHost metric=cpu\.3 foo=fancy 0\.28 \d{10,}$/)
277
+ expect(server.pop).to match(/^host=myHost metric=storageRW foo=fancy 51 \d{10,}$/)
278
+ expect(server.empty?).to eq(true)
279
+ end
280
+ end
281
+
282
+ context "fields_as_metrics (graphite)" do
283
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "fields_as_metrics" => true, "metrics_format" => "graphite") }
284
+ let(:event) { LogStash::Event.new(
285
+ "host" => "myHost",
286
+ "foo" => "fancy",
287
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
288
+ "storageRW" => 51,
289
+ "bar" => "blahblah",
290
+ "blkio" => {
291
+ "write_ps" => 0,
292
+ "read_ps" => 0,
293
+ "total_ps" => 0
294
+ })}
295
+
296
+ it "include content" do
297
+ expect(server.pop).to match(/^blkio.write_ps 0 \d{10,}$/)
298
+ expect(server.pop).to match(/^blkio.read_ps 0 \d{10,}$/)
299
+ expect(server.pop).to match(/^blkio.total_ps 0 \d{10,}$/)
300
+ expect(server.pop).to match(/^cpu\.0 0\.24 \d{10,}$/)
301
+ expect(server.pop).to match(/^cpu\.1 0\.11 \d{10,}$/)
302
+ expect(server.pop).to match(/^cpu\.2 0\.75 \d{10,}$/)
303
+ expect(server.pop).to match(/^cpu\.3 0\.28 \d{10,}$/)
304
+ expect(server.pop).to match(/^storageRW 51 \d{10,}$/)
305
+ end
306
+ end
307
+
308
+ context "fields_include is honored when fields_as_metrics (carbon2)" do
309
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "fields_as_metrics" => true, "intrinsic_tags" => {"host"=>"%{host}"}, "meta_tags" => {"foo" => "%{foo}"}, "fields_include" => ["cpu*"]) }
310
+ let(:event) { LogStash::Event.new(
311
+ "host" => "myHost",
312
+ "foo" => "fancy",
313
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
314
+ "storageRW" => 51,
315
+ "bar" => "blahblah",
316
+ "blkio" => {
317
+ "write_ps" => 5,
318
+ "read_ps" => 2,
319
+ "total_ps" => 0
320
+ })}
321
+
322
+ it "include content" do
323
+ expect(server.pop).to match(/^host=myHost metric=cpu\.0 foo=fancy 0\.24 \d{10,}$/)
324
+ expect(server.pop).to match(/^host=myHost metric=cpu\.1 foo=fancy 0\.11 \d{10,}$/)
325
+ expect(server.pop).to match(/^host=myHost metric=cpu\.2 foo=fancy 0\.75 \d{10,}$/)
326
+ expect(server.pop).to match(/^host=myHost metric=cpu\.3 foo=fancy 0\.28 \d{10,}$/)
327
+ expect(server.empty?).to eq(true)
328
+ end
329
+ end
330
+
331
+ context "fields_exclude is honored when fields_as_metrics (carbon2)" do
332
+ subject { LogStash::Outputs::SumoLogic.new("url" => "http://localhost/1234", "fields_as_metrics" => true, "intrinsic_tags" => {"host"=>"%{host}"}, "meta_tags" => {"foo" => "%{foo}"}, "fields_include" => ["cpu*"], "fields_exclude" => [".*1"]) }
333
+ let(:event) { LogStash::Event.new(
334
+ "host" => "myHost",
335
+ "foo" => "fancy",
336
+ "cpu" => [0.24, 0.11, 0.75, 0.28],
337
+ "storageRW" => 51,
338
+ "bar" => "blahblah",
339
+ "blkio" => {
340
+ "write_ps" => 5,
341
+ "read_ps" => 2,
342
+ "total_ps" => 0
343
+ })}
344
+
345
+ it "include content" do
346
+ expect(server.pop).to match(/^host=myHost metric=cpu\.0 foo=fancy 0\.24 \d{10,}$/)
347
+ expect(server.pop).to match(/^host=myHost metric=cpu\.2 foo=fancy 0\.75 \d{10,}$/)
348
+ expect(server.pop).to match(/^host=myHost metric=cpu\.3 foo=fancy 0\.28 \d{10,}$/)
349
+ expect(server.empty?).to eq(true)
350
+ end
351
+ end
352
+
22
353
  end