Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ using namespace Statsd;

int main() {
// Define the client on localhost, with port 8080, using a prefix and a batching size of 20 bytes
StatsdClient client{ "127.0.0.1", 8080, "myPrefix.", 20 };
StatsdClient client{ "127.0.0.1", 8080, "myPrefix", 20 };

// Increment the metric "coco"
client.increment("coco");
Expand Down Expand Up @@ -85,7 +85,7 @@ struct MyApp {
m_client.count("bar", 3);
}
private:
StatsdClient m_client{"localhost", 8125, "foo."};
StatsdClient m_client{"localhost", 8125, "foo"};
};

int main() {
Expand All @@ -110,12 +110,12 @@ using namespace Statsd;
int main()
{
// Define the client on localhost, with port 8080, using a prefix and a batching size of 20 bytes
StatsdClient client{ "127.0.0.1", 8080, "myPrefix.", 20 };
StatsdClient client{ "127.0.0.1", 8080, "myPrefix", 20 };

client.increment("coco");

// Set a new configuration, using a different port and a different prefix
client.setConfig("127.0.0.1", 8000, "anotherPrefix.");
client.setConfig("127.0.0.1", 8000, "anotherPrefix");

client.decrement("kiki");
}
Expand Down
34 changes: 29 additions & 5 deletions include/cpp-statsd-client/StatsdClient.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ namespace Statsd {
* This is the Statsd client, exposing the classic methods
* and relying on a UDP sender for the actual sending.
*
* The prefix for a stat is provided once at construction or
* on reconfiguring the client. The separator character '.'
* is automatically inserted between the prefix and the stats
* key, therefore you should neither append one to the prefix
* nor prepend one to the key
*
* The sampling frequency can be input, as well as the
* batching size. The latter is the optional limit in
* number of bytes a batch of stats can be before it is
Expand Down Expand Up @@ -86,11 +92,21 @@ class StatsdClient {
mutable std::mt19937 m_randomEngine;
};

namespace detail {
std::string sanitizePrefix(std::string prefix) {
// For convenience we provide the dot when generating the stat message
if (!prefix.empty() && prefix.back() == '.') {
prefix.pop_back();
}
return prefix;
}
} // namespace detail

inline StatsdClient::StatsdClient(const std::string& host,
const uint16_t port,
const std::string& prefix,
const uint64_t batchsize) noexcept
: m_prefix(prefix), m_sender(new UDPSender{host, port, batchsize}) {
: m_prefix(detail::sanitizePrefix(prefix)), m_sender(new UDPSender{host, port, batchsize}) {
// Initialize the random generator to be used for sampling
seed();
}
Expand All @@ -99,7 +115,7 @@ inline void StatsdClient::setConfig(const std::string& host,
const uint16_t port,
const std::string& prefix,
const uint64_t batchsize) noexcept {
m_prefix = prefix;
m_prefix = detail::sanitizePrefix(prefix);
m_sender.reset(new UDPSender(host, port, batchsize));
}

Expand Down Expand Up @@ -150,18 +166,26 @@ inline void StatsdClient::send(const std::string& key,
}

// Prepare the buffer and include the sampling rate if it's not 1.f
const bool needs_dot = !m_prefix.empty() && !key.empty();
std::string buffer(256, '\0');
int string_len = -1;
if (isFrequencyOne) {
// Sampling rate is 1.0f, no need to specify it
string_len = std::snprintf(
&buffer.front(), buffer.size(), "%s%s:%d|%s", m_prefix.c_str(), key.c_str(), value, type.c_str());
string_len = std::snprintf(&buffer.front(),
buffer.size(),
"%s%s%s:%d|%s",
m_prefix.c_str(),
needs_dot ? "." : "",
key.c_str(),
value,
type.c_str());
} else {
// Sampling rate is different from 1.0f, hence specify it
string_len = std::snprintf(&buffer.front(),
buffer.size(),
"%s%s:%d|%s|@%.2f",
"%s%s%s:%d|%s|@%.2f",
m_prefix.c_str(),
needs_dot ? "." : "",
key.c_str(),
value,
type.c_str(),
Expand Down
19 changes: 15 additions & 4 deletions tests/testStatsdClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,23 @@ void testReconfigure() {
throw std::runtime_error("Incorrect stat received");
}

client.setConfig("localhost", 8125, "second.");
client.setConfig("localhost", 8125, "second");
client.send("bar", 1, "c", 1.f);
if (server.receive() != "second.bar:1|c") {
throw std::runtime_error("Incorrect stat received");
}

client.setConfig("localhost", 8125, "");
client.send("third.baz", 1, "c", 1.f);
if (server.receive() != "third.baz:1|c") {
throw std::runtime_error("Incorrect stat received");
}

client.send("", 1, "c", 1.f);
if (server.receive() != ":1|c") {
throw std::runtime_error("Incorrect stat received");
}

// TODO: test what happens with the batching after resolving the question about incomplete
// batches being dropped vs sent on reconfiguring
}
Expand Down Expand Up @@ -90,7 +101,7 @@ void testSendRecv(uint64_t batchSize) {
throwOnError(client);
expected.emplace_back("sendRecv.kiki:-1|c");

// Adjusts "toto" by +3
// Adjusts "toto" by +2
client.seed(19); // this seed gets a hit on the first call
client.count("toto", 2, 0.1f);
throwOnError(client);
Expand All @@ -112,9 +123,9 @@ void testSendRecv(uint64_t batchSize) {
expected.emplace_back("sendRecv.myTiming:2|ms|@0.10");

// Send a metric explicitly
client.send("tutu", 4, "c", 2.0f);
client.send("tutu", 241, "c", 2.0f);

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was just because i thought it would be useful to exorcise some bigger numbers some times

throwOnError(client);
expected.emplace_back("sendRecv.tutu:4|c");
expected.emplace_back("sendRecv.tutu:241|c");
}

// Signal the mock server we are done
Expand Down