sensu-plugin 2.3.0 → 2.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a61eebfc31a5b1110afdbc0931b0f24fae2be0b6
4
- data.tar.gz: c55bce147df126c8b799f788ccfceeac5b252e53
3
+ metadata.gz: 8747827e125aa55103dc20ba8217bffea6971346
4
+ data.tar.gz: 985836889272cfa6c86511c63c764c6fb1697b53
5
5
  SHA512:
6
- metadata.gz: 25436cf2246717c5c24b9101878d8de2f107198db84744e8f7338445de53b3dc1032af7a2006766d403ac556f7e8cdbfd40f57d619e4dd6c69dd5f9a037c34c6
7
- data.tar.gz: 24e159cf2077552ec1cf46e6e973126b533560ff497a9f0168c66dc4b8f89a1f334f0ccb1d1dd7672032b8bd89a7b18ea94b493c59acf680cc575a508bbda716
6
+ metadata.gz: c044b4e98fae26fb3e04973678d35813a91abfdf5fab1dd379d014e93dace786e43b39d79b9065e33e4054ba4954195e769bd0f31aff8eed3206f24b016a763a
7
+ data.tar.gz: 5b2d6108d52570617b9d1e2143b83e25ee9747f7e937417bfe0f5bbe8882b90b14da2e0476bf3777a15f98dc8d11734d3010ea0b197e9acbcb6dcc759f800044
@@ -1,6 +1,6 @@
1
1
  module Sensu
2
2
  module Plugin
