class Chef::Handler::Datadog
Attributes
Public Class Methods
For the tags to work, the client must have created an Application Key on the “Account Settings” page here: app.datadoghq.com/account/settings It should be passed along from the node/role/environemnt attributes, as the default is nil.
# File lib/chef/handler/datadog.rb, line 19 def initialize(config = {}) @config = Mash.new(config) @dogs = prepare_the_pack end
Public Instance Methods
# File lib/chef/handler/datadog.rb, line 25 def report # use datadog agent proxy settings, if available use_agent_proxy unless ENV['DATADOG_PROXY'].nil? # prepare the metrics, event, and tags information to be reported prepare_report_for_datadog @dogs.each do |dog| # post the report information to the datadog service Chef::Log.debug("Sending Chef report to #{dog.datadog_host}") send_report_to_datadog dog end ensure # restore the env proxy settings before leaving to avoid downstream side-effects restore_env_proxies unless ENV['DATADOG_PROXY'].nil? end
Private Instance Methods
# File lib/chef/handler/datadog.rb, line 150 def config_url() url = 'https://app.datadoghq.com' url = 'https://app.' + @config[:site] unless @config[:site].nil? url = @config[:url] unless @config[:url].nil? url end
return all endpoints as a list of triplets [url, api_key, application_key]
# File lib/chef/handler/datadog.rb, line 158 def endpoints validate_keys(@config[:api_key], @config[:application_key], true) # the first endpoint is always the url/site + apikey + appkey one endpoints = [[config_url(), @config[:api_key], @config[:application_key]]] # then add extra endpoints extra_endpoints = @config[:extra_endpoints] || [] extra_endpoints.each do |endpoint| url = endpoint[:api_url] || endpoint[:url] || config_url() api_key = endpoint[:api_key] app_key = endpoint[:application_key] endpoints << [url, api_key, app_key] if validate_keys(api_key, app_key, false) end endpoints end
prepare metrics, event, and tags data for posting to datadog
# File lib/chef/handler/datadog.rb, line 45 def prepare_report_for_datadog # uses class method accessors for run_status and config hostname = resolve_correct_hostname # prepare chef run metrics @metrics = DatadogChefMetrics.new .with_hostname(hostname) .with_run_status(run_status) # Collect and prepare tags @tags = DatadogChefTags.new .with_hostname(hostname) .with_run_status(run_status) .with_tag_prefix(config[:tag_prefix]) .with_retries(config[:tags_submission_retries]) .with_tag_blacklist(config[:tags_blacklist_regex]) .with_scope_prefix(config[:scope_prefix]) .with_policy_tags_enabled(config[:send_policy_tags]) # Build the chef event information @event = DatadogChefEvents.new .with_hostname(hostname) .with_run_status(run_status) .with_failure_notifications(@config['notify_on_failure']) .with_tags(@tags.combined_host_tags) end
create and configure all the Dogapi Clients to be used
@return [Array] all Dogapi::Client to be used
# File lib/chef/handler/datadog.rb, line 129 def prepare_the_pack dogs = [] endpoints.each do |url, api_key, app_key| begin dogs.push(Dogapi::Client.new( api_key, app_key, nil, # host nil, # device false, # silent nil, # timeout url, config[:skip_ssl_validation] )) rescue => e Chef::Log.error("Could not create API Client '#{url}'\n #{e.to_s}") end end dogs end
Select which hostname to report back to Datadog
. Makes decision based on inputs from `config` and when absent, use the node's `ec2` attribute existence to make the decision.
@return [String] the hostname decided upon
# File lib/chef/handler/datadog.rb, line 95 def resolve_correct_hostname node = run_status.node use_ec2_instance_id = !config.key?(:use_ec2_instance_id) || (config.key?(:use_ec2_instance_id) && config[:use_ec2_instance_id]) if config[:hostname] config[:hostname] elsif use_ec2_instance_id && node.attribute?('ec2') && node['ec2'].attribute?('instance_id') node['ec2']['instance_id'] else node.name end end
Restore environment proxy settings to pre-report values
# File lib/chef/handler/datadog.rb, line 121 def restore_env_proxies ENV['http_proxy'] = @env_http_proxy ENV['https_proxy'] = @env_https_proxy end
Submit metrics, event, and tags information to datadog
@param dog [Dogapi::Client] Dogapi Client to be used
# File lib/chef/handler/datadog.rb, line 77 def send_report_to_datadog(dog) @metrics.emit_to_datadog dog @event.emit_to_datadog dog @tags.send_update_to_datadog dog rescue => e Chef::Log.error("Could not send/emit to Datadog:\n" + e.to_s) Chef::Log.error('Event data to be submitted was:') Chef::Log.error(@event.event_title) Chef::Log.error(@event.event_body) Chef::Log.error('Tags to be set for this run:') Chef::Log.error(@tags.combined_host_tags) end
Using the agent proxy settings requires setting http(s)_proxy env vars. However, original env var settings need to be preserved for restoration at the end of the handler.
# File lib/chef/handler/datadog.rb, line 112 def use_agent_proxy Chef::Log.info('Using agent proxy settings') @env_http_proxy = ENV['http_proxy'] @env_https_proxy = ENV['https_proxy'] ENV['http_proxy'] = ENV['DATADOG_PROXY'] ENV['https_proxy'] = ENV['DATADOG_PROXY'] end
Validate endpoints config (api_key and application key) fails if incorrect and should_fail is true (needed for the default) Doesn't fail for the other endpoints but logs a warning
# File lib/chef/handler/datadog.rb, line 179 def validate_keys(api_key, app_key, should_fail) if api_key.nil? Chef::Log.warn('You need an API key to communicate with Datadog') fail ArgumentError, 'Missing Datadog Api Key' if should_fail return false end if app_key.nil? Chef::Log.warn('You need an application key to let Chef tag your nodes ' \ 'in Datadog. Visit https://app.datadoghq.com/account/settings#api to ' \ 'create one and update your datadog attributes in the datadog cookbook.') fail ArgumentError, 'Missing Datadog Application Key' if should_fail return false end true end