From f8bf1fe7cdbd31901fa527ba1a7ab0d7deab5c4d Mon Sep 17 00:00:00 2001 From: Benjamin Sergeant Date: Sun, 29 Mar 2020 19:31:49 -0700 Subject: [PATCH] (cobra to statsd bot) add ability to extract a numerical value and send a gauge event to statsd --- docs/CHANGELOG.md | 4 +++ ixbots/ixbots/IXCobraToStatsdBot.cpp | 52 +++++++++++++++++++++++++--- ixbots/ixbots/IXCobraToStatsdBot.h | 1 + ixwebsocket/IXWebSocketVersion.h | 2 +- test/IXCobraToStatsdBotTest.cpp | 2 ++ ws/ws.cpp | 3 ++ 6 files changed, 58 insertions(+), 6 deletions(-) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index fe9c2b86..16767cd0 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,6 +1,10 @@ # Changelog All changes to this project will be documented in this file. +## [9.1.7] - 2020-03-29 + +(cobra to statsd bot) add ability to extract a numerical value and send a gauge event to statsd + ## [9.1.6] - 2020-03-29 (ws cobra subscriber) use a Json::StreamWriter to write to std::cout, and save one std::string allocation for each message printed diff --git a/ixbots/ixbots/IXCobraToStatsdBot.cpp b/ixbots/ixbots/IXCobraToStatsdBot.cpp index fd1b2673..2a907b4d 100644 --- a/ixbots/ixbots/IXCobraToStatsdBot.cpp +++ b/ixbots/ixbots/IXCobraToStatsdBot.cpp @@ -40,7 +40,7 @@ namespace ix // Extract an attribute from a Json Value. // extractAttr("foo.bar", {"foo": {"bar": "baz"}}) => baz // - std::string extractAttr(const std::string& attr, const Json::Value& jsonValue) + Json::Value extractAttr(const std::string& attr, const Json::Value& jsonValue) { // Split by . std::string token; @@ -53,7 +53,7 @@ namespace ix val = val[token]; } - return val.asString(); + return val; } int cobra_to_statsd_bot(const ix::CobraConfig& config, @@ -62,6 +62,7 @@ namespace ix const std::string& position, StatsdClient& statsdClient, const std::string& fields, + const std::string& gauge, bool verbose, size_t maxQueueSize, bool enableHeartbeat, @@ -124,7 +125,7 @@ namespace ix std::thread t2(heartbeat); - auto statsdSender = [&statsdClient, &queueManager, &sentCount, &tokens, &stop] { + auto statsdSender = [&statsdClient, &queueManager, &sentCount, &tokens, &stop, &gauge, &fatalCobraError] { while (true) { Json::Value msg = queueManager.pop(); @@ -136,10 +137,51 @@ namespace ix for (auto&& attr : tokens) { id += "."; - id += extractAttr(attr, msg); + auto val = extractAttr(attr, msg); + id += val.asString(); + } + + if (gauge.empty()) + { + statsdClient.count(id, 1); + } + else + { + // spdlog::info("{} - {} -> {}", id, gauge, x); + auto val = extractAttr(gauge, msg); + + if (val.isInt()) + { + auto x = val.asInt(); + statsdClient.gauge(id, (size_t) x); + } + else if (val.isInt64()) + { + auto x = val.asInt64(); + statsdClient.gauge(id, (size_t) x); + } + else if (val.isUInt()) + { + auto x = val.asUInt(); + statsdClient.gauge(id, (size_t) x); + } + else if (val.isUInt64()) + { + auto x = val.asUInt64(); + statsdClient.gauge(id, (size_t) x); + } + else if (val.isDouble()) + { + auto x = val.asUInt64(); + statsdClient.gauge(id, (size_t) x); + } + else + { + spdlog::error("Gauge {} is not a numberic type", gauge); + fatalCobraError = true; + } } - statsdClient.count(id, 1); sentCount += 1; } }; diff --git a/ixbots/ixbots/IXCobraToStatsdBot.h b/ixbots/ixbots/IXCobraToStatsdBot.h index dcf5462b..05e3a9dc 100644 --- a/ixbots/ixbots/IXCobraToStatsdBot.h +++ b/ixbots/ixbots/IXCobraToStatsdBot.h @@ -18,6 +18,7 @@ namespace ix const std::string& position, StatsdClient& statsdClient, const std::string& fields, + const std::string& gauge, bool verbose, size_t maxQueueSize, bool enableHeartbeat, diff --git a/ixwebsocket/IXWebSocketVersion.h b/ixwebsocket/IXWebSocketVersion.h index 28fad4aa..f586f714 100644 --- a/ixwebsocket/IXWebSocketVersion.h +++ b/ixwebsocket/IXWebSocketVersion.h @@ -6,4 +6,4 @@ #pragma once -#define IX_WEBSOCKET_VERSION "9.1.6" +#define IX_WEBSOCKET_VERSION "9.1.7" diff --git a/test/IXCobraToStatsdBotTest.cpp b/test/IXCobraToStatsdBotTest.cpp index 0786362f..b2ac54dc 100644 --- a/test/IXCobraToStatsdBotTest.cpp +++ b/test/IXCobraToStatsdBotTest.cpp @@ -111,6 +111,7 @@ TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]") REQUIRE(initialized); std::string fields("device.game\ndevice.os_name"); + std::string gauge; int sentCount = ix::cobra_to_statsd_bot(config, channel, @@ -118,6 +119,7 @@ TEST_CASE("Cobra_to_statsd_bot", "[cobra_bots]") position, statsdClient, fields, + gauge, verbose, maxQueueSize, enableHeartbeat, diff --git a/ws/ws.cpp b/ws/ws.cpp index fe7172d0..d3be0e21 100644 --- a/ws/ws.cpp +++ b/ws/ws.cpp @@ -70,6 +70,7 @@ int main(int argc, char** argv) std::string password; std::string prefix("ws.test.v0"); std::string fields; + std::string gauge; std::string dsn; std::string redisHosts("127.0.0.1"); std::string redisPassword; @@ -264,6 +265,7 @@ int main(int argc, char** argv) cobra2statsd->add_option("--port", statsdPort, "Statsd port"); cobra2statsd->add_option("--prefix", prefix, "Statsd prefix"); cobra2statsd->add_option("--fields", fields, "Extract fields for naming the event")->join(); + cobra2statsd->add_option("--gauge", gauge, "Value to extract, and use as a statsd gauge")->join(); cobra2statsd->add_option("channel", channel, "Channel")->required(); cobra2statsd->add_flag("-v", verbose, "Verbose"); cobra2statsd->add_option("--pidfile", pidfile, "Pid file"); @@ -463,6 +465,7 @@ int main(int argc, char** argv) position, statsdClient, fields, + gauge, verbose, maxQueueSize, enableHeartbeat,