chef-handler-datadog 0.3.0 → 0.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.
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