3
- VERSION = '2.3.0'.freeze
3
+ VERSION = '2.4.0'.freeze
4
4
  EXIT_CODES = {
5
5
  'OK' => 0,
6
6
  'WARNING' => 1,
@@ -4,103 +4,195 @@ require 'json'
4
4
  module Sensu
5
5
  module Plugin
6
6
  class Metric
7
- class CLI
8
- class JSON < Sensu::Plugin::CLI
9
- def output(obj = nil)
10
- if obj.is_a?(String) || obj.is_a?(Exception)
11
- puts obj.to_s
12
- elsif obj.is_a?(Hash)
13
- obj['timestamp'] ||= Time.now.to_i
14
- puts ::JSON.generate(obj)
15
- end
7
+ class CLI < Sensu::Plugin::CLI
8
+ # Outputs metrics using raw json format
9
+ #
10
+ # @param obj [Hash] there is no strict expectation from the provided object
11
+ # @return [String] formated metric data
12
+ def to_json(obj = nil)
13
+ if obj.is_a?(String) || obj.is_a?(Exception)
14
+ puts obj.to_s
15
+ elsif obj.is_a?(Hash)
16
+ obj['timestamp'] ||= Time.now.to_i
17
+ puts ::JSON.generate(obj)
16
18
  end
17
19
  end
18
20
 
19
- class Graphite < Sensu::Plugin::CLI
20
- # Outputs metrics using the Statsd datagram format
21
- #
22
- # @param args [Array<String, Int>] list of arguments
23
- # @note the argument order should be:
24
- # `metric_path`: Mandatory, name for the metric,
25
- # `value`: Mandatory, metric value
26
- # `timestamp`: Optional, unix timestamp, defaults to current time
27
- # @return [String] formated metric data
21
+ # Outputs metrics using the Statsd datagram format
22
+ #
23
+ # @param args [Array<String, Int>] list of arguments
24
+ # @note the argument order should be:
25
+ # `metric_path`: Mandatory, name for the metric,
26
+ # `value`: Mandatory, metric value
27
+ # `timestamp`: Optional, unix timestamp, defaults to current time
28
+ # @return [String] formated metric data
29
+ def to_graphite(*args)
30
+ return if args.join.empty?
31
+ if args[0].is_a?(Exception) || args[1].nil?
32
+ puts args[0].to_s
33
+ else
34
+ args[2] ||= Time.now.to_i
35
+ puts args[0..2].join("\s")
36
+ end
37
+ end
38
+
39
+ # Outputs metrics using the Statsd datagram format
40
+ #
41
+ # @param args [Array<String, Int>] list of arguments
42
+ # @note the argument order should be:
43
+ # `metric_name`: Mandatory, name for the metric,
44
+ # `value`: Mandatory, metric value
45
+ # `type`: Optional, metric type- `c` for counter, `g` for gauge, `ms` for timer, `s` for set
46
+ # @return [String] formated metric data
47
+ def to_statsd(*args)
48
+ return if args.join.empty?
49
+ if args[0].is_a?(Exception) || args[1].nil?
50
+ puts args[0].to_s
51
+ else
52
+ type = args[2] || 'kv'
53
+ puts [args[0..1].join(':'), type].join('|')
54
+ end
55
+ end
56
+
57
+ # Outputs metrics using the DogStatsd datagram format
58
+ #
59
+ # @param args [Array<String, Int>] list of arguments
60
+ # @note the argument order should be:
61
+ # `metric_name`: Mandatory, name for the metric,
62
+ # `value`: Mandatory, metric value
63
+ # `type`: Optional, metric type- `c` for counter, `g` for gauge, `ms` for timer, `h` for histogram, `s` for set
64
+ # `tags`: Optional, a comma separated key:value string `tag1:value1,tag2:value2`
65
+ # @return [String] formated metric data
66
+ def to_dogstatsd(*args)
67
+ return if args.join.empty?
68
+ if args[0].is_a?(Exception) || args[1].nil?
69
+ puts args[0].to_s
70
+ else
71
+ type = args[2] || 'kv'
72
+ tags = args[3] ? "##{args[3]}" : nil
73
+ puts [args[0..1].join(':'), type, tags].compact.join('|')
74
+ end
75
+ end
76
+
77
+ # Outputs metrics using the InfluxDB line protocol format
78
+ #
79
+ # @param args [Array<String, Int>] list of arguments
80
+ # @note the argument order should be:
81
+ # `measurement_name`: Mandatory, name for the InfluxDB measurement,
82
+ # `fields`: Mandatory, either an integer or a comma separated key=value string `field1=value1,field2=value2`
83
+ # `tags`: Optional, a comma separated key=value string `tag1=value1,tag2=value2`
84
+ # `timestamp`: Optional, unix timestamp, defaults to current time
85
+ # @return [String] formated metric data
86
+ def to_influxdb(*args)
87
+ return if args.join.empty?
88
+ if args[0].is_a?(Exception) || args[1].nil?
89
+ puts args[0].to_s
90
+ else
91
+ fields = if args[1].is_a?(Integer)
92
+ "value=#{args[1]}"
93
+ else
94
+ args[1]
95
+ end
96
+ measurement = [args[0], args[2]].compact.join(',')
97
+ ts = args[3] || Time.now.to_i
98
+ puts [measurement, fields, ts].join(' ')
99
+ end
100
+ end
101
+
102
+ class JSON < Sensu::Plugin::Metric::CLI
28
103
  def output(*args)
29
- return if args.empty?
30
- if args[0].is_a?(Exception) || args[1].nil?
31
- puts args[0].to_s
32
- else
33
- args[2] ||= Time.now.to_i
34
- puts args[0..2].join("\s")
35
- end
104
+ to_json(*args)
36
105
  end
37
106
  end
38
107
 
39
- class Statsd < Sensu::Plugin::CLI
40
- # Outputs metrics using the Statsd datagram format
41
- #
42
- # @param args [Array<String, Int>] list of arguments
43
- # @note the argument order should be:
44
- # `metric_name`: Mandatory, name for the metric,
45
- # `value`: Mandatory, metric value
46
- # `type`: Optional, metric type- `c` for counter, `g` for gauge, `ms` for timer, `s` for set
47
- # @return [String] formated metric data
108
+ class Graphite < Sensu::Plugin::Metric::CLI
48
109
  def output(*args)
49
- return if args.empty?
50
- if args[0].is_a?(Exception) || args[1].nil?
51
- puts args[0].to_s
52
- else
53
- type = args[2] || 'kv'
54
- puts [args[0..1].join(':'), type].join('|')
55
- end
110
+ to_graphite(*args)
56
111
  end
57
112
  end
58
113
 
59
- class Dogstatsd < Sensu::Plugin::CLI
60
- # Outputs metrics using the DogStatsd datagram format
61
- #
62
- # @param args [Array<String, Int>] list of arguments
63
- # @note the argument order should be:
64
- # `metric_name`: Mandatory, name for the metric,
65
- # `value`: Mandatory, metric value
66
- # `type`: Optional, metric type- `c` for counter, `g` for gauge, `ms` for timer, `h` for histogram, `s` for set
67
- # `tags`: Optional, a comma separated key:value string `tag1:value1,tag2:value2`
68
- # @return [String] formated metric data
114
+ class Statsd < Sensu::Plugin::Metric::CLI
69
115
  def output(*args)
70
- return if args.empty?
71
- if args[0].is_a?(Exception) || args[1].nil?
72
- puts args[0].to_s
73
- else
74
- type = args[2] || 'kv'
75
- tags = args[3] ? "##{args[3]}" : nil
76
- puts [args[0..1].join(':'), type, tags].compact.join('|')
77
- end
116
+ to_statsd(*args)
78
117
  end
79
118
  end
80
119
 
81
- class Influxdb < Sensu::Plugin::CLI
82
- # Outputs metrics using the InfluxDB line protocol format
83
- #
84
- # @param args [Array<String, Int>] list of arguments
85
- # @note the argument order should be:
86
- # `measurement_name`: Mandatory, name for the InfluxDB measurement,
87
- # `fields`: Mandatory, either an integer or a comma separated key=value string `field1=value1,field2=value2`
88
- # `tags`: Optional, a comma separated key=value string `tag1=value1,tag2=value2`
89
- # `timestamp`: Optional, unix timestamp, defaults to current time
90
- # @return [String] formated metric data
120
+ class Dogstatsd < Sensu::Plugin::Metric::CLI
121
+ def output(*args)
122
+ to_dogstatsd(*args)
123
+ end
124
+ end
125
+
126
+ class Influxdb < Sensu::Plugin::Metric::CLI
91
127
  def output(*args)
92
- return if args.empty?
93
- if args[0].is_a?(Exception) || args[1].nil?
94
- puts args[0].to_s
95
- else
96
- fields = if args[1].is_a?(Integer)
97
- "value=#{args[1]}"
98
- else
99
- args[1]
100
- end
101
- measurement = [args[0], args[2]].compact.join(',')
102
- ts = args[3] || Time.now.to_i
103
- puts [measurement, fields, ts].join(' ')
128
+ to_influxdb(*args)
129
+ end
130
+ end
131
+
132
+ class Generic < Sensu::Plugin::Metric::CLI
133
+ option :metric_format,
134
+ long: '--metric_format METRIC_FORMAT',
135
+ in: ['json', 'graphite', 'statsd', 'dogstatsd', 'influxdb'],
136
+ default: 'graphite'
137
+
138
+ # Outputs metrics using different metric formats
139
+ #
140
+ # @param metric [Hash] the metric hash with keys below
141
+ # @note the metric could have these fields:
142
+ # `metric_name`: Mandatory, name for the metric,
143
+ # `value`: Mandatory, metric value
144
+ # `type`: Optional, metric type- `c` for counter, `g` for gauge, `ms` for timer, `h` for histogram, `s` for set
145
+ # `tags`: Optional, a Hash that includes all tags
146
+ # `timestamp`: Optional, unix timestamp, eventually defaults to output's timestamp handling
147
+ # `graphite_metric_path`: Optional, `metric_name` will be used if not provided.
148
+ # `statsd_metric_name`: Optional, `metric_name` will be used if not provided.
149
+ # `statsd_type`: Optional.
150
+ # `dogstatsd_metric_name`: Optional, `statsd_metric_name` or `metric_name` will be used if not provided.
151
+ # `dogstatsd_type`: Optional, `statsd_type` will be used if not provided.
152
+ # `influxdb_measurement`: Optional, class name will be used if not provided.
153
+ # `influxdb_field_key`: Optional, the `metric_name` will be used if not provided.
154
+ # @return [String] formated metric data based on metric_format configuration.
155
+ def output(metric = {})
156
+ return if metric.nil? ||
157
+ metric.empty? ||
158
+ metric[:value].nil?
159
+
160
+ tags = metric[:tags] || []
161
+
162
+ case config[:metric_format]
163
+ when 'json'
164
+ return if metric[:value].nil?
165
+ json_obj = metric[:json_obj] || {
166
+ metric_name: metric[:metric_name],
167
+ value: metric[:value],
168
+ tags: tags
169
+ }
170
+ to_json json_obj
171
+ when 'graphite'
172
+ graphite_metric_path = metric[:graphite_metric_path] ||
173
+ metric[:metric_name]
174
+ to_graphite graphite_metric_path, metric[:value], metric[:timestamp]
175
+ when 'statsd'
176
+ statsd_metric_name = metric[:statsd_metric_name] ||
177
+ metric[:metric_name]
178
+ to_statsd statsd_metric_name, metric[:value], metric[:statsd_type]
179
+ when 'dogstatsd'
180
+ dogstatsd_metric_name = metric[:dogstatsd_metric_name] ||
181
+ metric[:statsd_metric_name] ||
182
+ metric[:metric_name]
183
+ dogstatsd_type = metric[:dogstatsd_type] || metric[:statsd_type]
184
+ dogstatsd_tags = tags.map { |k, v| "#{k}:#{v}" }.join(',')
185
+ to_dogstatsd dogstatsd_metric_name, metric[:value],
186
+ dogstatsd_type, dogstatsd_tags
187
+ when 'influxdb'
188
+ influxdb_measurement = metric[:influxdb_measurement] ||
189
+ self.class.name
190
+ influxdb_field_key = metric[:influxdb_field_key] ||
191
+ metric[:metric_name]
192
+ influxdb_field = "#{influxdb_field_key}=#{metric[:value]}"
193
+ influxdb_tags = tags.map { |k, v| "#{k}=#{v}" }.join(',')
194
+ to_influxdb influxdb_measurement, influxdb_field,
195
+ influxdb_tags, metric[:timestamp]
104
196
  end
105
197
  end
106
198
  end
@@ -1,5 +1,6 @@
1
1
  require 'test_helper'
2
2
  require 'English'
3
+ require 'json'
3
4
 
4
5
  class TestMetricExternal < MiniTest::Test
5
6
  include SensuPluginTestHelper
@@ -81,3 +82,54 @@ class TestInfluxdbMetricExternal < MiniTest::Test
81
82
  end
82
83
  end
83
84
  end
85
+
86
+ class TestGenericMetricsExternal < MiniTest::Test
87
+ include SensuPluginTestHelper
88
+
89
+ def test_json
90
+ set_script 'external/generic-metrics --metric_format json'
91
+ lines = run_script.split("\n")
92
+ assert lines.size == 8
93
+ lines.each { |line| assert line.include? 'metric_name' }
94
+ end
95
+
96
+ def test_graphite
97
+ set_script 'external/generic-metrics --metric_format graphite'
98
+ lines = run_script.split("\n")
99
+ assert lines.size == 8
100
+ assert lines[1].include? 'metric.name 1'
101
+ assert lines[2].include? 'graphite.metric.path 2'
102
+ end
103
+
104
+ def test_statsd
105
+ set_script 'external/generic-metrics --metric_format statsd'
106
+ lines = run_script.split("\n")
107
+ assert lines.size == 8
108
+ assert lines[2].include? 'metric.name:2|kv'
109
+ assert lines[3].include? 'statsd.metric.name:3|s'
110
+ assert lines[4].include? 'metric.name:4|kv'
111
+ assert lines[5].include? 'statsd.metric.name:5|kv'
112
+ end
113
+
114
+ def test_dogstatsd
115
+ set_script 'external/generic-metrics --metric_format dogstatsd'
116
+ lines = run_script.split("\n")
117
+ assert lines.size == 8
118
+ assert lines[1].include? 'metric.name:1|kv|#env:prod,location:us-midwest'
119
+ assert lines[2].include? 'metric.name:2|kv|#'
120
+ assert lines[3].include? 'statsd.metric.name:3|s|#'
121
+ assert lines[4].include? 'statsd.metric.name:4|m|#'
122
+ assert lines[5].include? 'dogstatsd.metric.name:5|kv|#'
123
+ end
124
+
125
+ def test_influxdb
126
+ set_script 'external/generic-metrics --metric_format influxdb'
127
+ lines = run_script.split("\n")
128
+ assert lines.size == 8
129
+ assert lines[0].include? 'GenericTestMetric, metric.name=0 '
130
+ assert lines[1].include? 'GenericTestMetric,env=prod,location=us-midwest metric.name=1 '
131
+ assert lines[2].include? 'GenericTestMetric, metric.name=2 '
132
+ assert lines[6].include? 'influxdb.measurement, metric.name=6 '
133
+ assert lines[7].include? 'GenericTestMetric, influxdb.field=7 '
134
+ end
135
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sensu-plugin
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.3.0
4
+ version: 2.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Decklin Foster
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-08-18 00:00:00.000000000 Z
12
+ date: 2018-02-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -126,7 +126,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
126
126
  version: '0'
127
127
  requirements: []
128
128
  rubyforge_project:
129
- rubygems_version: 2.4.5.1
129
+ rubygems_version: 2.5.2.1
130
130
  signing_key:
131
131
  specification_version: 4
132
132
  summary: Sensu Plugins