chef-handler-datadog 0.3.0 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (36) hide show
  1. checksums.yaml +8 -8
  2. data/.gitignore +1 -2
  3. data/.rubocop.yml +3 -1
  4. data/.travis.yml +3 -2
  5. data/Appraisals +4 -4
  6. data/CHANGELOG.md +12 -1
  7. data/chef-handler-datadog.gemspec +6 -6
  8. data/gemfiles/chef_10.26.0.gemfile +1 -1
  9. data/gemfiles/chef_10.26.0.gemfile.lock +140 -0
  10. data/gemfiles/chef_10.32.2.gemfile +13 -0
  11. data/gemfiles/chef_10.32.2.gemfile.lock +140 -0
  12. data/gemfiles/{chef_10.14.0.gemfile → chef_11.10.4.gemfile} +2 -2
  13. data/gemfiles/chef_11.10.4.gemfile.lock +143 -0
  14. data/gemfiles/{chef_10.30.2.gemfile → chef_11.12.2.gemfile} +2 -2
  15. data/gemfiles/chef_11.12.2.gemfile.lock +139 -0
  16. data/gemfiles/chef_11.8.2.gemfile +1 -2
  17. data/gemfiles/chef_11.8.2.gemfile.lock +143 -0
  18. data/lib/chef/handler/datadog.rb +102 -79
  19. data/lib/{chef-handler-datadog.rb → chef_handler_datadog.rb} +1 -1
  20. data/spec/datadog_spec.rb +55 -7
  21. data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_alert_handles_when_specified.yml +363 -0
  22. data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_event_title_correctly.yml +25 -60
  23. data/spec/support/cassettes/Chef_Handler_Datadog/failed_Chef_run/sets_priority_correctly.yml +25 -60
  24. data/spec/support/cassettes/Chef_Handler_Datadog/handles_no_application_key/fails_when_no_application_key_is_provided.yml +20 -20
  25. data/spec/support/cassettes/Chef_Handler_Datadog/handles_tags_correctly/sets_the_role_and_env_and_tags.yml +25 -60
  26. data/spec/support/cassettes/Chef_Handler_Datadog/{reports_metrics_event_and_sets_tags/get_and_set_tags/gets_the_tags_for_the_current_node.yml → hostname/uses_the_node_name_when_no_config_specified.yml} +30 -65
  27. data/spec/support/cassettes/Chef_Handler_Datadog/hostname/uses_the_specified_hostname_when_provided.yml +179 -0
  28. data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/does_not_use_the_instance_id_when_config_specified_to_false.yml +23 -58
  29. data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/uses_the_instance_id_when_config_is_specified.yml +23 -58
  30. data/spec/support/cassettes/Chef_Handler_Datadog/reports_correct_hostname_on_an_ec2_node/uses_the_instance_id_when_no_config_specified.yml +23 -58
  31. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_events/posts_an_event.yml +23 -58
  32. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_events/sets_priority_correctly.yml +23 -58
  33. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/emits_metrics/reports_metrics.yml +23 -58
  34. data/spec/support/cassettes/Chef_Handler_Datadog/reports_metrics_event_and_sets_tags/{get_and_set_tags → sets_tags}/puts_the_tags_for_the_current_node.yml +23 -58
  35. data/spec/support/cassettes/Chef_Handler_Datadog/updated_resources/posts_an_event.yml +23 -58
  36. metadata +28 -18
@@ -20,81 +20,31 @@ class Chef
20
20
 
21
21
  def report
22
22
  # resolve correct hostname
23
- hostname = select_hostname(run_status.node)
23
+ hostname = select_hostname(run_status.node, config)
24
24
 
25
25
  # Send the metrics
26
26
  emit_metrics_to_datadog(hostname, run_status)
27
27
 
28
28
  # Build the correct event
