Skip to content

Commit

Permalink
Merge pull request #9 from Castaglia/metric-namespacing
Browse files Browse the repository at this point in the history
Support configuring prefix/suffix labels to the generated metric name…
  • Loading branch information
Castaglia committed Mar 25, 2017
2 parents bb73ef3 + 8ba2ac5 commit fdc5400
Show file tree
Hide file tree
Showing 8 changed files with 316 additions and 26 deletions.
12 changes: 8 additions & 4 deletions metric.c
Original file line number Diff line number Diff line change
Expand Up @@ -56,22 +56,26 @@ static int write_metric(struct statsd *statsd, const char *metric_type,
const char *name, const char *val_prefix, int64_t val, float sampling) {
int res, xerrno;
pool *p, *tmp_pool;
const char *prefix = NULL, *suffix = NULL;
char *metric;
size_t metric_len;

statsd_statsd_get_namespacing(statsd, &prefix, &suffix);
p = statsd_statsd_get_pool(statsd);
tmp_pool = make_sub_pool(p);

metric_len = STATSD_MAX_METRIC_SIZE;
metric = pcalloc(tmp_pool, metric_len);

if (sampling >= 1.0) {
res = snprintf(metric, metric_len-1, "%s:%s%lld|%s",
sanitize_name(tmp_pool, name), val_prefix, (long long) val, metric_type);
res = snprintf(metric, metric_len-1, "%s%s%s:%s%lld|%s",
prefix != NULL ? prefix : "", sanitize_name(tmp_pool, name),
suffix != NULL ? suffix : "", val_prefix, (long long) val, metric_type);

} else {
res = snprintf(metric, metric_len-1, "%s:%s%lld|%s|@%.2f",
sanitize_name(tmp_pool, name), val_prefix, (long long) val, metric_type,
res = snprintf(metric, metric_len-1, "%s%s%s:%s%lld|%s|@%.2f",
prefix != NULL ? prefix : "", sanitize_name(tmp_pool, name),
suffix != NULL ? suffix : "", val_prefix, (long long) val, metric_type,
sampling);
}

Expand Down
41 changes: 36 additions & 5 deletions mod_statsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,14 +144,18 @@ MODRET set_statsdsampling(cmd_rec *cmd) {
return PR_HANDLED(cmd);
}

/* usage: StatsdServer [scheme://]host[:port] */
/* usage: StatsdServer [scheme://]host[:port] [prefix] [suffix] */
MODRET set_statsdserver(cmd_rec *cmd) {
config_rec *c;
char *server, *ptr;
size_t server_len;
int port = STATSD_DEFAULT_PORT, use_tcp = FALSE;

CHECK_ARGS(cmd, 1);
if (cmd->argc < 2 ||
cmd->argc > 4) {
CONF_ERROR(cmd, "wrong number of parameters");
}

CHECK_CONF(cmd, CONF_ROOT|CONF_VIRTUAL|CONF_GLOBAL);

server = pstrdup(cmd->tmp_pool, cmd->argv[1]);
Expand Down Expand Up @@ -193,13 +197,37 @@ MODRET set_statsdserver(cmd_rec *cmd) {
}
}

c = add_config_param(cmd->argv[0], 3, NULL, NULL, NULL);
c = add_config_param(cmd->argv[0], 5, NULL, NULL, NULL, NULL, NULL);
c->argv[0] = pstrdup(c->pool, server);
c->argv[1] = palloc(c->pool, sizeof(int));
*((int *) c->argv[1]) = port;
c->argv[2] = pcalloc(c->pool, sizeof(int));
*((int *) c->argv[2]) = use_tcp;

if (cmd->argc > 2) {
char *prefix;

prefix = cmd->argv[2];
if (*prefix) {
/* Automatically append a '.' here, to make construction of the metric
* name easier.
*/
c->argv[3] = pstrcat(c->pool, prefix, ".", NULL);
}
}

if (cmd->argc == 4) {
char *suffix;

suffix = cmd->argv[3];
if (*suffix) {
/* Automatically prepend a '.' here, to make construction of the metric
* name easier.
*/
c->argv[4] = pstrcat(c->pool, ".", suffix, NULL);
}
}

return PR_HANDLED(cmd);
}

Expand Down Expand Up @@ -300,7 +328,7 @@ static void statsd_shutdown_ev(const void *event_data, void *user_data) {

static int statsd_sess_init(void) {
config_rec *c;
char *host, *metric;
char *host, *metric, *prefix = NULL, *suffix = NULL;
int port, use_tcp = FALSE;
const pr_netaddr_t *addr;

Expand Down Expand Up @@ -334,8 +362,11 @@ static int statsd_sess_init(void) {
pr_netaddr_set_port2((pr_netaddr_t *) addr, port);

use_tcp = *((int *) c->argv[2]);
prefix = c->argv[3];
suffix = c->argv[4];

statsd = statsd_statsd_open(session.pool, addr, use_tcp, statsd_sampling);
statsd = statsd_statsd_open(session.pool, addr, use_tcp, statsd_sampling,
prefix, suffix);
if (statsd == NULL) {
pr_log_pri(PR_LOG_NOTICE, MOD_STATSD_VERSION
": error opening statsd connection to %s%s:%d: %s",
Expand Down
19 changes: 18 additions & 1 deletion mod_statsd.html
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ <h3><a name="StatsdSampling">StatsdSampling</a></h3>

<hr>
<h3><a name="StatsdServer">StatsdServer</a></h3>
<strong>Syntax:</strong> StatsdServer <em>[scheme://]address[:port]</em><br>
<strong>Syntax:</strong> StatsdServer <em>[scheme://]address[:port] [prefix] [suffix]</em><br>
<strong>Default:</strong> None<br>
<strong>Context:</strong> server config, <code>&lt;VirtualHost&gt;</code>, <code>&lt;Global&gt;</code><br>
<strong>Module:</strong> mod_statsd<br>
Expand Down Expand Up @@ -115,6 +115,23 @@ <h3><a name="StatsdServer">StatsdServer</a></h3>
StatsdServer udp://[::ffff:1.2.3.4]:8125
</pre>

<p>
The <code>StatsdServer</code> directive also supports optional <em>prefix</em>
and <em>suffix</em> values. These are strings which will be used as prefixes
and suffixes to the metric names. For example:
<pre>
StatsdServer udp://1.2.3.4:8125 proftpd.prod ftp03
</pre>
This will use the prefix "proftpd.prod", and the suffix "ftp03", to generate
counter/timer metric names such as <code>proftpd.proftpd.command.PASS.230.ftp03</code>, instead of the default <code>command.PASS.230</code>. Other examples:
<pre>
# Use a prefix but no suffix for the metrics
StatsdServer udp://1.2.3.4:8125 proftpd.prod

# Use a suffix but no prefix for the metrics
StatsdServer udp://1.2.3.4:8125 "" ftp03
</pre>

<p>
<hr>
<h2><a name="Installation">Installation</a></h2>
Expand Down
39 changes: 38 additions & 1 deletion statsd.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ struct statsd {
/* Sampling */
float sampling;

/* Namespacing */
const char *prefix;
const char *suffix;

/* Pending metrics */
pool *metrics_pool;
char *metrics_buf;
Expand All @@ -48,7 +52,7 @@ static int statsd_proto_udp = IPPROTO_UDP;
static const char *trace_channel = "statsd.statsd";

struct statsd *statsd_statsd_open(pool *p, const pr_netaddr_t *addr,
int use_tcp, float sampling) {
int use_tcp, float sampling, const char *prefix, const char *suffix) {
int family, fd, xerrno;
pool *sub_pool;
struct statsd *statsd;
Expand Down Expand Up @@ -112,6 +116,14 @@ struct statsd *statsd_statsd_open(pool *p, const pr_netaddr_t *addr,
statsd->use_tcp = use_tcp;
statsd->sampling = sampling;

if (prefix != NULL) {
statsd->prefix = pstrdup(statsd->pool, prefix);
}

if (suffix != NULL) {
statsd->suffix = pstrdup(statsd->pool, suffix);
}

return statsd;
}

Expand All @@ -130,6 +142,31 @@ int statsd_statsd_close(struct statsd *statsd) {
return 0;
}

int statsd_statsd_get_namespacing(struct statsd *statsd, const char **prefix,
const char **suffix) {

if (statsd == NULL) {
errno = EINVAL;
return -1;
}

if (prefix == NULL &&
suffix == NULL) {
errno = EINVAL;
return -1;
}

if (prefix != NULL) {
*prefix = statsd->prefix;
}

if (suffix != NULL) {
*suffix = statsd->suffix;
}

return 0;
}

pool *statsd_statsd_get_pool(struct statsd *statsd) {
if (statsd == NULL) {
errno = EINVAL;
Expand Down
8 changes: 7 additions & 1 deletion statsd.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ struct statsd;
#define STATSD_MAX_METRIC_SIZE STATSD_MAX_UDP_PACKET_SIZE

struct statsd *statsd_statsd_open(pool *p, const pr_netaddr_t *addr,
int use_tcp, float sampling);
int use_tcp, float sampling, const char *prefix, const char *suffix);
int statsd_statsd_close(struct statsd *statsd);

int statsd_statsd_write(struct statsd *statsd, const char *metric,
Expand All @@ -51,6 +51,12 @@ int statsd_statsd_write(struct statsd *statsd, const char *metric,
/* Flush any buffered pending metrics */
int statsd_statsd_flush(struct statsd *statsd);

/* Returns a reference to the prefix/suffix labels, if any, for this statsd
* client.
*/
int statsd_statsd_get_namespacing(struct statsd *statsd, const char **prefix,
const char **suffix);

/* Returns a reference to pool used for the statsd client. */
pool *statsd_statsd_get_pool(struct statsd *statsd);

Expand Down
6 changes: 3 additions & 3 deletions t/api/metric.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ START_TEST (metric_counter_test) {
addr = statsd_addr(STATSD_DEFAULT_PORT);

mark_point();
statsd = statsd_statsd_open(p, addr, FALSE, 1.0);
statsd = statsd_statsd_open(p, addr, FALSE, 1.0, NULL, NULL);
fail_unless(statsd != NULL, "Failed to open statsd connection: %s",
strerror(errno));

Expand Down Expand Up @@ -112,7 +112,7 @@ START_TEST (metric_timer_test) {
addr = statsd_addr(STATSD_DEFAULT_PORT);

mark_point();
statsd = statsd_statsd_open(p, addr, FALSE, 1.0);
statsd = statsd_statsd_open(p, addr, FALSE, 1.0, NULL, NULL);
fail_unless(statsd != NULL, "Failed to open statsd connection: %s",
strerror(errno));

Expand Down Expand Up @@ -157,7 +157,7 @@ START_TEST (metric_gauge_test) {
addr = statsd_addr(STATSD_DEFAULT_PORT);

mark_point();
statsd = statsd_statsd_open(p, addr, FALSE, 1.0);
statsd = statsd_statsd_open(p, addr, FALSE, 1.0, NULL, NULL);
fail_unless(statsd != NULL, "Failed to open statsd connection: %s",
strerror(errno));

Expand Down
Loading

0 comments on commit fdc5400

Please sign in to comment.