diff --git a/.clang-format b/.clang-format new file mode 100644 index 0000000..54137e6 --- /dev/null +++ b/.clang-format @@ -0,0 +1,32 @@ +BasedOnStyle: Mozilla +ConstructorInitializerIndentWidth: 4 +ContinuationIndentWidth: 4 +IndentWidth: 4 +ColumnLimit: 180 +AlwaysBreakAfterDefinitionReturnType: None +AlwaysBreakAfterReturnType: None +AllowShortFunctionsOnASingleLine: false +AlignAfterOpenBracket: AlwaysBreak +AllowAllArgumentsOnNextLine: false +FixNamespaceComments: true +PenaltyBreakAssignment: 1000 +BreakBeforeBraces: Custom +BraceWrapping: + AfterCaseLabel: true + AfterClass: true + AfterControlStatement: Always + AfterEnum: true + AfterFunction: true + AfterNamespace: true + AfterObjCDeclaration: true + AfterStruct: true + AfterUnion: true + AfterExternBlock: true + BeforeCatch: true + BeforeElse: true +# BeforeLambdaBody: false +# BeforeWhile: true + IndentBraces: false + SplitEmptyFunction: true + SplitEmptyRecord: true + SplitEmptyNamespace: true \ No newline at end of file diff --git a/.gitignore b/.gitignore index 620d3dc..42afabf 100644 --- a/.gitignore +++ b/.gitignore @@ -1,13 +1 @@ -# Compiled Object files -*.slo -*.lo -*.o - -# Compiled Dynamic libraries -*.so -*.dylib - -# Compiled Static libraries -*.lai -*.la -*.a +/build \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 520a55b..de177f6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,21 +1,9 @@ -cmake_minimum_required (VERSION 3.2) -project (StatsdClient) +cmake_minimum_required(VERSION 3.2) -set (StatsdClient_VERSION_MAJOR 1) -set (StatsdClient_VERSION_MINOR 1) +project(StatsdClient LANGUAGES CXX) -include_directories ("src") -add_subdirectory ("src") +add_library(StatsdClient STATIC src/statsd_client.cpp) -configure_file ( - "src/StatsdClientConfig.h.in" - "StatsdClientConfig.h" - ) - -set_property (SOURCE "StatsdClientConfig.h" PROPERTY GENERATED TRUE) - -target_compile_features(StatsdClient PRIVATE cxx_nullptr) - -install (FILES "${PROJECT_BINARY_DIR}/StatsdClientConfig.h" - DESTINATION include) +target_include_directories(StatsdClient PUBLIC inc) +add_subdirectory(demo) \ No newline at end of file diff --git a/Makefile b/Makefile deleted file mode 100644 index 4a3700d..0000000 --- a/Makefile +++ /dev/null @@ -1,11 +0,0 @@ - -all: - make -C src/; - make -C demo/; - @for f in demo/*; do test -x $$f && cp -v $$f ./; done; echo - -clean: - make -C src/ clean; - make -C demo/ clean; - @rm -f ./system_monitor ./test_client - diff --git a/README.md b/README.md index 460ef13..f0861ae 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ 2. Next , build the generated `Visual Studio` solution. `StatsDClient.lib` will be built. ## API -See [header file](src/statsd_client.h) for more api detail. +See [header file](inc/statsd_client.h) for more api detail. ** Notice: this client is not thread-safe ** diff --git a/demo/CMakeLists.txt b/demo/CMakeLists.txt new file mode 100644 index 0000000..259be4c --- /dev/null +++ b/demo/CMakeLists.txt @@ -0,0 +1,5 @@ +add_executable(system_monitor system_monitor.cpp) +target_link_libraries(system_monitor StatsdClient) + +add_executable(test_client test_client.cpp) +target_link_libraries(test_client StatsdClient) \ No newline at end of file diff --git a/demo/Makefile b/demo/Makefile deleted file mode 100644 index 598efc8..0000000 --- a/demo/Makefile +++ /dev/null @@ -1,19 +0,0 @@ - -CXX=g++ -CPPFLAGS += -Wall -g - -STATSD_INC = -I ../src/ -STATSD_LIB = -L ../src/ -lstatsd_client -TARGETS=test_client system_monitor - -all: $(TARGETS) - -test_client: test_client.cpp - $(CXX) -o $@ $< $(CPPFLAGS) $(STATSD_INC) $(STATSD_LIB) - -system_monitor: system_monitor.cpp - $(CXX) -o $@ $< $(CPPFLAGS) $(STATSD_INC) $(STATSD_LIB) - -clean: - rm -f $(TARGETS) - diff --git a/demo/system_monitor.cpp b/demo/system_monitor.cpp index 6318105..2667870 100644 --- a/demo/system_monitor.cpp +++ b/demo/system_monitor.cpp @@ -1,23 +1,20 @@ +#include -#include +#include +#include #include #include -#include -#include #include -#include #include +#include +#include -#include -#include #include +#include #include +#include #include -#include "statsd_client.h" - -using namespace std; - static int running = 1; void sigterm(int sig) @@ -25,9 +22,10 @@ void sigterm(int sig) running = 0; } -string localhost() { +std::string localhost() +{ struct addrinfo hints, *info, *p; - string hostname(1024, '\0'); + std::string hostname(1024, '\0'); gethostname((char*)hostname.data(), hostname.capacity()); memset(&hints, 0, sizeof hints); @@ -35,15 +33,17 @@ string localhost() { hints.ai_socktype = SOCK_STREAM; hints.ai_flags = AI_CANONNAME; - if ( getaddrinfo(hostname.c_str(), "http", &hints, &info) == 0) { - for(p = info; p != NULL; p = p->ai_next) { + if (getaddrinfo(hostname.c_str(), "http", &hints, &info) == 0) + { + for (p = info; p != NULL; p = p->ai_next) + { hostname = p->ai_canonname; } freeaddrinfo(info); } - string::size_type pos = hostname.find("."); - while ( pos != string::npos ) + std::string::size_type pos = hostname.find("."); + while (pos != std::string::npos) { hostname[pos] = '_'; pos = hostname.find(".", pos); @@ -51,50 +51,52 @@ string localhost() { return hostname; } -vector& StringSplitTrim(const string& sData, - const string& sDelim, vector& vItems) +std::vector& StringSplitTrim(const std::string& sData, const std::string& sDelim, std::vector& vItems) { vItems.clear(); - string::size_type bpos = 0; - string::size_type epos = 0; - string::size_type nlen = sDelim.size(); + std::string::size_type bpos = 0; + std::string::size_type epos = 0; + std::string::size_type nlen = sDelim.size(); - while(sData.substr(epos,nlen) == sDelim) + while (sData.substr(epos, nlen) == sDelim) { epos += nlen; } bpos = epos; - while ((epos=sData.find(sDelim, epos)) != string::npos) + while ((epos = sData.find(sDelim, epos)) != std::string::npos) { - vItems.push_back(sData.substr(bpos, epos-bpos)); + vItems.push_back(sData.substr(bpos, epos - bpos)); epos += nlen; - while(sData.substr(epos,nlen) == sDelim) + while (sData.substr(epos, nlen) == sDelim) { epos += nlen; } bpos = epos; } - if(bpos != sData.size()) + if (bpos != sData.size()) { - vItems.push_back(sData.substr(bpos, sData.size()-bpos)); + vItems.push_back(sData.substr(bpos, sData.size() - bpos)); } return vItems; } -int main(int argc, char *argv[]) +int main(int argc, char* argv[]) { FILE *net, *stat; struct sysinfo si; char line[256]; - unsigned int user, nice, sys, idle, total, busy, old_total=0, old_busy=0; + unsigned int user, nice, sys, idle, total, busy, old_total = 0, old_busy = 0; - if (argc != 3) { - printf( "Usage: %s host port\n" - "Eg: %s 127.0.0.1 8125\n", - argv[0], argv[0]); + if (argc != 3) + { + printf( + "Usage: %s host port\n" + "Eg: %s 127.0.0.1 8125\n", + argv[0], + argv[0]); exit(1); } @@ -103,43 +105,50 @@ int main(int argc, char *argv[]) signal(SIGCHLD, SIG_IGN); /* will save one syscall per sleep */ signal(SIGTERM, sigterm); - if ( (net = fopen("/proc/net/dev", "r")) == NULL) { + if ((net = fopen("/proc/net/dev", "r")) == NULL) + { perror("fopen"); exit(-1); } - if ( (stat = fopen("/proc/stat", "r")) == NULL) { + if ((stat = fopen("/proc/stat", "r")) == NULL) + { perror("fopen"); exit(-1); } - string ns = string("host.") + localhost().c_str() + "."; + std::string ns = std::string("host.") + localhost().c_str() + "."; statsd::StatsdClient client(argv[1], atoi(argv[2]), ns); - daemon(0,0); + daemon(0, 0); printf("running in background.\n"); - while(running) { + while (running) + { rewind(net); - vector items; - while(!feof(net)) { + std::vector items; + while (!feof(net)) + { fgets(line, sizeof(line), net); StringSplitTrim(line, " ", items); - if ( items.size() < 17 ) continue; - if ( items[0].find(":") == string::npos ) continue; - if ( items[1] == "0" and items[9] == "0" ) continue; - - string netface = "network."+items[0].erase( items[0].find(":") ); - client.count( netface+".receive.bytes", atoll(items[1].c_str()) ); - client.count( netface+".receive.packets", atoll(items[2].c_str()) ); - client.count( netface+".transmit.bytes", atoll(items[9].c_str()) ); - client.count( netface+".transmit.packets", atoll(items[10].c_str()) ); + if (items.size() < 17) + continue; + if (items[0].find(":") == std::string::npos) + continue; + if (items[1] == "0" and items[9] == "0") + continue; + + std::string netface = "network." + items[0].erase(items[0].find(":")); + client.count(netface + ".receive.bytes", atoll(items[1].c_str())); + client.count(netface + ".receive.packets", atoll(items[2].c_str())); + client.count(netface + ".transmit.bytes", atoll(items[9].c_str())); + client.count(netface + ".transmit.packets", atoll(items[10].c_str())); } sysinfo(&si); - client.gauge("system.load", 100*si.loads[0]/0x10000); - client.gauge("system.freemem", si.freeram/1024); + client.gauge("system.load", 100 * si.loads[0] / 0x10000); + client.gauge("system.freemem", si.freeram / 1024); client.gauge("system.procs", si.procs); client.count("system.uptime", si.uptime); @@ -150,7 +159,7 @@ int main(int argc, char *argv[]) total = user + sys + idle; busy = user + sys; - client.send("system.cpu", 100 * (busy - old_busy)/(total - old_total), "g", 1.0); + // client.send("system.cpu", 100 * (busy - old_busy) / (total - old_total), "g", 1.0); old_total = total; old_busy = busy; diff --git a/demo/test_client.cpp b/demo/test_client.cpp index 9320305..f2c5e8a 100644 --- a/demo/test_client.cpp +++ b/demo/test_client.cpp @@ -1,27 +1,31 @@ +#include #include #include -#include "statsd_client.h" int main(void) { std::cout << "running..." << std::endl; statsd::StatsdClient client; - statsd::StatsdClient client2("127.0.0.1", 8125, "myproject.abx."); + statsd::StatsdClient client2{ "127.0.0.1", 8125, "myproject.abx." }; + + client.event({ "An error occurred", "Error message", statsd::Event::Type::error, { "env:dev" } }); client.count("count1", 123, 1.0); client.count("count2", 125, 1.0); client.gauge("speed", 10); client2.timing("request", 2400); + sleep(1); + client.inc("count1", 1.0); client2.dec("count2", 1.0); - int i; - for(i=0; i<10; i++) { + + for (int i = 0; i < 10; i++) + { client2.count("count3", i, 0.8); } std::cout << "done" << std::endl; - return 0; } diff --git a/inc/statsd_client.h b/inc/statsd_client.h new file mode 100644 index 0000000..987f6fa --- /dev/null +++ b/inc/statsd_client.h @@ -0,0 +1,113 @@ + +#ifndef STATSD_CLIENT_H +#define STATSD_CLIENT_H + +#include +#include + +namespace statsd +{ +class Event +{ + public: + enum class Type + { + info, + success, + warning, + error + }; + + enum class Priority + { + normal, + low + }; + + using tags_t = std::vector; + + private: + std::string title_; + std::string text_; + unsigned int timestamp_{ 0 }; + std::string hostname_; + std::string aggregation_Key_; + Priority priority_{ Priority::normal }; + std::string source_type_name_; + Type type_{ Type::info }; + tags_t tags_; + + public: + Event(std::string title, std::string text, Type type = Type::info, tags_t tags = tags_t{}); + + void set_timestamp(unsigned int timestamp) + { + timestamp_ = timestamp; + } + void set_hostname(std::string hostname) + { + hostname_ = hostname; + } + void set_aggregation_Key(std::string aggregation_Key) + { + aggregation_Key_ = aggregation_Key; + } + void set_priority(Priority priority) + { + priority_ = priority; + } + void set_source_type_name(std::string source_type_name) + { + source_type_name_ = source_type_name; + } + + std::string serialize() const; +}; + +class StatsdClient +{ + public: + StatsdClient(const std::string& host = "127.0.0.1", int port = 8125, const std::string& ns = ""); + ~StatsdClient(); + + using tags_t = std::vector; + + public: + // you can config at anytime; client will use new address (useful for Singleton) + void config(const std::string& host, int port, const std::string& ns = ""); + const char* errmsg(); + + public: + int inc(const std::string& key, float sample_rate = 1.0, tags_t = tags_t(0)); + int dec(const std::string& key, float sample_rate = 1.0, tags_t = tags_t(0)); + int count(const std::string& key, size_t value, float sample_rate = 1.0, tags_t = tags_t(0)); + int gauge(const std::string& key, size_t value, float sample_rate = 1.0, tags_t = tags_t(0)); + int timing(const std::string& key, size_t ms, float sample_rate = 1.0, tags_t = tags_t(0)); + int event(const Event& event); + + public: + /** + * (Low Level Api) manually send a message + * which might be composed of several lines. + */ + int send(const std::string& message); + + /* (Low Level Api) manually send a message + * type = "c", "g" or "ms" + */ + int send(std::string key, size_t value, const std::string& type, float sample_rate, tags_t tags); + + protected: + int init(); + void cleanup(std::string& key); + + protected: + struct StatsdClientData; + StatsdClientData* d; + + private: + bool should_send(float sample_rate); +}; +}; // namespace statsd + +#endif \ No newline at end of file diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt deleted file mode 100644 index 197b1b5..0000000 --- a/src/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -add_library(StatsdClient statsd_client.cpp) - -include_directories(${PROJECT_BINARY_DIR}) - -install (TARGETS StatsdClient DESTINATION lib) -install (FILES statsd_client.h DESTINATION include) diff --git a/src/StatsdClientConfig.h.in b/src/StatsdClientConfig.h.in deleted file mode 100644 index 37dc48d..0000000 --- a/src/StatsdClientConfig.h.in +++ /dev/null @@ -1,2 +0,0 @@ -#define StatsdClient_VERSION_MAJOR @StatsdClient_VERSION_MAJOR@ -#define StatsdClient_VERSION_MINOR @StatsdClient_VERSION_MINOR@ diff --git a/src/statsd_client.cpp b/src/statsd_client.cpp index 9f04e32..36ffb85 100644 --- a/src/statsd_client.cpp +++ b/src/statsd_client.cpp @@ -1,79 +1,156 @@ +#include + #include -#include +#include +#include #include #include -#include #include -#include -#include "statsd_client.h" - +#include /* platform-specific headers */ #ifdef _WIN32 - #include - #include - #define CLOSE_SOCKET(s) closesocket(s) +#include +#include +#define CLOSE_SOCKET(s) closesocket(s) #else - #include - #include - #include /* Needed for getaddrinfo() and freeaddrinfo() */ - #include /* Needed for close() */ - - #define CLOSE_SOCKET(s) close(s) +#include +#include /* Needed for getaddrinfo() and freeaddrinfo() */ +#include +#include /* Needed for close() */ +#define CLOSE_SOCKET(s) close(s) #endif -using namespace std; -namespace statsd { - -inline bool fequal(float a, float b) +namespace statsd +{ +Event::Event(std::string title, std::string text, Event::Type type, tags_t tags) + : title_{ title } + , text_{ text } + , type_{ type } + , tags_{ tags } { - const float epsilon = 0.0001; - return ( fabs(a - b) < epsilon ); } -struct _StatsdClientData { - int sock; - struct sockaddr_in server; +std::string Event::serialize() const +{ + std::string message; + + const auto e_text = [&] { + std::string str; + for (const char c : text_) + { + if (c == '\n') + str.append("\\n"); + else + str.push_back(c); + } + return str; + }(); - string ns; - string host; - short port; - bool init; + message += "_e{" + std::to_string(title_.size()) + "," + std::to_string(e_text.size()) + "}:" + title_ + "|" + e_text; - std::default_random_engine rng_engine; - std::uniform_real_distribution<> rng_dist; + if (timestamp_ != 0) + message += "|d:" + std::to_string(timestamp_); + if (hostname_ != "") + message += "|h:" + hostname_; - char errmsg[1024]; -}; + if (aggregation_Key_ != "") + message += "|k:" + aggregation_Key_; -inline bool should_send(_StatsdClientData* d, float sample_rate) -{ - if ( fequal(sample_rate, 1.0) ) + switch (priority_) { - return true; + case Priority::low: + message += "|p:low"; + break; + case Priority::normal: + message += "|p:normal"; + break; } - float p = d->rng_dist(d->rng_engine); - return sample_rate > p; + if (source_type_name_ != "") + message += "|s:" + source_type_name_; + + switch (type_) + { + case Type::info: + message += "|t:info"; + break; + case Type::success: + message += "|t:success"; + break; + case Type::warning: + message += "|t:warning"; + break; + case Type::error: + message += "|t:error"; + break; + } + + if (!tags_.empty()) + { + message += "|#"; + for (std::size_t i = 0, size = tags_.size(); i < size; ++i) + { + message += tags_[i]; + if (i < size - 1) + message += ","; + } + } + + return message; +} + +inline bool fequal(float a, float b) +{ + const float epsilon = 0.0001; + return (fabs(a - b) < epsilon); } -StatsdClient::StatsdClient(const string& host, int port, const string& ns) +struct StatsdClient::StatsdClientData +{ + int sock; + struct sockaddr_in server; + + std::string ns; + std::string host; + short port; + bool init; + + std::default_random_engine rng_engine; + std::uniform_real_distribution<> rng_dist; + + char errmsg[1024]; +}; + +StatsdClient::StatsdClient(const std::string& host, int port, const std::string& ns) { - d = new _StatsdClientData; + d = new StatsdClientData; d->sock = -1; std::random_device rd; - d->rng_engine = std::default_random_engine(rd () ); + d->rng_engine = std::default_random_engine(rd()); d->rng_dist = std::uniform_real_distribution<>(0.0f, 1.0f); config(host, port, ns); } +bool StatsdClient::should_send(float sample_rate) +{ + if (fequal(sample_rate, 1.0)) + { + return true; + } + + float p = d->rng_dist(d->rng_engine); + return sample_rate > p; +} + StatsdClient::~StatsdClient() { // close socket - if (d->sock >= 0) { + if (d->sock >= 0) + { CLOSE_SOCKET(d->sock); d->sock = -1; delete d; @@ -81,13 +158,14 @@ StatsdClient::~StatsdClient() } } -void StatsdClient::config(const string& host, int port, const string& ns) +void StatsdClient::config(const std::string& host, int port, const std::string& ns) { d->ns = ns; d->host = host; d->port = port; d->init = false; - if ( d->sock >= 0 ) { + if (d->sock >= 0) + { CLOSE_SOCKET(d->sock); } d->sock = -1; @@ -95,10 +173,12 @@ void StatsdClient::config(const string& host, int port, const string& ns) int StatsdClient::init() { - if ( d->init ) return 0; + if (d->init) + return 0; d->sock = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if ( d->sock == -1 ) { + if (d->sock == -1) + { snprintf(d->errmsg, sizeof(d->errmsg), "could not create socket, err=%m"); return -1; } @@ -115,9 +195,9 @@ int StatsdClient::init() // looks up IPv4/IPv6 address by host name or stringized IP address int ret = getaddrinfo(d->host.c_str(), NULL, &hints, &result); - if ( ret ) { - snprintf(d->errmsg, sizeof(d->errmsg), - "getaddrinfo fail, error=%d, msg=%s", ret, gai_strerror(ret) ); + if (ret) + { + snprintf(d->errmsg, sizeof(d->errmsg), "getaddrinfo fail, error=%d, msg=%s", ret, gai_strerror(ret)); return -2; } struct sockaddr_in* host_addr = (struct sockaddr_in*)result->ai_addr; @@ -129,87 +209,94 @@ int StatsdClient::init() } /* will change the original string */ -void StatsdClient::cleanup(string& key) +void StatsdClient::cleanup(std::string& key) { size_t pos = key.find_first_of(":|@"); - while ( pos != string::npos ) + while (pos != std::string::npos) { key[pos] = '_'; pos = key.find_first_of(":|@"); } } -int StatsdClient::dec(const string& key, float sample_rate, tags_t tags) +int StatsdClient::dec(const std::string& key, float sample_rate, tags_t tags) { return count(key, -1, sample_rate, tags); } -int StatsdClient::inc(const string& key, float sample_rate, tags_t tags) +int StatsdClient::inc(const std::string& key, float sample_rate, tags_t tags) { return count(key, 1, sample_rate, tags); } -int StatsdClient::count(const string& key, size_t value, float sample_rate, tags_t tags) +int StatsdClient::count(const std::string& key, size_t value, float sample_rate, tags_t tags) { return send(key, value, "c", sample_rate, tags); } -int StatsdClient::gauge(const string& key, size_t value, float sample_rate, tags_t tags) +int StatsdClient::gauge(const std::string& key, size_t value, float sample_rate, tags_t tags) { return send(key, value, "g", sample_rate, tags); } -int StatsdClient::timing(const string& key, size_t ms, float sample_rate, tags_t tags) +int StatsdClient::timing(const std::string& key, size_t ms, float sample_rate, tags_t tags) { return send(key, ms, "ms", sample_rate, tags); } -int StatsdClient::send(string key, size_t value, const string &type, float sample_rate, tags_t tags) +int StatsdClient::event(const Event& event) +{ + return send(event.serialize()); +} + +int StatsdClient::send(std::string key, size_t value, const std::string& type, float sample_rate, tags_t tags) { - if (!should_send(this->d, sample_rate)) { + if (!should_send(sample_rate)) + { return 0; } cleanup(key); std::string tags_str; - if (!tags.empty()) { + if (!tags.empty()) + { tags_str.reserve(256); tags_str += "|#"; - for(std::size_t i = 0, size = tags.size(); i < size; ++i) { + for (std::size_t i = 0, size = tags.size(); i < size; ++i) + { tags_str += tags[i]; - if (i < size -1 ) { + if (i < size - 1) + { tags_str += ","; } } } char buf[256]; - if ( fequal( sample_rate, 1.0 ) ) + if (fequal(sample_rate, 1.0)) { - snprintf(buf, sizeof(buf), "%s%s:%zd|%s%s", - d->ns.c_str(), key.c_str(), value, type.c_str(), tags_str.c_str()); + snprintf(buf, sizeof(buf), "%s%s:%zd|%s%s", d->ns.c_str(), key.c_str(), value, type.c_str(), tags_str.c_str()); } else { - snprintf(buf, sizeof(buf), "%s%s:%zd|%s|@%.2f%s", - d->ns.c_str(), key.c_str(), value, type.c_str(), sample_rate, tags_str.c_str()); + snprintf(buf, sizeof(buf), "%s%s:%zd|%s|@%.2f%s", d->ns.c_str(), key.c_str(), value, type.c_str(), sample_rate, tags_str.c_str()); } return send(buf); } -int StatsdClient::send(const string &message) +int StatsdClient::send(const std::string& message) { int ret = init(); - if ( ret ) + if (ret) { return ret; } - ret = sendto(d->sock, message.data(), message.size(), 0, (struct sockaddr *) &d->server, sizeof(d->server)); - if ( ret == -1) { - snprintf(d->errmsg, sizeof(d->errmsg), - "sendto server fail, host=%s:%d, err=%m", d->host.c_str(), d->port); + ret = sendto(d->sock, message.data(), message.size(), 0, (struct sockaddr*)&d->server, sizeof(d->server)); + if (ret == -1) + { + snprintf(d->errmsg, sizeof(d->errmsg), "sendto server fail, host=%s:%d, err=%m", d->host.c_str(), d->port); return -1; } return 0; @@ -219,6 +306,4 @@ const char* StatsdClient::errmsg() { return d->errmsg; } - -} - +} // namespace statsd \ No newline at end of file diff --git a/src/statsd_client.h b/src/statsd_client.h deleted file mode 100644 index d57d78f..0000000 --- a/src/statsd_client.h +++ /dev/null @@ -1,56 +0,0 @@ - -#ifndef STATSD_CLIENT_H -#define STATSD_CLIENT_H - -#include -#include -#include - - -namespace statsd { - -struct _StatsdClientData; - -class StatsdClient { - public: - StatsdClient(const std::string& host="127.0.0.1", int port=8125, const std::string& ns = ""); - ~StatsdClient(); - - using tags_t = std::vector; - - public: - // you can config at anytime; client will use new address (useful for Singleton) - void config(const std::string& host, int port, const std::string& ns = ""); - const char* errmsg(); - - public: - int inc(const std::string& key, float sample_rate = 1.0, tags_t = tags_t(0)); - int dec(const std::string& key, float sample_rate = 1.0, tags_t = tags_t(0)); - int count(const std::string& key, size_t value, float sample_rate = 1.0, tags_t = tags_t(0)); - int gauge(const std::string& key, size_t value, float sample_rate = 1.0, tags_t = tags_t(0)); - int timing(const std::string& key, size_t ms, float sample_rate = 1.0, tags_t = tags_t(0)); - - public: - /** - * (Low Level Api) manually send a message - * which might be composed of several lines. - */ - int send(const std::string& message); - - /* (Low Level Api) manually send a message - * type = "c", "g" or "ms" - */ - int send(std::string key, size_t value, - const std::string& type, float sample_rate, tags_t tags); - - protected: - int init(); - void cleanup(std::string& key); - - protected: - struct _StatsdClientData* d; -}; - -}; // end namespace - -#endif