29
- event_title = ''
30
- run_time = pluralize(run_status.elapsed_time, 'second')
31
- if run_status.success?
32
- alert_type = 'success'
33
- event_priority = 'low'
34
- event_title << "Chef completed in #{run_time} on #{hostname} "
35
- else
36
- event_title << "Chef failed in #{run_time} on #{hostname} "
37
- end
38
-
39
- event_data = "Chef updated #{run_status.updated_resources.length} resources out of #{run_status.all_resources.length} resources total."
40
-
41
- if run_status.failed?
42
- alert_type = 'error'
43
- event_priority = 'normal'
44
- event_data << "\n@@@\n#{run_status.formatted_exception}\n@@@\n"
45
- event_data << "\n@@@\n#{run_status.backtrace.join("\n")}\n@@@\n"
46
- end
47
-
48
- if run_status.updated_resources.length.to_i > 0
49
- event_data << "\n@@@\n"
50
- run_status.updated_resources.each do |r|
51
- event_data << "- #{r.to_s} (#{r.defined_at})\n"
52
- end
53
- event_data << "\n@@@\n"
54
- end
29
+ event_data = build_event_data(hostname, run_status)
55
30
 
56
31
  # Submit the details back to Datadog
57
32
  begin
58
33
  # Send the Event data
59
- evt = @dog.emit_event(Dogapi::Event.new(event_data,
60
- :msg_title => event_title,
61
- :event_type => 'config_management.run',
62
- :event_object => hostname,
63
- :alert_type => alert_type,
64
- :priority => event_priority,
65
- :source_type_name => 'chef'
66
- ), :host => hostname)
67
-
68
- begin
69
- # FIXME: nice-to-have: abstract format of return value away a bit
70
- # in dogapi directly. See https://github.com/DataDog/dogapi-rb/issues/18
71
- if evt.length < 2
72
- Chef::Log.warn("Unexpected response from Datadog Event API: #{evt}")
73
- else
74
- # [http_response_code, {"event" => {"url" => "...", ...}}]
75
- # 2xx means ok
76
- if evt[0].to_i / 100 != 2
77
- Chef::Log.warn("Could not submit event to Datadog (HTTP call failed): #{evt[0]}")
78
- else
79
- Chef::Log.debug("Successfully submitted Chef event to Datadog for #{hostname} at #{evt[1]['event']['url']}")
80
- end
81
- end
82
- rescue
83
- Chef::Log.warn("Could not determine whether chef run was successfully submitted to Datadog: #{evt}")
84
- end
34
+ emit_event_to_datadog(hostname, event_data)
85
35
 
86
36
  # Update tags
87
37
  if config[:application_key].nil?
