Skip to content

Commit 8592b96

Browse files
authored
Allow to set dimensions for metrics (#57)
1 parent 79d0142 commit 8592b96

File tree

2 files changed

+93
-8
lines changed

2 files changed

+93
-8
lines changed

lib/fluent/plugin/out_sumologic.rb

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,14 @@ def initialize(endpoint, verify_ssl, connect_timeout, proxy_uri, disable_cookies
2424
end
2525
end
2626

27-
def publish(raw_data, source_host=nil, source_category=nil, source_name=nil, data_type, metric_data_type, collected_fields)
28-
response = http.post(@endpoint, compress(raw_data), request_headers(source_host, source_category, source_name, data_type, metric_data_type, collected_fields))
27+
def publish(raw_data, source_host=nil, source_category=nil, source_name=nil, data_type, metric_data_type, collected_fields, dimensions)
28+
response = http.post(@endpoint, compress(raw_data), request_headers(source_host, source_category, source_name, data_type, metric_data_type, collected_fields, dimensions))
2929
unless response.ok?
3030
raise RuntimeError, "Failed to send data to HTTP Source. #{response.code} - #{response.body}"
3131
end
3232
end
3333

34-
def request_headers(source_host, source_category, source_name, data_type, metric_data_format, collected_fields)
34+
def request_headers(source_host, source_category, source_name, data_type, metric_data_format, collected_fields, dimensions)
3535
headers = {
3636
'X-Sumo-Name' => source_name,
3737
'X-Sumo-Category' => source_category,
@@ -54,6 +54,10 @@ def request_headers(source_host, source_category, source_name, data_type, metric
5454
else
5555
raise RuntimeError, "Invalid #{metric_data_format}, must be graphite or carbon2 or prometheus"
5656
end
57+
58+
unless dimensions.nil?
59+
headers['X-Sumo-Dimensions'] = dimensions
60+
end
5761
end
5862
unless collected_fields.nil?
5963
headers['X-Sumo-Fields'] = collected_fields
@@ -127,14 +131,17 @@ class Fluent::Plugin::Sumologic < Fluent::Plugin::Output
127131
config_param :proxy_uri, :string, :default => nil
128132
config_param :disable_cookies, :bool, :default => false
129133
# https://help.sumologic.com/Manage/Fields
130-
desc 'Fields string (eg "cluster=payment, service=credit_card") which is going to be added to every record.'
134+
desc 'Fields string (eg "cluster=payment, service=credit_card") which is going to be added to every log record.'
131135
config_param :custom_fields, :string, :default => nil
132136
desc 'Name of sumo client which is send as X-Sumo-Client header'
133137
config_param :sumo_client, :string, :default => 'fluentd-output'
134138
desc 'Compress payload'
135139
config_param :compress, :bool, :default => false
136140
desc 'Encoding method of compresssion (either gzip or deflate)'
137141
config_param :compress_encoding, :string, :default => SumologicConnection::COMPRESS_GZIP
142+
# https://help.sumologic.com/03Send-Data/Sources/02Sources-for-Hosted-Collectors/HTTP-Source/Upload-Metrics-to-an-HTTP-Source#supported-http-headers
143+
desc 'Dimensions string (eg "cluster=payment, service=credit_card") which is going to be added to every metric record.'
144+
config_param :custom_dimensions, :string, :default => nil
138145

139146
config_section :buffer do
140147
config_set_default :@type, DEFAULT_BUFFER_TYPE
@@ -178,8 +185,14 @@ def configure(conf)
178185
end
179186
end
180187

181-
if conf['custom_fields'].nil? || conf['custom_fields'].strip.length == 0
182-
conf['custom_fields'] = nil
188+
conf['custom_fields'] = validate_key_value_pairs(conf['custom_fields'])
189+
unless conf['custom_fields']
190+
@log.info "Custom fields: #{conf['custom_fields']}"
191+
end
192+
193+
conf['custom_dimensions'] = validate_key_value_pairs(conf['custom_dimensions'])
194+
unless conf['custom_dimensions']
195+
@log.info "Custom dimensions: #{conf['custom_dimensions']}"
183196
end
184197

185198
# For some reason default is set incorrectly in unit-tests
@@ -350,9 +363,26 @@ def write(chunk)
350363
source_name =source_name,
351364
data_type =@data_type,
352365
metric_data_format =@metric_data_format,
353-
collected_fields =fields
366+
collected_fields =fields,
367+
dimensions =@custom_dimensions
354368
)
355369
end
356370

357371
end
372+
373+
def validate_key_value_pairs(fields)
374+
if fields.nil?
375+
return fields
376+
end
377+
378+
fields = fields.split(",").select { |field|
379+
field.split('=').length == 2
380+
}
381+
382+
if fields.length == 0
383+
return nil
384+
end
385+
386+
fields.join(',')
387+
end
358388
end

test/plugin/test_out_sumologic.rb

Lines changed: 56 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -343,7 +343,7 @@ def test_emit_with_sumo_metadata_with_empty_fields_and_custom_fields_fields_form
343343
config = %{
344344
endpoint https://collectors.sumologic.com/v1/receivers/http/1234
345345
log_format fields
346-
custom_fields "lorem=ipsum"
346+
custom_fields "lorem=ipsum,invalid"
347347
}
348348
driver = create_driver(config)
349349
time = event_time
@@ -490,6 +490,61 @@ def test_emit_prometheus
490490
times:1
491491
end
492492

493+
def test_emit_prometheus_with_custom_dimensions
494+
config = %{
495+
endpoint https://collectors.sumologic.com/v1/receivers/http/1234
496+
data_type metrics
497+
metric_data_format prometheus
498+
source_category test
499+
source_host test
500+
source_name test
501+
custom_dimensions 'foo=bar, dolor=sit,amet,test'
502+
}
503+
driver = create_driver(config)
504+
time = event_time
505+
stub_request(:post, 'https://collectors.sumologic.com/v1/receivers/http/1234')
506+
driver.run do
507+
driver.feed("output.test", time, {'message' =>'cpu{cluster="prod", node="lb-1"} 87.2 1501753030'})
508+
end
509+
assert_requested :post, "https://collectors.sumologic.com/v1/receivers/http/1234",
510+
headers: {
511+
'X-Sumo-Category'=>'test',
512+
'X-Sumo-Client'=>'fluentd-output',
513+
'X-Sumo-Host'=>'test',
514+
'X-Sumo-Name'=>'test',
515+
'X-Sumo-Dimensions'=>'foo=bar, dolor=sit',
516+
'Content-Type'=>'application/vnd.sumologic.prometheus'},
517+
body: 'cpu{cluster="prod", node="lb-1"} 87.2 1501753030',
518+
times:1
519+
end
520+
521+
def test_emit_prometheus_with_empty_custom_metadata
522+
config = %{
523+
endpoint https://collectors.sumologic.com/v1/receivers/http/1234
524+
data_type metrics
525+
metric_data_format prometheus
526+
source_category test
527+
source_host test
528+
source_name test
529+
custom_metadata " "
530+
}
531+
driver = create_driver(config)
532+
time = event_time
533+
stub_request(:post, 'https://collectors.sumologic.com/v1/receivers/http/1234')
534+
driver.run do
535+
driver.feed("output.test", time, {'message' =>'cpu{cluster="prod", node="lb-1"} 87.2 1501753030'})
536+
end
537+
assert_requested :post, "https://collectors.sumologic.com/v1/receivers/http/1234",
538+
headers: {
539+
'X-Sumo-Category'=>'test',
540+
'X-Sumo-Client'=>'fluentd-output',
541+
'X-Sumo-Host'=>'test',
542+
'X-Sumo-Name'=>'test',
543+
'Content-Type'=>'application/vnd.sumologic.prometheus'},
544+
body: 'cpu{cluster="prod", node="lb-1"} 87.2 1501753030',
545+
times:1
546+
end
547+
493548
def test_batching_same_headers
494549
config = %{
495550
endpoint https://collectors.sumologic.com/v1/receivers/http/1234

0 commit comments

Comments
 (0)