chef-handler-datadog 0.6.0 → 0.7.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 +5 -13
- data/.rubocop.yml +19 -17
- data/.travis.yml +16 -11
- data/Appraisals +9 -20
- data/CHANGELOG.md +13 -0
- data/README.md +12 -0
- data/Rakefile +1 -2
- data/chef-handler-datadog.gemspec +6 -6
- data/gemfiles/{chef_10.26.0.gemfile → chef_10.14.4.gemfile} +2 -2
- data/gemfiles/{chef_11.14.2.gemfile → chef_10.gemfile} +1 -1
- data/gemfiles/{chef_11.16.0.gemfile → chef_11.gemfile} +1 -1
- data/gemfiles/{chef_11.10.4.gemfile → chef_12.gemfile} +1 -1
- data/lib/chef/handler/datadog.rb +72 -218
- data/lib/chef/handler/datadog_chef_events.rb +174 -0
- data/lib/chef/handler/datadog_chef_metrics.rb +53 -0
- data/lib/chef/handler/datadog_chef_tags.rb +111 -0
- data/lib/chef_handler_datadog.rb +1 -1
- data/spec/datadog_spec.rb +29 -13
- data/spec/support/cassettes/Chef_Handler_Datadog/{handles_tags_correctly → tags/when_specified}/sets_the_role_and_env_and_tags.yml +62 -38
- data/spec/support/cassettes/Chef_Handler_Datadog/tags/when_unspecified/sets_role_env_and_nothing_else.yml +204 -0
- metadata +54 -53
- data/gemfiles/chef_10.32.2.gemfile +0 -17
- data/gemfiles/chef_11.12.8.gemfile +0 -16
- data/gemfiles/chef_11.8.2.gemfile +0 -16
- data/gemfiles/chef_12.0.0.alpha.1.gemfile +0 -16
@@ -0,0 +1,174 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rubygems'
|
3
|
+
require 'chef/handler'
|
4
|
+
require 'chef/mash'
|
5
|
+
require 'dogapi'
|
6
|
+
|
7
|
+
# helper class for sending events about chef runs
|
8
|
+
class DatadogChefEvents
|
9
|
+
def initialize
|
10
|
+
@dog = nil
|
11
|
+
@hostname = nil
|
12
|
+
@run_status = nil
|
13
|
+
@failure_notfications = nil
|
14
|
+
|
15
|
+
@alert_type = ''
|
16
|
+
@event_priority = ''
|
17
|
+
@event_title = ''
|
18
|
+
# TODO: refactor how event_body is constructed in the class methods
|
19
|
+
# handling of the event_body is a bit clunky and depends on the order of
|
20
|
+
# method calls
|
21
|
+
@event_body = ''
|
22
|
+
end
|
23
|
+
|
24
|
+
# set the dogapi client handle
|
25
|
+
#
|
26
|
+
# @param dogapi_client [Dogapi::Client] datadog api client handle
|
27
|
+
# @return [DatadogChefTags] instance reference to self enabling method chaining
|
28
|
+
def with_dogapi_client(dogapi_client)
|
29
|
+
@dog = dogapi_client
|
30
|
+
self
|
31
|
+
end
|
32
|
+
|
33
|
+
# set the target hostname (chef node name)
|
34
|
+
#
|
35
|
+
# @param hostname [String] hostname to use for the handler report
|
36
|
+
# @return [DatadogChefTags] instance reference to self enabling method chaining
|
37
|
+
def with_hostname(hostname)
|
38
|
+
@hostname = hostname
|
39
|
+
self
|
40
|
+
end
|
41
|
+
|
42
|
+
# set the chef run status used for the report
|
43
|
+
#
|
44
|
+
# @param run_status [Chef::RunStatus] current chef run status
|
45
|
+
# @return [DatadogChefTags] instance reference to self enabling method chaining
|
46
|
+
def with_run_status(run_status)
|
47
|
+
@run_status = run_status
|
48
|
+
self
|
49
|
+
end
|
50
|
+
|
51
|
+
# set the failure notification list
|
52
|
+
#
|
53
|
+
# @param failure_notifications [Array] set of datadog notification handles
|
54
|
+
# @return [DatadogChefTags] instance reference to self enabling method chaining
|
55
|
+
def with_failure_notifications(failure_notifications)
|
56
|
+
@failure_notifications = failure_notifications
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
# set the datadog host tags associated with the event
|
61
|
+
#
|
62
|
+
# @param [Array] the set of host tags
|
63
|
+
# @return [DatadogChefTags] instance reference to self enabling method chaining
|
64
|
+
def with_tags(tags)
|
65
|
+
@tags = tags
|
66
|
+
self
|
67
|
+
end
|
68
|
+
|
69
|
+
# Emit Chef event to Datadog
|
70
|
+
def emit_to_datadog
|
71
|
+
@event_body = ''
|
72
|
+
build_event_data
|
73
|
+
evt = @dog.emit_event(Dogapi::Event.new(@event_body,
|
74
|
+
msg_title: @event_title,
|
75
|
+
event_type: 'config_management.run',
|
76
|
+
event_object: @hostname,
|
77
|
+
alert_type: @alert_type,
|
78
|
+
priority: @event_priority,
|
79
|
+
source_type_name: 'chef',
|
80
|
+
tags: @tags
|
81
|
+
), host: @hostname)
|
82
|
+
|
83
|
+
begin
|
84
|
+
# FIXME: nice-to-have: abstract format of return value away a bit
|
85
|
+
# in dogapi directly. See https://github.com/DataDog/dogapi-rb/issues/18
|
86
|
+
if evt.length < 2
|
87
|
+
Chef::Log.warn("Unexpected response from Datadog Event API: #{evt}")
|
88
|
+
else
|
89
|
+
# [http_response_code, {"event" => {"url" => "...", ...}}]
|
90
|
+
# 2xx means ok
|
91
|
+
if evt[0].to_i / 100 != 2
|
92
|
+
Chef::Log.warn("Could not submit event to Datadog (HTTP call failed): #{evt[0]}")
|
93
|
+
else
|
94
|
+
Chef::Log.debug("Successfully submitted Chef event to Datadog for #{@hostname} at #{evt[1]['event']['url']}")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
rescue
|
98
|
+
Chef::Log.warn("Could not determine whether chef run was successfully submitted to Datadog: #{evt}")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
private
|
103
|
+
|
104
|
+
def pluralize(number, noun)
|
105
|
+
case number
|
106
|
+
when 0..1
|
107
|
+
"less than 1 #{noun}"
|
108
|
+
else
|
109
|
+
"#{number.round} #{noun}s"
|
110
|
+
end
|
111
|
+
rescue
|
112
|
+
Chef::Log.warn("Cannot make #{number} more legible")
|
113
|
+
"#{number} #{noun}s"
|
114
|
+
end
|
115
|
+
|
116
|
+
# Compose a list of resources updated during a run.
|
117
|
+
def update_resource_list
|
118
|
+
# No resources updated?
|
119
|
+
return unless @run_status.updated_resources.length.to_i > 0
|
120
|
+
|
121
|
+
if @run_status.failed?
|
122
|
+
# Shorten the list when there is a failure for stacktrace debugging
|
123
|
+
report_resources = @run_status.updated_resources.last(5)
|
124
|
+
else
|
125
|
+
report_resources = @run_status.updated_resources
|
126
|
+
end
|
127
|
+
|
128
|
+
@event_body = "\n$$$\n"
|
129
|
+
report_resources.each do |r|
|
130
|
+
@event_body << "- #{r} (#{r.defined_at})\n"
|
131
|
+
end
|
132
|
+
@event_body << "\n$$$\n"
|
133
|
+
end
|
134
|
+
|
135
|
+
# Marshal the Event data for submission
|
136
|
+
def build_event_data
|
137
|
+
# bail early in case of a compiletime failure
|
138
|
+
# OPTIMIZE: Use better inspectors to handle failure scenarios, refactor needed.
|
139
|
+
if @run_status.elapsed_time.nil?
|
140
|
+
@alert_type = 'error'
|
141
|
+
@event_title = "Chef failed during compile phase on #{@hostname} "
|
142
|
+
@event_priority = 'normal'
|
143
|
+
@event_body = 'Chef was unable to complete a run, an error during compilation may have occurred.'
|
144
|
+
else
|
145
|
+
run_time = pluralize(@run_status.elapsed_time, 'second')
|
146
|
+
|
147
|
+
# This is the first line of the Event body, the rest is appended here.
|
148
|
+
@event_body = "Chef updated #{@run_status.updated_resources.length} resources out of #{@run_status.all_resources.length} resources total."
|
149
|
+
|
150
|
+
# Update resource list, truncated when failed to 5
|
151
|
+
# update will add to the event_body
|
152
|
+
update_resource_list
|
153
|
+
|
154
|
+
if @run_status.success?
|
155
|
+
@alert_type = 'success'
|
156
|
+
@event_priority = 'low'
|
157
|
+
@event_title = "Chef completed in #{run_time} on #{@hostname} "
|
158
|
+
else
|
159
|
+
@alert_type = 'error'
|
160
|
+
@event_priority = 'normal'
|
161
|
+
@event_title = "Chef failed in #{run_time} on #{@hostname} "
|
162
|
+
|
163
|
+
if @failure_notifications
|
164
|
+
handles = @failure_notifications
|
165
|
+
# convert the notification handle array to a string
|
166
|
+
@event_body << "\nAlerting: #{handles.join(' ')}\n"
|
167
|
+
end
|
168
|
+
|
169
|
+
@event_body << "\n$$$\n#{@run_status.formatted_exception}\n$$$\n"
|
170
|
+
@event_body << "\n$$$\n#{@run_status.backtrace.join("\n")}\n$$$\n"
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end # end module DatadogChefEvent
|
@@ -0,0 +1,53 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'dogapi'
|
3
|
+
|
4
|
+
# helper class for sending datadog metrics from a chef run
|
5
|
+
class DatadogChefMetrics
|
6
|
+
def initialize
|
7
|
+
@dog = nil
|
8
|
+
@hostname = ''
|
9
|
+
@run_status = nil
|
10
|
+
end
|
11
|
+
|
12
|
+
# set the dogapi client handle
|
13
|
+
#
|
14
|
+
# @param dogapi_client [Dogapi::Client] datadog api client
|
15
|
+
# @return [DatadogChefMetrics] instance reference to self enabling method chaining
|
16
|
+
def with_dogapi_client(dogapi_client)
|
17
|
+
@dog = dogapi_client
|
18
|
+
self
|
19
|
+
end
|
20
|
+
|
21
|
+
# set the target hostname (chef node name)
|
22
|
+
#
|
23
|
+
# @param hostname [String] hostname used for reporting metrics
|
24
|
+
# @return [DatadogChefMetrics] instance reference to self enabling method chaining
|
25
|
+
def with_hostname(hostname)
|
26
|
+
@hostname = hostname
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
# set the chef run status used for the report
|
31
|
+
#
|
32
|
+
# @param run_status [Chef::RunStatus] current run status
|
33
|
+
# @return [DatadogChefMetrics] instance reference to self enabling method chaining
|
34
|
+
def with_run_status(run_status)
|
35
|
+
@run_status = run_status
|
36
|
+
self
|
37
|
+
end
|
38
|
+
|
39
|
+
# Emit Chef metrics to Datadog
|
40
|
+
def emit_to_datadog
|
41
|
+
# If there is a failure during compile phase, a large portion of
|
42
|
+
# run_status may be unavailable. Bail out here
|
43
|
+
warn_msg = 'Error during compile phase, no Datadog metrics available.'
|
44
|
+
return Chef::Log.warn(warn_msg) if @run_status.elapsed_time.nil?
|
45
|
+
|
46
|
+
@dog.emit_point('chef.resources.total', @run_status.all_resources.length, host: @hostname)
|
47
|
+
@dog.emit_point('chef.resources.updated', @run_status.updated_resources.length, host: @hostname)
|
48
|
+
@dog.emit_point('chef.resources.elapsed_time', @run_status.elapsed_time, host: @hostname)
|
49
|
+
Chef::Log.debug('Submitted Chef metrics back to Datadog')
|
50
|
+
rescue Errno::ECONNREFUSED, Errno::ETIMEDOUT => e
|
51
|
+
Chef::Log.error("Could not send metrics to Datadog. Connection error:\n" + e)
|
52
|
+
end
|
53
|
+
end # end class DatadogChefMetrics
|
@@ -0,0 +1,111 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require 'rubygems'
|
3
|
+
require 'chef/handler'
|
4
|
+
require 'chef/mash'
|
5
|
+
require 'dogapi'
|
6
|
+
|
7
|
+
# helper class for sending datadog tags from chef runs
|
8
|
+
class DatadogChefTags
|
9
|
+
def initialize
|
10
|
+
@node = nil
|
11
|
+
@run_status = nil
|
12
|
+
@application_key = nil
|
13
|
+
@combined_host_tags = nil
|
14
|
+
end
|
15
|
+
|
16
|
+
# set the dogapi client handle
|
17
|
+
#
|
18
|
+
# @param dogapi_client [Dogapi::Client] datadog api client handle
|
19
|
+
# @return [DatadogChefTags] instance reference to self enabling method chaining
|
20
|
+
def with_dogapi_client(dogapi_client)
|
21
|
+
@dog = dogapi_client
|
22
|
+
self
|
23
|
+
end
|
24
|
+
|
25
|
+
# attribute accessor for combined array of tags
|
26
|
+
#
|
27
|
+
# @return [Array] the set of host tags based off the chef run
|
28
|
+
attr_reader :combined_host_tags
|
29
|
+
|
30
|
+
# set the chef run status used for the report
|
31
|
+
#
|
32
|
+
# @param run_status [Chef::RunStatus] current chef run status
|
33
|
+
# @return [DatadogChefTags] instance reference to self enabling method chaining
|
34
|
+
def with_run_status(run_status)
|
35
|
+
@run_status = run_status
|
36
|
+
# Build up an array of Chef tags that will be sent back
|
37
|
+
# Selects all [env, roles, tags] from the Node's object and reformats
|
38
|
+
# them to `key:value` e.g. `role:database-master`.
|
39
|
+
@node = run_status.node
|
40
|
+
# generate the combined tags
|
41
|
+
chef_env = node_env.split # converts a string into an array
|
42
|
+
chef_roles = node_roles
|
43
|
+
chef_tags = node_tags
|
44
|
+
|
45
|
+
# Combine (union) all arrays. Removes duplicates if found.
|
46
|
+
@combined_host_tags = chef_env | chef_roles | chef_tags
|
47
|
+
self
|
48
|
+
end
|
49
|
+
|
50
|
+
# set the target hostname (chef node name)
|
51
|
+
#
|
52
|
+
# @param hostname [String] hostname to use for the handler report
|
53
|
+
# @return [DatadogChefTags] instance reference to self enabling method chaining
|
54
|
+
def with_hostname(hostname)
|
55
|
+
@hostname = hostname
|
56
|
+
self
|
57
|
+
end
|
58
|
+
|
59
|
+
# set the datadog application key
|
60
|
+
#
|
61
|
+
# TODO: the application key is only needed for error checking, e.g. an app key exists
|
62
|
+
# would be cleaner to push this check up to the data prep method in the
|
63
|
+
# calling handler class
|
64
|
+
#
|
65
|
+
# @param application_key [String] datadog application key used for chef reports
|
66
|
+
# @return [DatadogChefTags] instance reference to self enabling method chaining
|
67
|
+
def with_application_key(application_key)
|
68
|
+
@application_key = application_key
|
69
|
+
if @application_key.nil?
|
70
|
+
Chef::Log.warn('You need an application key to let Chef tag your nodes ' \
|
71
|
+
'in Datadog. Visit https://app.datadoghq.com/account/settings#api to ' \
|
72
|
+
'create one and update your datadog attributes in the datadog cookbook.'
|
73
|
+
)
|
74
|
+
fail ArgumentError, 'Missing Datadog Application Key'
|
75
|
+
end
|
76
|
+
self
|
77
|
+
end
|
78
|
+
|
79
|
+
# send updated chef run generated tags to Datadog
|
80
|
+
def send_update_to_datadog
|
81
|
+
rc = @dog.update_tags(@hostname, combined_host_tags, 'chef')
|
82
|
+
begin
|
83
|
+
# See FIXME above about why I feel dirty repeating this code here
|
84
|
+
if rc.length < 2
|
85
|
+
Chef::Log.warn("Unexpected response from Datadog Event API: #{rc}")
|
86
|
+
else
|
87
|
+
if rc[0].to_i / 100 != 2
|
88
|
+
Chef::Log.warn("Could not submit #{combined_host_tags} tags for #{@hostname} to Datadog: #{rc}")
|
89
|
+
else
|
90
|
+
Chef::Log.debug("Successfully updated #{@hostname}'s tags to #{combined_host_tags.join(', ')}")
|
91
|
+
end
|
92
|
+
end
|
93
|
+
rescue
|
94
|
+
Chef::Log.warn("Could not determine whether #{@hostname}'s tags were successfully submitted to Datadog: #{rc}")
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
private
|
99
|
+
|
100
|
+
def node_roles
|
101
|
+
@node.run_list.roles.map! { |role| 'role:' + role }
|
102
|
+
end
|
103
|
+
|
104
|
+
def node_env
|
105
|
+
'env:' + @node.chef_environment if @node.respond_to?('chef_environment')
|
106
|
+
end
|
107
|
+
|
108
|
+
def node_tags
|
109
|
+
@node.tags.map! { |tag| 'tag:' + tag } if @node.tags
|
110
|
+
end
|
111
|
+
end # end class DatadogChefTags
|
data/lib/chef_handler_datadog.rb
CHANGED
data/spec/datadog_spec.rb
CHANGED
@@ -182,13 +182,12 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
182
182
|
end
|
183
183
|
end
|
184
184
|
|
185
|
-
|
185
|
+
context 'tags' do
|
186
186
|
before(:each) do
|
187
187
|
@node = Chef::Node.build('chef.handler.datadog.test-tags')
|
188
188
|
|
189
189
|
@node.send(:chef_environment, 'hostile')
|
190
190
|
@node.send(:run_list, 'role[highlander]')
|
191
|
-
@node.normal.tags = ['the_one_and_only']
|
192
191
|
|
193
192
|
@events = Chef::EventDispatch::Dispatcher.new
|
194
193
|
@run_context = Chef::RunContext.new(@node, {}, @events)
|
@@ -200,20 +199,37 @@ describe Chef::Handler::Datadog, :vcr => :new_episodes do
|
|
200
199
|
@run_status.stop_clock
|
201
200
|
|
202
201
|
@run_status.run_context = @run_context
|
202
|
+
end
|
203
203
|
|
204
|
-
|
205
|
-
|
204
|
+
describe 'when specified' do
|
205
|
+
it 'sets the role and env and tags' do
|
206
|
+
@node.normal.tags = ['the_one_and_only']
|
207
|
+
@handler.run_report_unsafe(@run_status)
|
208
|
+
|
209
|
+
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
210
|
+
:query => { 'api_key' => @handler.config[:api_key],
|
211
|
+
'application_key' => @handler.config[:application_key],
|
212
|
+
'source' => 'chef' },
|
213
|
+
:body => hash_including(:tags => [
|
214
|
+
'env:hostile', 'role:highlander', 'tag:the_one_and_only'
|
215
|
+
]),
|
216
|
+
)).to have_been_made.times(1)
|
217
|
+
end
|
206
218
|
end
|
207
219
|
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
220
|
+
describe 'when unspecified' do
|
221
|
+
it 'sets role, env and nothing else' do
|
222
|
+
@handler.run_report_unsafe(@run_status)
|
223
|
+
|
224
|
+
expect(a_request(:put, HOST_TAG_ENDPOINT + @node.name).with(
|
225
|
+
:query => { 'api_key' => @handler.config[:api_key],
|
226
|
+
'application_key' => @handler.config[:application_key],
|
227
|
+
'source' => 'chef' },
|
228
|
+
:body => hash_including(:tags => [
|
229
|
+
'env:hostile', 'role:highlander'
|
230
|
+
]),
|
231
|
+
)).to have_been_made.times(1)
|
232
|
+
end
|
217
233
|
end
|
218
234
|
end
|
219
235
|
|
@@ -5,10 +5,12 @@ http_interactions:
|
|
5
5
|
uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
|
6
6
|
body:
|
7
7
|
encoding: UTF-8
|
8
|
-
string:
|
8
|
+
string: '{"series":[{"metric":"chef.resources.total","points":[[1428248966,0.0]],"type":"gauge","host":"chef.handler.datadog.test-tags","device":null}]}'
|
9
9
|
headers:
|
10
|
+
Accept-Encoding:
|
11
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
10
12
|
Accept:
|
11
|
-
-
|
13
|
+
- "*/*"
|
12
14
|
User-Agent:
|
13
15
|
- Ruby
|
14
16
|
Content-Type:
|
@@ -21,27 +23,31 @@ http_interactions:
|
|
21
23
|
Content-Type:
|
22
24
|
- text/json; charset=UTF-8
|
23
25
|
Date:
|
24
|
-
-
|
26
|
+
- Sun, 05 Apr 2015 15:49:21 GMT
|
25
27
|
Server:
|
26
|
-
- dogdispatcher/
|
28
|
+
- dogdispatcher/6.1.23
|
29
|
+
Strict-Transport-Security:
|
30
|
+
- max-age=15724800;
|
27
31
|
Content-Length:
|
28
32
|
- '15'
|
29
33
|
Connection:
|
30
34
|
- keep-alive
|
31
35
|
body:
|
32
|
-
encoding:
|
33
|
-
string:
|
36
|
+
encoding: UTF-8
|
37
|
+
string: '{"status":"ok"}'
|
34
38
|
http_version:
|
35
|
-
recorded_at:
|
39
|
+
recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
|
36
40
|
- request:
|
37
41
|
method: post
|
38
42
|
uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
|
39
43
|
body:
|
40
44
|
encoding: UTF-8
|
41
|
-
string:
|
45
|
+
string: '{"series":[{"metric":"chef.resources.updated","points":[[1428248966,0.0]],"type":"gauge","host":"chef.handler.datadog.test-tags","device":null}]}'
|
42
46
|
headers:
|
47
|
+
Accept-Encoding:
|
48
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
43
49
|
Accept:
|
44
|
-
-
|
50
|
+
- "*/*"
|
45
51
|
User-Agent:
|
46
52
|
- Ruby
|
47
53
|
Content-Type:
|
@@ -54,27 +60,31 @@ http_interactions:
|
|
54
60
|
Content-Type:
|
55
61
|
- text/json; charset=UTF-8
|
56
62
|
Date:
|
57
|
-
-
|
63
|
+
- Sun, 05 Apr 2015 15:49:22 GMT
|
58
64
|
Server:
|
59
|
-
- dogdispatcher/
|
65
|
+
- dogdispatcher/6.1.23
|
66
|
+
Strict-Transport-Security:
|
67
|
+
- max-age=15724800;
|
60
68
|
Content-Length:
|
61
69
|
- '15'
|
62
70
|
Connection:
|
63
71
|
- keep-alive
|
64
72
|
body:
|
65
|
-
encoding:
|
66
|
-
string:
|
73
|
+
encoding: UTF-8
|
74
|
+
string: '{"status":"ok"}'
|
67
75
|
http_version:
|
68
|
-
recorded_at:
|
76
|
+
recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
|
69
77
|
- request:
|
70
78
|
method: post
|
71
79
|
uri: https://app.datadoghq.com/api/v1/series?api_key=<API_KEY>
|
72
80
|
body:
|
73
81
|
encoding: UTF-8
|
74
|
-
string:
|
82
|
+
string: '{"series":[{"metric":"chef.resources.elapsed_time","points":[[1428248966,5.0]],"type":"gauge","host":"chef.handler.datadog.test-tags","device":null}]}'
|
75
83
|
headers:
|
84
|
+
Accept-Encoding:
|
85
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
76
86
|
Accept:
|
77
|
-
-
|
87
|
+
- "*/*"
|
78
88
|
User-Agent:
|
79
89
|
- Ruby
|
80
90
|
Content-Type:
|
@@ -87,30 +97,34 @@ http_interactions:
|
|
87
97
|
Content-Type:
|
88
98
|
- text/json; charset=UTF-8
|
89
99
|
Date:
|
90
|
-
-
|
100
|
+
- Sun, 05 Apr 2015 15:49:23 GMT
|
91
101
|
Server:
|
92
|
-
- dogdispatcher/
|
102
|
+
- dogdispatcher/6.1.23
|
103
|
+
Strict-Transport-Security:
|
104
|
+
- max-age=15724800;
|
93
105
|
Content-Length:
|
94
106
|
- '15'
|
95
107
|
Connection:
|
96
108
|
- keep-alive
|
97
109
|
body:
|
98
|
-
encoding:
|
99
|
-
string:
|
110
|
+
encoding: UTF-8
|
111
|
+
string: '{"status":"ok"}'
|
100
112
|
http_version:
|
101
|
-
recorded_at:
|
113
|
+
recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
|
102
114
|
- request:
|
103
115
|
method: post
|
104
116
|
uri: https://app.datadoghq.com/api/v1/events?api_key=<API_KEY>
|
105
117
|
body:
|
106
118
|
encoding: UTF-8
|
107
|
-
string:
|
119
|
+
string: '{"msg_text":"Chef updated 0 resources out of 0 resources total.","date_happened":1428248966,"msg_title":"Chef
|
108
120
|
completed in 5 seconds on chef.handler.datadog.test-tags ","priority":"low","parent":null,"tags":["env:hostile","role:highlander","tag:the_one_and_only"],"aggregation_key":"chef.handler.datadog.test-tags","alert_type":"success","event_type":"config_management.run","source_type_name":"chef","title":"Chef
|
109
121
|
completed in 5 seconds on chef.handler.datadog.test-tags ","text":"Chef updated
|
110
122
|
0 resources out of 0 resources total.","host":"chef.handler.datadog.test-tags","device":null}'
|
111
123
|
headers:
|
124
|
+
Accept-Encoding:
|
125
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
112
126
|
Accept:
|
113
|
-
-
|
127
|
+
- "*/*"
|
114
128
|
User-Agent:
|
115
129
|
- Ruby
|
116
130
|
Content-Type:
|
@@ -123,32 +137,36 @@ http_interactions:
|
|
123
137
|
Content-Type:
|
124
138
|
- text/json; charset=UTF-8
|
125
139
|
Date:
|
126
|
-
-
|
140
|
+
- Sun, 05 Apr 2015 15:49:23 GMT
|
127
141
|
Server:
|
128
|
-
- dogdispatcher/
|
142
|
+
- dogdispatcher/6.1.23
|
143
|
+
Strict-Transport-Security:
|
144
|
+
- max-age=15724800;
|
129
145
|
Content-Length:
|
130
|
-
- '
|
146
|
+
- '420'
|
131
147
|
Connection:
|
132
148
|
- keep-alive
|
133
149
|
body:
|
134
|
-
encoding:
|
135
|
-
string:
|
150
|
+
encoding: UTF-8
|
151
|
+
string: '{"status": "ok", "event": {"priority": "low", "date_happened": 1428248966,
|
136
152
|
"handle": null, "title": "Chef completed in 5 seconds on chef.handler.datadog.test-tags
|
137
|
-
", "url": "https://app.datadoghq.com/event/
|
153
|
+
", "url": "https://app.datadoghq.com/event/event?id=2751230185062799345",
|
138
154
|
"text": "Chef updated 0 resources out of 0 resources total.", "tags": ["env:hostile",
|
139
155
|
"role:highlander", "tag:the_one_and_only"], "related_event_id": null, "id":
|
140
|
-
|
156
|
+
2751230185062799345}}'
|
141
157
|
http_version:
|
142
|
-
recorded_at:
|
158
|
+
recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
|
143
159
|
- request:
|
144
160
|
method: put
|
145
161
|
uri: https://app.datadoghq.com/api/v1/tags/hosts/chef.handler.datadog.test-tags?api_key=<API_KEY>&application_key=<APPLICATION_KEY>&source=chef
|
146
162
|
body:
|
147
163
|
encoding: UTF-8
|
148
|
-
string:
|
164
|
+
string: '{"tags":["env:hostile","role:highlander","tag:the_one_and_only"]}'
|
149
165
|
headers:
|
166
|
+
Accept-Encoding:
|
167
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
150
168
|
Accept:
|
151
|
-
-
|
169
|
+
- "*/*"
|
152
170
|
User-Agent:
|
153
171
|
- Ruby
|
154
172
|
Content-Type:
|
@@ -163,19 +181,25 @@ http_interactions:
|
|
163
181
|
Content-Type:
|
164
182
|
- application/json
|
165
183
|
Date:
|
166
|
-
-
|
184
|
+
- Sun, 05 Apr 2015 15:49:24 GMT
|
167
185
|
Pragma:
|
168
186
|
- no-cache
|
169
187
|
Server:
|
170
188
|
- gunicorn/19.1.0
|
189
|
+
Strict-Transport-Security:
|
190
|
+
- max-age=15724800;
|
191
|
+
X-Dd-Debug:
|
192
|
+
- mPU4gm+hKkKT8ia9ZdY5CzVKb87xvoCEvNtumo6b6Z8=
|
193
|
+
X-Frame-Options:
|
194
|
+
- SAMEORIGIN
|
171
195
|
Content-Length:
|
172
196
|
- '110'
|
173
197
|
Connection:
|
174
198
|
- keep-alive
|
175
199
|
body:
|
176
|
-
encoding:
|
177
|
-
string:
|
200
|
+
encoding: UTF-8
|
201
|
+
string: '{"host": "chef.handler.datadog.test-tags", "tags": ["env:hostile",
|
178
202
|
"role:highlander", "tag:the_one_and_only"]}'
|
179
203
|
http_version:
|
180
|
-
recorded_at:
|
181
|
-
recorded_with: VCR 2.9.
|
204
|
+
recorded_at: Sun, 05 Apr 2015 15:49:26 GMT
|
205
|
+
recorded_with: VCR 2.9.3
|