88
- Chef::Log.warn("You need an application key to let Chef tag your nodes " \
89
- "in Datadog. Visit https://app.datadoghq.com/account/settings#api to " \
90
- "create one and update your datadog attributes in the datadog cookbook."
38
+ Chef::Log.warn('You need an application key to let Chef tag your nodes ' \
39
+ 'in Datadog. Visit https://app.datadoghq.com/account/settings#api to ' \
40
+ 'create one and update your datadog attributes in the datadog cookbook.'
91
41
  )
92
42
  fail ArgumentError, 'Missing Datadog Application Key'
93
43
  else
94
- new_host_tags = get_combined_tags(hostname, node)
44
+ new_host_tags = get_combined_tags(node)
95
45
 
96
- # Replace all tags with the new tags
97
- rc = @dog.update_tags(hostname, new_host_tags)
46
+ # Replace all Chef tags with the found Chef tags
47
+ rc = @dog.update_tags(hostname, new_host_tags, 'chef')
98
48
  begin
99
49
  # See FIXME above about why I feel dirty repeating this code here
100
50
  if rc.length < 2
@@ -114,7 +64,7 @@ class Chef
114
64
  Chef::Log.error("Could not connect to Datadog. Connection error:\n" + e)
115
65
  Chef::Log.error('Data to be submitted was:')
116
66
  Chef::Log.error(event_title)
117
- Chef::Log.error(event_data)
67
+ Chef::Log.error(event_body)
118
68
  Chef::Log.error('Tags to be set for this run:')
119
69
  Chef::Log.error(new_host_tags)
120
70
  end
@@ -122,6 +72,83 @@ class Chef
122
72
 
123
73
  private
124
74
 
75
+ # Build the Event data for submission
76
+ #
77
+ # @param hostname [String] resolved hostname to attach to Event
78
+ # @param run_status [Chef::RunStatus] current run status
79
+ # @return [Array] alert_type, event_priority, event_title, event_body
80
+ def build_event_data(hostname, run_status)
81
+ run_time = pluralize(run_status.elapsed_time, 'second')
82
+
83
+ # This is the first line of the Event body, the rest is appended here.
84
+ event_body = "Chef updated #{run_status.updated_resources.length} resources out of #{run_status.all_resources.length} resources total."
85
+
86
+ if run_status.success?
87
+ alert_type = 'success'
88
+ event_priority = 'low'
89
+ event_title = "Chef completed in #{run_time} on #{hostname} "
90
+ else
91
+ alert_type = 'error'
92
+ event_priority = 'normal'
93
+ event_title = "Chef failed in #{run_time} on #{hostname} "
94
+
95
+ if @config[:notify_on_failure]
96
+ handles = @config[:notify_on_failure]
97
+ # convert the notification handle array to a string
98
+ event_body << "\nAlerting: #{handles.join(' ')}\n"
99
+ end
100
+
101
+ event_body << "\n@@@\n#{run_status.formatted_exception}\n@@@\n"
102
+ event_body << "\n@@@\n#{run_status.backtrace.join("\n")}\n@@@\n"
103
+ end
104
+
105
+ if run_status.updated_resources.length.to_i > 0
106
+ event_body << "\n@@@\n"
107
+ run_status.updated_resources.each do |r|
108
+ event_body << "- #{r} (#{r.defined_at})\n"
109
+ end
110
+ event_body << "\n@@@\n"
111
+ end
112
+
113
+ # Return resolved data
114
+ [alert_type, event_priority, event_title, event_body]
115
+ end
116
+
117
+ # Emit Event to Datadog Event Stream
118
+ #
119
+ # @param hostname [String] resolved hostname to attach to Event
120
+ # @param event_params [Array] all the configurables to build a valid Event
121
+ def emit_event_to_datadog(hostname, event_data)
122
+ alert_type, event_priority, event_title, event_body = event_data
123
+
124
+ evt = @dog.emit_event(Dogapi::Event.new(event_body,
125
+ :msg_title => event_title,
126
+ :event_type => 'config_management.run',
127
+ :event_object => hostname,
128
+ :alert_type => alert_type,
129
+ :priority => event_priority,
130
+ :source_type_name => 'chef'
131
+ ), :host => hostname)
132
+
133
+ begin
134
+ # FIXME: nice-to-have: abstract format of return value away a bit
135
+ # in dogapi directly. See https://github.com/DataDog/dogapi-rb/issues/18
136
+ if evt.length < 2
137
+ Chef::Log.warn("Unexpected response from Datadog Event API: #{evt}")
138
+ else
139
+ # [http_response_code, {"event" => {"url" => "...", ...}}]
140
+ # 2xx means ok
141
+ if evt[0].to_i / 100 != 2
142
+ Chef::Log.warn("Could not submit event to Datadog (HTTP call failed): #{evt[0]}")
143
+ else
144
+ Chef::Log.debug("Successfully submitted Chef event to Datadog for #{hostname} at #{evt[1]['event']['url']}")
145
+ end
146
+ end
147
+ rescue
148
+ Chef::Log.warn("Could not determine whether chef run was successfully submitted to Datadog: #{evt}")
149
+ end
150
+ end
151
+
125
152
  # Emit Chef metrics to Datadog
126
153
  #
127
154
  # @param hostname [String] resolved hostname to attach to series
@@ -135,28 +162,21 @@ class Chef
135
162
  Chef::Log.error("Could not send metrics to Datadog. Connection error:\n" + e)
136
163
  end
137
164
 
138
- # Call Datadog API for a given hostname and retrieve the current list
139
- # of Datadog tags - not the same as Chef 'tags' - rather all tags in
140
- # are `key:value` e.g. `role:database-master`.
141
- # Build up an array of Datadog tags to send back
165
+ # Build up an array of Chef tags to send back
142
166
  #
143
- # @param hostname [String]
144
- # @return [Array] an array of current Datadog tags, roles, env
145
- def get_combined_tags(hostname, node)
146
- host_tags = get_host_tags(hostname)
147
- host_tags << get_node_env(node)
167
+ # Selects all [env, roles, tags] from the Node's object and reformats
168
+ # them to `key:value` e.g. `role:database-master`.
169
+ #
170
+ # @param node [Chef::Node]
171
+ # @return [Array] current Chef env, roles, tags
172
+ def get_combined_tags(node)
173
+ chef_env = get_node_env(node).split # converts a string into an array
148
174
 
149
175
  chef_roles = get_node_roles(node)
150
176
  chef_tags = get_node_tags(node)
151
177
 
152
- # Combine (union) all arrays. Removes dupes, preserves non-Chef tags.
153
- host_tags | chef_roles | chef_tags
154
- end
155
-
156
- # Get current tags, drop any that will be replaced
157
- def get_host_tags(hostname)
158
- tags = @dog.host_tags(hostname)[1]['tags'] || []
159
- tags.delete_if { |tag| tag.start_with?('role:', 'env:', 'tag:') }
178
+ # Combine (union) all arrays. Removes duplicates if found.
179
+ chef_env | chef_roles | chef_tags
160
180
  end
161
181
 
162
182
  def get_node_roles(node)
@@ -188,13 +208,16 @@ class Chef
188
208
  # node's `ec2` attribute existence to make the decision.
189
209
  #
190
210
  # @param node [Chef::Node] from `run_status`, can feasibly any `node`
211
+ # @param config [Hash] config object passed in to handler
191
212
  # @return [String] the hostname decided upon
192
- def select_hostname(node)
213
+ def select_hostname(node, config)
193
214
  use_ec2_instance_id = !config.key?(:use_ec2_instance_id) ||
194
215
  (config.key?(:use_ec2_instance_id) &&
195
216
  config[:use_ec2_instance_id])
196
217
 
197
- if use_ec2_instance_id && node.attribute?('ec2') && node.ec2.attribute?('instance_id')
218
+ if config[:hostname]
219
+ config[:hostname]
220
+ elsif use_ec2_instance_id && node.attribute?('ec2') && node.ec2.attribute?('instance_id')
198
221
  node.ec2.instance_id
199
222
  else
200
223
  node.name
@@ -2,5 +2,5 @@
2
2
  # Helper module for version number only.
3
3
  # Real deal in 'chef/handler/datadog.rb'
4
4
  module ChefHandlerDatadog
5
- VERSION = '0.3.0'
5
+ VERSION = '0.4.0'
6
6
  end
data/spec/datadog_spec.rb CHANGED
@@ -68,18 +68,19 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
68
68
  end
69
69
  end
70
70
 
71
- context 'get and set tags' do
72
- it 'gets the tags for the current node' do
71
+ context 'sets tags' do
72
+ it 'puts the tags for the current node' do
73
+ # We no longer need to query the tag api for current tags,
74
+ # rather udpate only the tags for the designated source type
73
75
  expect(a_request(:get, HOST_TAG_ENDPOINT + @node.name).with(
74
76
  :query => { 'api_key' => @handler.config[:api_key],
75
77
  'application_key' => @handler.config[:application_key] },
76
- )).to have_been_made.times(1)
77
- end
78
+ )).to have_been_made.times(0)
78
79
 
