#include <netdb.h>
#include <poll.h>
+/* AIX doesn't have MSG_DONTWAIT */
+#ifndef MSG_DONTWAIT
+# define MSG_DONTWAIT MSG_NONBLOCK
+#endif
+
#ifndef STATSD_DEFAULT_NODE
# define STATSD_DEFAULT_NODE NULL
#endif
struct statsd_metric_s
{
metric_type_t type;
- int64_t value;
+ double value;
latency_counter_t *latency;
c_avl_tree_t *set;
unsigned long updates_num;
static double *conf_timer_percentile = NULL;
static size_t conf_timer_percentile_num = 0;
+static _Bool conf_timer_lower = 0;
+static _Bool conf_timer_upper = 0;
+static _Bool conf_timer_sum = 0;
+static _Bool conf_timer_count = 0;
+
/* Must hold metrics_lock when calling this function. */
static statsd_metric_t *statsd_metric_lookup_unsafe (char const *name, /* {{{ */
metric_type_t type)
return (metric);
} /* }}} statsd_metric_lookup_unsafe */
-static int statsd_metric_set (char const *name, int64_t value, /* {{{ */
+static int statsd_metric_set (char const *name, double value, /* {{{ */
metric_type_t type)
{
statsd_metric_t *metric;
return (0);
} /* }}} int statsd_metric_set */
-static int statsd_metric_add (char const *name, int64_t delta, /* {{{ */
+static int statsd_metric_add (char const *name, double delta, /* {{{ */
metric_type_t type)
{
statsd_metric_t *metric;
{
char *endptr = NULL;
- ret_value->derive = (derive_t) strtoll (str, &endptr, /* base = */ 0);
+ ret_value->gauge = (gauge_t) strtod (str, &endptr);
if ((str == endptr) || ((endptr != NULL) && (*endptr != 0)))
return (-1);
scale.gauge = 1.0;
if (extra != NULL)
{
- status = parse_value (extra + 1, &scale, DS_TYPE_GAUGE);
+ status = statsd_parse_value (extra + 1, &scale);
if (status != 0)
return (status);
return (-1);
}
- value.derive = 1;
+ value.gauge = 1.0;
status = statsd_parse_value (value_str, &value);
if (status != 0)
return (status);
- if (value.derive < 1)
- return (-1);
-
- return (statsd_metric_add (name,
- (int64_t) (((gauge_t) value.derive) / scale.gauge),
+ return (statsd_metric_add (name, (double) (value.gauge / scale.gauge),
STATSD_COUNTER));
} /* }}} int statsd_handle_counter */
value_t value;
int status;
- value.derive = 0;
+ value.gauge = 0;
status = statsd_parse_value (value_str, &value);
if (status != 0)
return (status);
if ((value_str[0] == '+') || (value_str[0] == '-'))
- return (statsd_metric_add (name, (int64_t) value.derive, STATSD_GAUGE));
+ return (statsd_metric_add (name, (double) value.gauge, STATSD_GAUGE));
else
- return (statsd_metric_set (name, (int64_t) value.derive, STATSD_GAUGE));
+ return (statsd_metric_set (name, (double) value.gauge, STATSD_GAUGE));
} /* }}} int statsd_handle_gauge */
static int statsd_handle_timer (char const *name, /* {{{ */
if (status != 0)
return (status);
- value = MS_TO_CDTIME_T (value_ms.derive);
+ value = MS_TO_CDTIME_T (value_ms.gauge);
pthread_mutex_lock (&metrics_lock);
cf_util_get_boolean (child, &conf_delete_gauges);
else if (strcasecmp ("DeleteSets", child->key) == 0)
cf_util_get_boolean (child, &conf_delete_sets);
+ else if (strcasecmp ("TimerLower", child->key) == 0)
+ cf_util_get_boolean (child, &conf_timer_lower);
+ else if (strcasecmp ("TimerUpper", child->key) == 0)
+ cf_util_get_boolean (child, &conf_timer_upper);
+ else if (strcasecmp ("TimerSum", child->key) == 0)
+ cf_util_get_boolean (child, &conf_timer_sum);
+ else if (strcasecmp ("TimerCount", child->key) == 0)
+ cf_util_get_boolean (child, &conf_timer_count);
else if (strcasecmp ("TimerPercentile", child->key) == 0)
statsd_config_timer_percentile (child);
else
{
pthread_mutex_lock (&metrics_lock);
if (metrics_tree == NULL)
- metrics_tree = c_avl_create ((void *) strcasecmp);
+ metrics_tree = c_avl_create ((void *) strcmp);
if (!network_thread_running)
{
latency_counter_get_average (metric->latency));
plugin_dispatch_values (&vl);
+ if (conf_timer_lower) {
+ ssnprintf (vl.type_instance, sizeof (vl.type_instance),
+ "%s-lower", name);
+ values[0].gauge = CDTIME_T_TO_DOUBLE (
+ latency_counter_get_min (metric->latency));
+ plugin_dispatch_values (&vl);
+ }
+
+ if (conf_timer_upper) {
+ ssnprintf (vl.type_instance, sizeof (vl.type_instance),
+ "%s-upper", name);
+ values[0].gauge = CDTIME_T_TO_DOUBLE (
+ latency_counter_get_max (metric->latency));
+ plugin_dispatch_values (&vl);
+ }
+
+ if (conf_timer_sum) {
+ ssnprintf (vl.type_instance, sizeof (vl.type_instance),
+ "%s-sum", name);
+ values[0].gauge = CDTIME_T_TO_DOUBLE (
+ latency_counter_get_sum (metric->latency));
+ plugin_dispatch_values (&vl);
+ }
+
for (i = 0; i < conf_timer_percentile_num; i++)
{
ssnprintf (vl.type_instance, sizeof (vl.type_instance),
plugin_dispatch_values (&vl);
}
+ /* Keep this at the end, since vl.type is set to "gauge" here. The
+ * vl.type's above are implicitly set to "latency". */
+ if (conf_timer_count) {
+ sstrncpy (vl.type, "gauge", sizeof (vl.type));
+ ssnprintf (vl.type_instance, sizeof (vl.type_instance),
+ "%s-count", name);
+ values[0].gauge = latency_counter_get_num (metric->latency);
+ plugin_dispatch_values (&vl);
+ }
+
latency_counter_reset (metric->latency);
return (0);
}