From 2eb4ba327e2016c6632cc559f28d4027ad932409 Mon Sep 17 00:00:00 2001 From: Igor Serebryany Date: Wed, 19 Nov 2014 16:32:15 -0800 Subject: [PATCH] statsd: option to namespace all metrics we are currently unable to run datadog on the machines in our staging or testing clusters. this is because the code in the applications running there is set to report metrics directly to datadog. those non-production metrics nontheless become mixed in with production metrics in datadog. there are two existing solutions: * in datadog, always specify an environment tag to exclude non-production metrics * in applications, always manually namespace the metrics the first is difficult. we already have many dashboards and alerts which don't specify any environment. also, naive examination in, e.g., the metric explorer will still conflate the metrics and cause confusion. the second is annoying, because we have to make an identical configuration change throughout multiple applications. instead, we propose the mechanism here, which allows statsd metrics being reported to be automatically namespaced. i wasn't sure how to test this functionality, since there are no existing tests for the `init` function. i am also not sure about grabbing a direct reference to the api_formatter function elsewhere in the code. --- datadog.conf.example | 5 +++++ dogstatsd.py | 24 ++++++++++++++++++++++-- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/datadog.conf.example b/datadog.conf.example index 34e7160b0a..4d05d7f607 100644 --- a/datadog.conf.example +++ b/datadog.conf.example @@ -108,6 +108,11 @@ use_mount: no # statsd_forward_host: address_of_own_statsd_server # statsd_forward_port: 8125 +# you may want all statsd metrics coming from this host to be namespaced +# in some way; if so, configure your namespace here. a metric that looks +# like `metric.name` will instead become `namespace.metric.name` +# statsd_metric_namespace: + # ========================================================================== # # Service-specific configuration # # ========================================================================== # diff --git a/dogstatsd.py b/dogstatsd.py index 0956122cf3..a59d833b16 100755 --- a/dogstatsd.py +++ b/dogstatsd.py @@ -25,7 +25,7 @@ from urllib import urlencode # project -from aggregator import MetricsBucketAggregator +from aggregator import MetricsBucketAggregator, api_formatter from checks.check_status import DogstatsdStatus from config import get_config from daemon import Daemon, AgentSupervisor @@ -389,7 +389,27 @@ def init(config_path=None, use_watchdog=False, use_forwarder=False, args=None): # server and reporting threads. assert 0 < interval - aggregator = MetricsBucketAggregator(hostname, aggregator_interval, recent_point_threshold=recent_point_threshold) + formatter = api_formatter + if c['statsd_metric_namespace']: + def metric_namespace_formatter_wrapper(*args, **kwargs): + metric_prefix = c['statsd_metric_namespace'] + if metric_prefix[-1] != '.': + metric_prefix += '.' + + metric = args[0] + new_metric = metric_prefix + metric + new_args = [new_metric] + args[1:] + return api_formatter(*new_args, **kwargs) + + formatter = metric_namespace_formatter_wrapper + + + aggregator = MetricsBucketAggregator( + hostname, + aggregator_interval, + recent_point_threshold=recent_point_threshold, + formatter = formatter + ) # Start the reporting thread. reporter = Reporter(interval, aggregator, target, api_key, use_watchdog, event_chunk_size)