79
- it 'puts the tags for the current node' do
80
80
  expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
81
81
  :query => { 'api_key' => @handler.config[:api_key],
82
- 'application_key' => @handler.config[:application_key] },
82
+ 'application_key' => @handler.config[:application_key],
83
+ 'source' => 'chef' },
83
84
  :body => { 'tags' => ['env:testing'] },
84
85
  )).to have_been_made.times(1)
85
86
  end
@@ -135,6 +136,42 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
135
136
  end
136
137
  end
137
138
 
139
+ context 'hostname' do
140
+ before(:each) do
141
+ @node = Chef::Node.build('chef.handler.datadog.test-hostname')
142
+ @node.send(:chef_environment, 'testing')
143
+
144
+ @run_context = Chef::RunContext.new(@node, {}, @events)
145
+ @run_status = Chef::RunStatus.new(@node, @events)
146
+ @expected_time = Time.now
147
+ Time.stub(:now).and_return(@expected_time, @expected_time + 5)
148
+ @run_status.start_clock
149
+ @run_status.stop_clock
150
+ @run_status.run_context = @run_context
151
+ end
152
+
153
+ it 'uses the node.name when no config specified' do
154
+ @handler.run_report_unsafe(@run_status)
155
+
156
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
157
+ :query => { 'api_key' => @handler.config[:api_key] },
158
+ :body => hash_including(:msg_title => "Chef completed in 5 seconds on #{@node.name}"),
159
+ :body => hash_including(:host => @node.name),
160
+ )).to have_been_made.times(1)
161
+ end
162
+
163
+ it 'uses the specified hostname when provided' do
164
+ @handler.config[:hostname] = 'my-imaginary-hostname.local'
165
+ @handler.run_report_unsafe(@run_status)
166
+
167
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
168
+ :query => { 'api_key' => @handler.config[:api_key] },
169
+ :body => hash_including(:msg_title => 'Chef completed in 5 seconds on my-imaginary-hostname.local'),
170
+ :body => hash_including(:host => 'my-imaginary-hostname.local'),
171
+ )).to have_been_made.times(1)
172
+ end
173
+ end
174
+
138
175
  describe 'handles tags correctly' do
139
176
  before(:each) do
140
177
  @node = Chef::Node.build('chef.handler.datadog.test-tags')
@@ -161,7 +198,8 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
161
198
  it 'sets the role and env and tags' do
162
199
  expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
163
200
  :query => { 'api_key' => @handler.config[:api_key],
164
- 'application_key' => @handler.config[:application_key] },
201
+ 'application_key' => @handler.config[:application_key],
202
+ 'source' => 'chef' },
165
203
  :body => hash_including(:tags => [
166
204
  'env:hostile', 'role:highlander', 'tag:the_one_and_only'
167
205
  ]),
@@ -240,6 +278,16 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
240
278
  :body => hash_including(:priority => 'normal'),
241
279
  )).to have_been_made.times(1)
242
280
  end
281
+
282
+ it 'sets alert handles when specified' do
283
+ @handler.config[:notify_on_failure] = ['@alice', '@bob']
284
+ @handler.run_report_unsafe(@run_status)
285
+
286
+ expect(a_request(:post, EVENTS_ENDPOINT).with(
287
+ :query => { 'api_key' => @handler.config[:api_key] },
288
+ :body => /Alerting: @alice @bob/
289
+ )).to have_been_made.times(1)
290
+ end
243
291
  end
244
292
 
245
293
  describe 'updated resources' do
