Last active
November 5, 2022 15:38
-
-
Save patbl/cb73d9865c330d2df426a0661b7c5204 to your computer and use it in GitHub Desktop.
Script to add custom tag groups to all StatsD-reported Datadog metrics. Don't run it unless you understand what it does. Tags in `TAGS_TO_EXCLUDE` are excluded from the custom tag groups.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# frozen_string_literal: true | |
require 'datadog_api_client' | |
require 'json' | |
class AddCustomTagGroups | |
ALL_METRICS_FILE = "metrics.txt" | |
METRIC_TYPES_FILE = "metric_types.json" | |
METRIC_TAGS_FILE = "metric_tags.json" | |
TAGS_TO_EXCLUDE = [ | |
# Put the names of tags you want to exclude here! Otherwise this script won't be useful. | |
] | |
def call | |
statsd_metric_types.each_key.with_index do |metric, i| | |
puts "#{metric} #{i} of #{statsd_metric_types.size}" | |
tags_for_metric = metric_tags[metric] | |
if tags_for_metric.nil? || tags_for_metric.empty? | |
puts "no tags for metric #{metric.inspect}" | |
next | |
end | |
tags_to_keep = tags_for_metric.to_a - TAGS_TO_EXCLUDE | |
body = DatadogAPIClient::V2::MetricTagConfigurationCreateRequest.new( | |
{ | |
data: DatadogAPIClient::V2::MetricTagConfigurationCreateData.new( | |
{ | |
id: metric, | |
type: DatadogAPIClient::V2::MetricTagConfigurationType::MANAGE_TAGS, | |
attributes: { | |
tags: tags_to_keep, | |
metric_type: statsd_metric_types.fetch(metric).fetch("type") | |
}, | |
} | |
) | |
} | |
) | |
attempts = 0 | |
begin | |
attempts += 1 | |
# Create a tag configuration | |
result = api_instance_v2.create_tag_configuration(metric, body) | |
p result | |
rescue DatadogAPIClient::V2::APIError => e | |
puts "Error when calling MetricsAPI->create_tag_configuration: #{e}" | |
if e.code == 429 && attempts < 3 | |
puts "rate-limited; retrying" | |
sleep 60 | |
retry | |
end | |
end | |
sleep 1 | |
end | |
end | |
def metric_tags | |
return @metric_tags if defined?(@metric_tags) | |
unless File.exist?(METRIC_TAGS_FILE) | |
metric_tags = statsd_metric_types.each_key.with_index.with_object({}) do |(metric, i), metric_tags| | |
puts "#{i} of #{statsd_metric_types.size}" | |
sleep 60.fdiv(50) + 0.1 | |
response = api_instance_v2.list_tags_by_metric_name(metric) | |
tags = response.data.attributes.tags | |
tag_keys = tags.each_with_object(Set.new) { |tag, set| set << tag.split(":")[0] } | |
metric_tags[metric] = tag_keys.to_a | |
rescue DatadogAPIClient::V2::APIError | |
puts "error, retrying" | |
sleep 60 | |
retry | |
end | |
File.write(METRIC_TAGS_FILE, JSON.pretty_generate(metric_tags)) | |
end | |
@metric_tags = JSON.parse(File.read(METRIC_TAGS_FILE)) | |
end | |
def all_metrics | |
return @all_metrics if defined?(@all_metrics) | |
unless File.exist?(ALL_METRICS_FILE) | |
from = Integer(Time.now - 3600 * 24) # 1 day ago | |
response = api_instance.list_active_metrics(from) | |
metrics = response.metrics | |
File.open(ALL_METRICS_FILE, "w") do |file| | |
metrics.each do |metric| | |
file.puts(metric) | |
end | |
end | |
end | |
@all_metrics = File.readlines(ALL_METRICS_FILE, chomp: true) | |
end | |
def metric_types | |
return @metric_types if defined?(@metric_types) | |
unless File.exist?(METRIC_TYPES_FILE) | |
metric_types = {} | |
all_metrics.each_with_index do |metric, i| | |
response = api_instance.get_metric_metadata(metric) | |
metric_types[metric] = response.to_hash | |
end | |
File.write(METRIC_TYPES_FILE, JSON.pretty_generate(metric_types)) | |
end | |
@metric_types = JSON.parse(File.read(METRIC_TYPES_FILE)) | |
end | |
def api_instance | |
@api_instance ||= DatadogAPIClient::V1::MetricsAPI.new | |
end | |
def api_instance_v2 | |
return @api_instance_v2 if defined?(@api_instance_v2) | |
DatadogAPIClient::V2.configure do |config| | |
config.unstable_operations[:create_tag_configuration] = true | |
config.unstable_operations[:list_tag_configuration_by_name] = true | |
end | |
@api_instance_v2 = DatadogAPIClient::V2::MetricsAPI.new | |
end | |
def statsd_metric_types | |
@statsd_metric_types ||= metric_types.select do |name, attrs| | |
attrs.key?("statsd_interval") | |
end | |
end | |
end | |
AddCustomTagGroups.new.call |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment