diff --git a/README.md b/README.md index ba6e70a..77448bc 100644 --- a/README.md +++ b/README.md @@ -37,7 +37,7 @@ plugin :statsd ## Usage -Ensure you have an environment variable set that points to a statsd host, then boot your puma app as usual. Optionally you may specify a port (default is 8125). +Ensure you have an environment variable set that points to a statsd host, then boot your puma app as usual. Optionally you may specify a port (default is 8125). ``` STATSD_HOST=127.0.0.1 bundle exec puma @@ -53,9 +53,25 @@ metric tags are a non-standard addition to the statsd protocol, supported by the datadog "dogstatsd" server. Should you be reporting the puma metrics to a dogstatsd server, you can set -tags via the following two environment variables. +tags via the following three environment variables. -`MY_POD_NAME` adds a `pod_name` tag to the metrics. The `MY_POD_NAME` + +#### DD_TAGS + +`DD_TAGS`: Set this to a space-separated list of tags, using the +[datadog agent standard format](https://docs.datadoghq.com/agent/docker/?tab=standard#global-options). + +For example, you could set this environment variable to set three datadog tags, +and then you can filter by in the datadog interface: + +```bash +export DD_TAGS="env:test simple-tag-0 tag-key-1:tag-value-1" +bundle exec rails server +``` + +#### MY_POD_NAME + +`MY_POD_NAME`: Set a `pod_name` tag to the metrics. The `MY_POD_NAME` environment variable is recommended in the datadog kubernetes setup documentation, and for puma apps deployed to kubernetes it's very helpful to have the option to report on specific pods. @@ -70,7 +86,9 @@ env: fieldPath: metadata.name ``` -`STATSD_GROUPING` adds a `grouping` tag to the metrics, with a value equal to +#### STATSD_GROUPING + +`STATSD_GROUPING`: add a `grouping` tag to the metrics, with a value equal to the environment variable value. This is particularly helpful in a kubernetes deployment where each pod has a unique name but you want the option to group metrics across all pods in a deployment. Setting this on the pods in a @@ -100,7 +118,7 @@ Start puma: Throw some traffic at it, either with curl or a tool like ab: curl http://127.0.0.1:9292/ - ab -n 10000 -c 20 http://127.0.0.1:9292/ + ab -n 10000 -c 20 http://127.0.0.1:9292/ Watch the output of the UDP server process - you should see statsd data printed to stdout. diff --git a/lib/puma/plugin/statsd.rb b/lib/puma/plugin/statsd.rb index 827ccf0..14fef00 100644 --- a/lib/puma/plugin/statsd.rb +++ b/lib/puma/plugin/statsd.rb @@ -20,12 +20,9 @@ def enabled? !!host end - def send(metric_name:, value:, type:, tags: {}) + def send(metric_name:, value:, type:, tags: nil) data = "#{metric_name}:#{value}|#{STATSD_TYPES.fetch(type)}" - if tags.any? - tag_str = tags.map { |k,v| "#{k}:#{v}" }.join(",") - data = "#{data}|##{tag_str}" - end + data = "#{data}|##{tags}" unless tags.nil? socket = UDPSocket.new socket.send(data, 0, host, port) @@ -123,15 +120,39 @@ def fetch_stats end end - def tags - tags = {} + def environment_variable_tags + # Tags are separated by spaces, and while they are normally a tag and + # value separated by a ':', they can also just be tagged without any + # associated value. + # + # Examples: simple-tag-0 tag-key-1:tag-value-1 + # + tags = [] + if ENV.has_key?("MY_POD_NAME") - tags[:pod_name] = ENV.fetch("MY_POD_NAME", "no_pod") + tags << "pod_name:#{ENV['MY_POD_NAME']}" end + if ENV.has_key?("STATSD_GROUPING") - tags[:grouping] = ENV.fetch("STATSD_GROUPING", "no-group") + tags << "grouping:#{ENV['STATSD_GROUPING']}" end - tags + + # Standardised datadog tag attributes, so that we can share the metric + # tags with the application running + # + # https://docs.datadoghq.com/agent/docker/?tab=standard#global-options + # + if ENV.has_key?("DD_TAGS") + ENV["DD_TAGS"].split(/\s+/).each do |t| + tags << t + end + end + + # Return nil if we have no environment variable tags. This way we don't + # send an unnecessary '|' on the end of each stat + return nil if tags.empty? + + tags.join(",") end def prefixed_metric_name(puma_metric) @@ -140,6 +161,8 @@ def prefixed_metric_name(puma_metric) # Send data to statsd every few seconds def stats_loop + tags = environment_variable_tags + sleep 5 loop do @launcher.events.debug "statsd: notify statsd"