@@ -0,0 +1,363 @@
1
+ ---
2
+ http_interactions:
3
+ - request:
4
+ method: post
5
+ uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
6
+ body:
7
+ encoding: UTF-8
8
+ string: ! '{"series":[{"metric":"chef.resources.total","points":[[1398187132,0.0]],"type":"gauge","host":"chef.handler.datadog.test-failed","device":null}]}'
9
+ headers:
10
+ Accept:
11
+ - ! '*/*'
12
+ User-Agent:
13
+ - Ruby
14
+ Content-Type:
15
+ - application/json
16
+ response:
17
+ status:
18
+ code: 202
19
+ message: Accepted
20
+ headers:
21
+ Content-Type:
22
+ - text/json; charset=UTF-8
23
+ Date:
24
+ - Tue, 22 Apr 2014 17:18:52 GMT
25
+ Server:
26
+ - dogdispatcher/4.12.1
27
+ Content-Length:
28
+ - '15'
29
+ Connection:
30
+ - keep-alive
31
+ body:
32
+ encoding: US-ASCII
33
+ string: ! '{"status":"ok"}'
34
+ http_version:
35
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
36
+ - request:
37
+ method: post
38
+ uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
39
+ body:
40
+ encoding: UTF-8
41
+ string: ! '{"series":[{"metric":"chef.resources.updated","points":[[1398187132,0.0]],"type":"gauge","host":"chef.handler.datadog.test-failed","device":null}]}'
42
+ headers:
43
+ Accept:
44
+ - ! '*/*'
45
+ User-Agent:
46
+ - Ruby
47
+ Content-Type:
48
+ - application/json
49
+ response:
50
+ status:
51
+ code: 202
52
+ message: Accepted
53
+ headers:
54
+ Content-Type:
55
+ - text/json; charset=UTF-8
56
+ Date:
57
+ - Tue, 22 Apr 2014 17:18:53 GMT
58
+ Server:
59
+ - dogdispatcher/4.12.1
60
+ Content-Length:
61
+ - '15'
62
+ Connection:
63
+ - keep-alive
64
+ body:
65
+ encoding: US-ASCII
66
+ string: ! '{"status":"ok"}'
67
+ http_version:
68
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
69
+ - request:
70
+ method: post
71
+ uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
72
+ body:
73
+ encoding: UTF-8
74
+ string: ! '{"series":[{"metric":"chef.resources.elapsed_time","points":[[1398187132,2.0]],"type":"gauge","host":"chef.handler.datadog.test-failed","device":null}]}'
75
+ headers:
76
+ Accept:
77
+ - ! '*/*'
78
+ User-Agent:
79
+ - Ruby
80
+ Content-Type:
81
+ - application/json
82
+ response:
83
+ status:
84
+ code: 202
85
+ message: Accepted
86
+ headers:
87
+ Content-Type:
88
+ - text/json; charset=UTF-8
89
+ Date:
90
+ - Tue, 22 Apr 2014 17:18:54 GMT
91
+ Server:
92
+ - dogdispatcher/4.12.1
93
+ Content-Length:
94
+ - '15'
95
+ Connection:
96
+ - keep-alive
97
+ body:
98
+ encoding: US-ASCII
99
+ string: ! '{"status":"ok"}'
100
+ http_version:
101
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
102
+ - request:
103
+ method: post
104
+ uri: https://app.datadoghq.com/api/v1/events?api_key=<API_KEY>
105
+ body:
106
+ encoding: UTF-8
107
+ string: ! '{"msg_text":"Chef updated 0 resources out of 0 resources total.\n@@@\nChef::Exceptions::UnsupportedAction:
108
+ Something awry.\n@@@\n\n@@@\nfile.rb:2\nfile.rb:1\n@@@\n","date_happened":1398187132,"msg_title":"Chef
109
+ failed in 2 seconds on chef.handler.datadog.test-failed ","priority":"normal","parent":null,"tags":[],"aggregation_key":"chef.handler.datadog.test-failed","alert_type":"error","event_type":"config_management.run","source_type_name":"chef","title":"Chef
110
+ failed in 2 seconds on chef.handler.datadog.test-failed ","text":"Chef updated
111
+ 0 resources out of 0 resources total.\n@@@\nChef::Exceptions::UnsupportedAction:
112
+ Something awry.\n@@@\n\n@@@\nfile.rb:2\nfile.rb:1\n@@@\n","host":"chef.handler.datadog.test-failed","device":null}'
113
+ headers:
114
+ Accept:
115
+ - ! '*/*'
116
+ User-Agent:
117
+ - Ruby
118
+ Content-Type:
119
+ - application/json
120
+ response:
121
+ status:
122
+ code: 202
123
+ message: Accepted
124
+ headers:
125
+ Content-Type:
126
+ - text/json; charset=UTF-8
127
+ Date:
128
+ - Tue, 22 Apr 2014 17:18:55 GMT
129
+ Server:
130
+ - dogdispatcher/4.12.1
131
+ Content-Length:
132
+ - '474'
133
+ Connection:
134
+ - keep-alive
135
+ body:
136
+ encoding: US-ASCII
137
+ string: ! '{"status": "ok", "event": {"priority": "normal", "date_happened":
138
+ 1398187132, "handle": null, "title": "Chef failed in 2 seconds on chef.handler.datadog.test-failed
139
+ ", "url": "https://app.datadoghq.com/event/jump_to?event_id=2246876398487094962",
140
+ "text": "Chef updated 0 resources out of 0 resources total.\n@@@\nChef::Exceptions::UnsupportedAction:
141
+ Something awry.\n@@@\n\n@@@\nfile.rb:2\nfile.rb:1\n@@@\n", "tags": [], "related_event_id":
142
+ null, "id": 2246876398487094962}}'
143
+ http_version:
144
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
145
+ - request:
146
+ method: put
147
+ uri: https://app.datadoghq.com/api/v1/tags/hosts/chef.handler.datadog.test-failed?api_key=<API_KEY>&application_key=<APPLICATION_KEY>&source=chef
148
+ body:
149
+ encoding: UTF-8
150
+ string: ! '{"tags":["env:hostile","role:highlander","tag:the_one_and_only"]}'
151
+ headers:
152
+ Accept:
153
+ - ! '*/*'
154
+ User-Agent:
155
+ - Ruby
156
+ Content-Type:
157
+ - application/json
158
+ response:
159
+ status:
160
+ code: 201
161
+ message: Created
162
+ headers:
163
+ Cache-Control:
164
+ - no-cache
165
+ Content-Type:
166
+ - application/json
167
+ Date:
168
+ - Tue, 22 Apr 2014 17:18:56 GMT
169
+ Pragma:
170
+ - no-cache
171
+ Server:
172
+ - gunicorn/0.17.4
173
+ Content-Length:
174
+ - '112'
175
+ Connection:
176
+ - keep-alive
177
+ body:
178
+ encoding: US-ASCII
179
+ string: ! '{"host": "chef.handler.datadog.test-failed", "tags": ["env:hostile",
180
+ "role:highlander", "tag:the_one_and_only"]}'
181
+ http_version:
182
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
183
+ - request:
184
+ method: post
185
+ uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
186
+ body:
187
+ encoding: UTF-8
188
+ string: ! '{"series":[{"metric":"chef.resources.total","points":[[1398187132,0.0]],"type":"gauge","host":"chef.handler.datadog.test-failed","device":null}]}'
189
+ headers:
190
+ Accept:
191
+ - ! '*/*'
192
+ User-Agent:
193
+ - Ruby
194
+ Content-Type:
195
+ - application/json
196
+ response:
197
+ status:
198
+ code: 202
199
+ message: Accepted
200
+ headers:
201
+ Content-Type:
202
+ - text/json; charset=UTF-8
203
+ Date:
204
+ - Tue, 22 Apr 2014 17:18:58 GMT
205
+ Server:
206
+ - dogdispatcher/4.12.1
207
+ Content-Length:
208
+ - '15'
209
+ Connection:
210
+ - keep-alive
211
+ body:
212
+ encoding: US-ASCII
213
+ string: ! '{"status":"ok"}'
214
+ http_version:
215
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
216
+ - request:
217
+ method: post
218
+ uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
219
+ body:
220
+ encoding: UTF-8
221
+ string: ! '{"series":[{"metric":"chef.resources.updated","points":[[1398187132,0.0]],"type":"gauge","host":"chef.handler.datadog.test-failed","device":null}]}'
222
+ headers:
223
+ Accept:
224
+ - ! '*/*'
225
+ User-Agent:
226
+ - Ruby
227
+ Content-Type:
228
+ - application/json
229
+ response:
230
+ status:
231
+ code: 202
232
+ message: Accepted
233
+ headers:
234
+ Content-Type:
235
+ - text/json; charset=UTF-8
236
+ Date:
237
+ - Tue, 22 Apr 2014 17:18:59 GMT
238
+ Server:
239
+ - dogdispatcher/4.12.1
240
+ Content-Length:
241
+ - '15'
242
+ Connection:
243
+ - keep-alive
244
+ body:
245
+ encoding: US-ASCII
246
+ string: ! '{"status":"ok"}'
247
+ http_version:
248
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
249
+ - request:
250
+ method: post
251
+ uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
252
+ body:
253
+ encoding: UTF-8
254
+ string: ! '{"series":[{"metric":"chef.resources.elapsed_time","points":[[1398187132,2.0]],"type":"gauge","host":"chef.handler.datadog.test-failed","device":null}]}'
255
+ headers:
256
+ Accept:
257
+ - ! '*/*'
258
+ User-Agent:
259
+ - Ruby
260
+ Content-Type:
261
+ - application/json
262
+ response:
263
+ status:
264
+ code: 202
265
+ message: Accepted
266
+ headers:
267
+ Content-Type:
268
+ - text/json; charset=UTF-8
269
+ Date:
270
+ - Tue, 22 Apr 2014 17:19:00 GMT
271
+ Server:
272
+ - dogdispatcher/4.12.1
273
+ Content-Length:
274
+ - '15'
275
+ Connection:
276
+ - keep-alive
277
+ body:
278
+ encoding: US-ASCII
279
+ string: ! '{"status":"ok"}'
280
+ http_version:
281
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
282
+ - request:
283
+ method: post
284
+ uri: https://app.datadoghq.com/api/v1/events?api_key=<API_KEY>
285
+ body:
286
+ encoding: UTF-8
287
+ string: ! '{"msg_text":"Chef updated 0 resources out of 0 resources total.\nAlerting:
288
+ @alice @bob\n\n@@@\nChef::Exceptions::UnsupportedAction: Something awry.\n@@@\n\n@@@\nfile.rb:2\nfile.rb:1\n@@@\n","date_happened":1398187132,"msg_title":"Chef
289
+ failed in 2 seconds on chef.handler.datadog.test-failed ","priority":"normal","parent":null,"tags":[],"aggregation_key":"chef.handler.datadog.test-failed","alert_type":"error","event_type":"config_management.run","source_type_name":"chef","title":"Chef
290
+ failed in 2 seconds on chef.handler.datadog.test-failed ","text":"Chef updated
291
+ 0 resources out of 0 resources total.\nAlerting: @alice @bob\n\n@@@\nChef::Exceptions::UnsupportedAction:
292
+ Something awry.\n@@@\n\n@@@\nfile.rb:2\nfile.rb:1\n@@@\n","host":"chef.handler.datadog.test-failed","device":null}'
293
+ headers:
294
+ Accept:
295
+ - ! '*/*'
296
+ User-Agent:
297
+ - Ruby
298
+ Content-Type:
299
+ - application/json
300
+ response:
301
+ status:
302
+ code: 202
303
+ message: Accepted
304
+ headers:
305
+ Content-Type:
306
+ - text/json; charset=UTF-8
307
+ Date:
308
+ - Tue, 22 Apr 2014 17:19:01 GMT
309
+ Server:
310
+ - dogdispatcher/4.12.1
311
+ Content-Length:
312
+ - '499'
313
+ Connection:
314
+ - keep-alive
315
+ body:
316
+ encoding: US-ASCII
317
+ string: ! '{"status": "ok", "event": {"priority": "normal", "date_happened":
318
+ 1398187132, "handle": null, "title": "Chef failed in 2 seconds on chef.handler.datadog.test-failed
319
+ ", "url": "https://app.datadoghq.com/event/jump_to?event_id=2246876504015312374",
320
+ "text": "Chef updated 0 resources out of 0 resources total.\nAlerting: @alice
321
+ @bob\n\n@@@\nChef::Exceptions::UnsupportedAction: Something awry.\n@@@\n\n@@@\nfile.rb:2\nfile.rb:1\n@@@\n",
322
+ "tags": [], "related_event_id": null, "id": 2246876504015312374}}'
323
+ http_version:
324
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
325
+ - request:
326
+ method: put
327
+ uri: https://app.datadoghq.com/api/v1/tags/hosts/chef.handler.datadog.test-failed?api_key=<API_KEY>&application_key=<APPLICATION_KEY>&source=chef
328
+ body:
329
+ encoding: UTF-8
330
+ string: ! '{"tags":["env:hostile","role:highlander","tag:tag:the_one_and_only"]}'
331
+ headers:
332
+ Accept:
333
+ - ! '*/*'
334
+ User-Agent:
335
+ - Ruby
336
+ Content-Type:
337
+ - application/json
338
+ response:
339
+ status:
340
+ code: 201
341
+ message: Created
342
+ headers:
343
+ Cache-Control:
344
+ - no-cache
345
+ Content-Type:
346
+ - application/json
347
+ Date:
348
+ - Tue, 22 Apr 2014 17:19:03 GMT
349
+ Pragma:
350
+ - no-cache
351
+ Server:
352
+ - gunicorn/0.17.4
353
+ Content-Length:
354
+ - '116'
355
+ Connection:
356
+ - keep-alive
357
+ body:
358
+ encoding: US-ASCII
359
+ string: ! '{"host": "chef.handler.datadog.test-failed", "tags": ["tag:tag:the_one_and_only",
360
+ "env:hostile", "role:highlander"]}'
361
+ http_version:
362
+ recorded_at: Tue, 22 Apr 2014 17:18:52 GMT
363
+ recorded_with: VCR 2.9.0