From c3be4e3076769af554358b2b45238f8f89e851a2 Mon Sep 17 00:00:00 2001 From: David Sze Date: Tue, 7 Jun 2022 16:30:18 -0400 Subject: [PATCH] feat: support custom metric types Other statsd backends (e.g. Datadog, netdata) support metric types beyond those supported by the original Etsy statsd daemon. For example: * Histograms (type "h") which are like Timers, but with different units. * Dictionaries (type "d") which are like Sets but also record a count for each unique value. Since these are non-standard, add a `custom()` method, where the metric type is passed in by the caller, assuming that they know the capabilities of the backend they are using. --- include/cpp-statsd-client/StatsdClient.hpp | 17 +++++++++++++++++ tests/testStatsdClient.cpp | 5 +++++ 2 files changed, 22 insertions(+) diff --git a/include/cpp-statsd-client/StatsdClient.hpp b/include/cpp-statsd-client/StatsdClient.hpp index 8c19426..7114432 100644 --- a/include/cpp-statsd-client/StatsdClient.hpp +++ b/include/cpp-statsd-client/StatsdClient.hpp @@ -122,6 +122,14 @@ class StatsdClient { float frequency = 1.0f, const std::vector& tags = {}) const noexcept; + //! Records a custom metric type for the key, with a given value, at a given frequency + template + void custom(const std::string& key, + const T value, + const char* type, + float frequency = 1.0f, + const std::vector& tags = {}) const noexcept; + //! Seed the RNG that controls sampling void seed(unsigned int seed = std::random_device()()) noexcept; @@ -248,6 +256,15 @@ inline void StatsdClient::set(const std::string& key, send(key, sum, detail::METRIC_TYPE_SET, frequency, tags); } +template +inline void StatsdClient::custom(const std::string& key, + const T value, + const char* type, + const float frequency, + const std::vector& tags) const noexcept { + send(key, value, type, frequency, tags); +} + template inline void StatsdClient::send(const std::string& key, const T value, diff --git a/tests/testStatsdClient.cpp b/tests/testStatsdClient.cpp index 74db846..22e0d6e 100644 --- a/tests/testStatsdClient.cpp +++ b/tests/testStatsdClient.cpp @@ -139,6 +139,11 @@ void testSendRecv(uint64_t batchSize, uint64_t sendInterval) { client.count("foo", -42, .9f, {"bar", "baz"}); throwOnError(client); expected.emplace_back("sendRecv.foo:-42|c|@0.90|#bar,baz"); + + // Custom metric type should pass through all params + client.custom("custom_metric_type", 5678, "cust", .95f, {"tag1", "tag2"}); + throwOnError(client); + expected.emplace_back("sendRecv.custom_metric_type:5678|cust|@0.95|#tag1,tag2"); } // Signal the mock server we are done