chef-handler-datadog 0.6.0 → 0.7.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|