You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by zw...@apache.org on 2019/11/04 23:04:31 UTC
[trafficserver] branch 9.0.x updated: Rewrote remap_stats plugin to
use C++
This is an automated email from the ASF dual-hosted git repository.
zwoop pushed a commit to branch 9.0.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
The following commit(s) were added to refs/heads/9.0.x by this push:
new 0932b0a Rewrote remap_stats plugin to use C++
0932b0a is described below
commit 0932b0ae864924a644baa66ab6b51aef92a78b67
Author: Silvano Cerza <si...@gmail.com>
AuthorDate: Thu Oct 10 16:57:40 2019 +0200
Rewrote remap_stats plugin to use C++
(cherry picked from commit a42e61f725d52c6c976c0ab1a03bfe2e77b95c69)
---
plugins/experimental/remap_stats/Makefile.inc | 2 +-
.../remap_stats/{remap_stats.c => remap_stats.cc} | 136 +++++++++------------
2 files changed, 56 insertions(+), 82 deletions(-)
diff --git a/plugins/experimental/remap_stats/Makefile.inc b/plugins/experimental/remap_stats/Makefile.inc
index 9cf318e..ce92258 100644
--- a/plugins/experimental/remap_stats/Makefile.inc
+++ b/plugins/experimental/remap_stats/Makefile.inc
@@ -17,4 +17,4 @@
pkglib_LTLIBRARIES += experimental/remap_stats/remap_stats.la
experimental_remap_stats_remap_stats_la_SOURCES = \
- experimental/remap_stats/remap_stats.c
+ experimental/remap_stats/remap_stats.cc
diff --git a/plugins/experimental/remap_stats/remap_stats.c b/plugins/experimental/remap_stats/remap_stats.cc
similarity index 65%
rename from plugins/experimental/remap_stats/remap_stats.c
rename to plugins/experimental/remap_stats/remap_stats.cc
index 79c9315..43df970 100644
--- a/plugins/experimental/remap_stats/remap_stats.c
+++ b/plugins/experimental/remap_stats/remap_stats.cc
@@ -21,57 +21,42 @@
#include "tscore/ink_config.h"
#include "tscore/ink_defs.h"
+#include "tscore/BufferWriter.h"
#include "ts/ts.h"
-#include <stdint.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdio.h>
-#include <getopt.h>
-#include <search.h>
+
+#include <string>
+#include <string_view>
+#include <unordered_map>
#define PLUGIN_NAME "remap_stats"
#define DEBUG_TAG PLUGIN_NAME
#define MAX_STAT_LENGTH (1 << 8)
-typedef struct {
+struct config_t {
bool post_remap_host;
int txn_slot;
TSStatPersistence persist_type;
TSMutex stat_creation_mutex;
-} config_t;
+};
// From "core".... sigh, but we need it for now at least.
extern int max_records_entries;
static void
-stat_add(char *name, TSMgmtInt amount, TSStatPersistence persist_type, TSMutex create_mutex)
+stat_add(const char *name, TSMgmtInt amount, TSStatPersistence persist_type, TSMutex create_mutex)
{
int stat_id = -1;
- ENTRY search, *result = NULL;
- static __thread struct hsearch_data stat_cache;
- static __thread bool hash_init = false;
-
- if (unlikely(!hash_init)) {
- // NOLINTNEXTLINE
- hcreate_r(max_records_entries << 1, &stat_cache); // This is weird, but oh well.
- hash_init = true;
- TSDebug(DEBUG_TAG, "stat cache hash init");
- }
-
- search.key = name;
- search.data = 0;
- // NOLINTNEXTLINE
- hsearch_r(search, FIND, &result, &stat_cache);
+ static thread_local std::unordered_map<std::string, int> hash;
- if (unlikely(result == NULL)) {
+ if (unlikely(hash.find(name) == hash.cend())) {
// This is an unlikely path because we most likely have the stat cached
// so this mutex won't be much overhead and it fixes a race condition
// in the RecCore. Hopefully this can be removed in the future.
TSMutexLock(create_mutex);
- if (TS_ERROR == TSStatFindName((const char *)name, &stat_id)) {
- stat_id = TSStatCreate((const char *)name, TS_RECORDDATATYPE_INT, persist_type, TS_STAT_SYNC_SUM);
+ if (TS_ERROR == TSStatFindName(name, &stat_id)) {
+ stat_id = TSStatCreate(name, TS_RECORDDATATYPE_INT, persist_type, TS_STAT_SYNC_SUM);
if (stat_id == TS_ERROR) {
TSDebug(DEBUG_TAG, "Error creating stat_name: %s", name);
} else {
@@ -81,14 +66,11 @@ stat_add(char *name, TSMgmtInt amount, TSStatPersistence persist_type, TSMutex c
TSMutexUnlock(create_mutex);
if (stat_id >= 0) {
- search.key = TSstrdup(name);
- search.data = (void *)((intptr_t)stat_id);
- // NOLINTNEXTLINE
- hsearch_r(search, ENTER, &result, &stat_cache);
+ hash.emplace(name, stat_id);
TSDebug(DEBUG_TAG, "Cached stat_name: %s stat_id: %d", name, stat_id);
}
} else {
- stat_id = (int)((intptr_t)result->data);
+ stat_id = hash.at(name);
}
if (likely(stat_id >= 0)) {
@@ -130,7 +112,7 @@ handle_read_req_hdr(TSCont cont, TSEvent event ATS_UNUSED, void *edata)
config_t *config;
void *txnd;
- config = (config_t *)TSContDataGet(cont);
+ config = static_cast<config_t *>(TSContDataGet(cont));
txnd = (void *)get_effective_host(txn); // low bit left 0 because we do not know that remap succeeded yet
TSHttpTxnArgSet(txn, config->txn_slot, txnd);
@@ -142,11 +124,11 @@ handle_read_req_hdr(TSCont cont, TSEvent event ATS_UNUSED, void *edata)
static int
handle_post_remap(TSCont cont, TSEvent event ATS_UNUSED, void *edata)
{
- TSHttpTxn txn = (TSHttpTxn)edata;
+ TSHttpTxn txn = static_cast<TSHttpTxn>(edata);
config_t *config;
void *txnd = (void *)0x01; // low bit 1 because we are post remap and thus success
- config = (config_t *)TSContDataGet(cont);
+ config = static_cast<config_t *>(TSContDataGet(cont));
if (config->post_remap_host) {
TSHttpTxnArgSet(txn, config->txn_slot, txnd);
@@ -160,29 +142,35 @@ handle_post_remap(TSCont cont, TSEvent event ATS_UNUSED, void *edata)
return 0;
}
-#define CREATE_STAT_NAME(s, h, b) snprintf(s, MAX_STAT_LENGTH, "plugin.%s.%s.%s", PLUGIN_NAME, h, b)
+static void
+create_stat_name(ts::LocalBufferWriter<MAX_STAT_LENGTH> &stat_name, std::string_view h, std::string_view b)
+{
+ stat_name.reset().reduce(1);
+ stat_name.print("plugin.{}.{}.{}", PLUGIN_NAME, h, b);
+ stat_name.extend(1).write('\0');
+}
static int
handle_txn_close(TSCont cont, TSEvent event ATS_UNUSED, void *edata)
{
- TSHttpTxn txn = (TSHttpTxn)edata;
+ TSHttpTxn txn = static_cast<TSHttpTxn>(edata);
config_t *config;
void *txnd;
int status_code = 0;
TSMBuffer buf;
TSMLoc hdr_loc;
uint64_t out_bytes, in_bytes;
- char *remap, *hostname;
- char *unknown = "unknown";
- char stat_name[MAX_STAT_LENGTH];
+ std::string_view remap, hostname;
+ std::string_view unknown("unknown");
+ ts::LocalBufferWriter<MAX_STAT_LENGTH> stat_name;
- config = (config_t *)TSContDataGet(cont);
+ config = static_cast<config_t *>(TSContDataGet(cont));
txnd = TSHttpTxnArgGet(txn, config->txn_slot);
- hostname = (char *)((uintptr_t)txnd & (~((uintptr_t)0x01))); // Get hostname
+ hostname = std::string_view(reinterpret_cast<char *>(reinterpret_cast<uintptr_t>(txnd) & ~0x01)); // Get hostname
if (txnd) {
- if ((uintptr_t)txnd & 0x01) // remap succeeded?
+ if (reinterpret_cast<uintptr_t>(txnd) & 0x01) // remap succeeded?
{
if (!config->post_remap_host) {
remap = hostname;
@@ -190,51 +178,45 @@ handle_txn_close(TSCont cont, TSEvent event ATS_UNUSED, void *edata)
remap = get_effective_host(txn);
}
- if (!remap) {
+ if (remap.empty()) {
remap = unknown;
}
in_bytes = TSHttpTxnClientReqHdrBytesGet(txn);
in_bytes += TSHttpTxnClientReqBodyBytesGet(txn);
- CREATE_STAT_NAME(stat_name, remap, "in_bytes");
- stat_add(stat_name, (TSMgmtInt)in_bytes, config->persist_type, config->stat_creation_mutex);
+ create_stat_name(stat_name, remap, "in_bytes");
+ stat_add(stat_name.data(), static_cast<TSMgmtInt>(in_bytes), config->persist_type, config->stat_creation_mutex);
out_bytes = TSHttpTxnClientRespHdrBytesGet(txn);
out_bytes += TSHttpTxnClientRespBodyBytesGet(txn);
- CREATE_STAT_NAME(stat_name, remap, "out_bytes");
- stat_add(stat_name, (TSMgmtInt)out_bytes, config->persist_type, config->stat_creation_mutex);
+ create_stat_name(stat_name, remap, "out_bytes");
+ stat_add(stat_name.data(), static_cast<TSMgmtInt>(out_bytes), config->persist_type, config->stat_creation_mutex);
if (TSHttpTxnClientRespGet(txn, &buf, &hdr_loc) == TS_SUCCESS) {
- status_code = (int)TSHttpHdrStatusGet(buf, hdr_loc);
+ status_code = static_cast<int>(TSHttpHdrStatusGet(buf, hdr_loc));
TSHandleMLocRelease(buf, TS_NULL_MLOC, hdr_loc);
if (status_code < 200) {
- CREATE_STAT_NAME(stat_name, remap, "status_other");
+ create_stat_name(stat_name, remap, "status_other");
} else if (status_code <= 299) {
- CREATE_STAT_NAME(stat_name, remap, "status_2xx");
+ create_stat_name(stat_name, remap, "status_2xx");
} else if (status_code <= 399) {
- CREATE_STAT_NAME(stat_name, remap, "status_3xx");
+ create_stat_name(stat_name, remap, "status_3xx");
} else if (status_code <= 499) {
- CREATE_STAT_NAME(stat_name, remap, "status_4xx");
+ create_stat_name(stat_name, remap, "status_4xx");
} else if (status_code <= 599) {
- CREATE_STAT_NAME(stat_name, remap, "status_5xx");
+ create_stat_name(stat_name, remap, "status_5xx");
} else {
- CREATE_STAT_NAME(stat_name, remap, "status_other");
+ create_stat_name(stat_name, remap, "status_other");
}
- stat_add(stat_name, 1, config->persist_type, config->stat_creation_mutex);
+ stat_add(stat_name.data(), 1, config->persist_type, config->stat_creation_mutex);
} else {
- CREATE_STAT_NAME(stat_name, remap, "status_unknown");
- stat_add(stat_name, 1, config->persist_type, config->stat_creation_mutex);
- }
-
- if (remap != unknown) {
- TSfree(remap);
+ create_stat_name(stat_name, remap, "status_unknown");
+ stat_add(stat_name.data(), 1, config->persist_type, config->stat_creation_mutex);
}
- } else if (hostname) {
- TSfree(hostname);
}
}
@@ -248,7 +230,6 @@ TSPluginInit(int argc, const char *argv[])
{
TSPluginRegistrationInfo info;
TSCont pre_remap_cont, post_remap_cont, global_cont;
- config_t *config;
info.plugin_name = PLUGIN_NAME;
info.vendor_name = "Apache Software Foundation";
@@ -262,28 +243,21 @@ TSPluginInit(int argc, const char *argv[])
TSDebug(DEBUG_TAG, "Plugin registration succeeded");
}
- config = TSmalloc(sizeof(config_t));
+ auto config = new config_t;
config->post_remap_host = false;
config->persist_type = TS_STAT_NON_PERSISTENT;
config->stat_creation_mutex = TSMutexCreate();
if (argc > 1) {
- int c;
- static const struct option longopts[] = {
- {"post-remap-host", no_argument, NULL, 'P'}, {"persistent", no_argument, NULL, 'p'}, {NULL, 0, NULL, 0}};
-
- while ((c = getopt_long(argc, (char *const *)argv, "Pp", longopts, NULL)) != -1) {
- switch (c) {
- case 'P':
+ // Argument parser
+ for (auto i = 0; i < argc; i++) {
+ const std::string arg(argv[i]);
+ if (arg == "-P" || arg == "--post-remap-host") {
config->post_remap_host = true;
TSDebug(DEBUG_TAG, "Using post remap hostname");
- break;
- case 'p':
+ } else if (arg == "-p" || arg == "--persistent") {
config->persist_type = TS_STAT_PERSISTENT;
TSDebug(DEBUG_TAG, "Using persistent stats");
- break;
- default:
- break;
}
}
}
@@ -292,16 +266,16 @@ TSPluginInit(int argc, const char *argv[])
if (!config->post_remap_host) {
pre_remap_cont = TSContCreate(handle_read_req_hdr, NULL);
- TSContDataSet(pre_remap_cont, (void *)config);
+ TSContDataSet(pre_remap_cont, static_cast<void *>(config));
TSHttpHookAdd(TS_HTTP_READ_REQUEST_HDR_HOOK, pre_remap_cont);
}
post_remap_cont = TSContCreate(handle_post_remap, NULL);
- TSContDataSet(post_remap_cont, (void *)config);
+ TSContDataSet(post_remap_cont, static_cast<void *>(config));
TSHttpHookAdd(TS_HTTP_POST_REMAP_HOOK, post_remap_cont);
global_cont = TSContCreate(handle_txn_close, NULL);
- TSContDataSet(global_cont, (void *)config);
+ TSContDataSet(global_cont, static_cast<void *>(config));
TSHttpHookAdd(TS_HTTP_TXN_CLOSE_HOOK, global_cont);
TSDebug(DEBUG_TAG, "Init complete");