/** * Streaming callback to format our output */ static int stream_formatter(FILE *pipe, void *data, metric_type type, char *name, void *value) { #define STREAM(...) if (fprintf(pipe, __VA_ARGS__, (long long)tv->tv_sec) < 0) return 1; struct timeval *tv = data; switch (type) { case KEY_VAL: STREAM("kv.%s|%f|%lld\n", name, *(double*)value); break; case COUNTER: STREAM("counts.%s|%f|%lld\n", name, counter_sum(value)); break; case TIMER: STREAM("timers.%s.sum|%f|%lld\n", name, timer_sum(value)); STREAM("timers.%s.mean|%f|%lld\n", name, timer_mean(value)); STREAM("timers.%s.lower|%f|%lld\n", name, timer_min(value)); STREAM("timers.%s.upper|%f|%lld\n", name, timer_max(value)); STREAM("timers.%s.count|%lld|%lld\n", name, timer_count(value)); STREAM("timers.%s.stdev|%f|%lld\n", name, timer_stddev(value)); STREAM("timers.%s.median|%f|%lld\n", name, timer_query(value, 0.5)); STREAM("timers.%s.p95|%f|%lld\n", name, timer_query(value, 0.95)); STREAM("timers.%s.p99|%f|%lld\n", name, timer_query(value, 0.99)); break; default: syslog(LOG_ERR, "Unknown metric type: %d", type); break; } return 0; }
static int stream_formatter_bin(FILE *pipe, void *data, metric_type type, char *name, void *value) { #define STREAM_BIN(...) if (stream_bin_writer(pipe, ((struct timeval *)data)->tv_sec, __VA_ARGS__, name)) return 1; #define STREAM_UINT(val) if (!fwrite(&val, sizeof(unsigned int), 1, pipe)) return 1; timer_hist *t; int i; switch (type) { case KEY_VAL: STREAM_BIN(BIN_TYPE_KV, BIN_OUT_NO_TYPE, *(double*)value); break; case GAUGE: STREAM_BIN(BIN_TYPE_GAUGE, BIN_OUT_NO_TYPE, ((gauge_t*)value)->value); break; case COUNTER: STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_SUM, counter_sum(value)); STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_SUM_SQ, counter_squared_sum(value)); STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_MEAN, counter_mean(value)); STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_COUNT, counter_count(value)); STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_STDDEV, counter_stddev(value)); STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_MIN, counter_min(value)); STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_MAX, counter_max(value)); break; case SET: STREAM_BIN(BIN_TYPE_SET, BIN_OUT_SUM, set_size(value)); break; case TIMER: t = (timer_hist*)value; STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_SUM, timer_sum(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_SUM_SQ, timer_squared_sum(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_MEAN, timer_mean(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_COUNT, timer_count(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_STDDEV, timer_stddev(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_MIN, timer_min(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_MAX, timer_max(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_PCT | 50, timer_query(&t->tm, 0.5)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_PCT | 95, timer_query(&t->tm, 0.95)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_PCT | 99, timer_query(&t->tm, 0.99)); // Binary streaming for histograms if (t->conf) { STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_HIST_FLOOR, t->conf->min_val); STREAM_UINT(t->counts[0]); for (i=0; i < t->conf->num_bins-2; i++) { STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_HIST_BIN, t->conf->min_val+(t->conf->bin_width*i)); STREAM_UINT(t->counts[i+1]); } STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_HIST_CEIL, t->conf->max_val); STREAM_UINT(t->counts[i+1]); } break; default: syslog(LOG_ERR, "Unknown metric type: %d", type); break; } return 0; }
END_TEST static int iter_test_all_cb(void *data, metric_type type, char *key, void *val) { int *o = data; switch (type) { case KEY_VAL: if (strcmp(key, "test") == 0 && *(double*)val == 100) *o = *o | 1; if (strcmp(key, "test2") == 0 && *(double*)val == 42) *o = *o | 1 << 1; break; case COUNTER: if (strcmp(key, "foo") == 0 && counter_sum(val) == 10) *o = *o | 1 << 2; if (strcmp(key, "bar") == 0 && counter_sum(val) == 30) *o = *o | 1 << 3; break; case TIMER: if (strcmp(key, "baz") == 0 && timer_sum(val) == 11) *o = *o | 1 << 4; break; default: return 1; } return 0; }
/** * Streaming callback to format our output */ static int stream_formatter(FILE *pipe, void *data, metric_type type, char *name, void *value) { #define STREAM(...) if (fprintf(pipe, __VA_ARGS__, (long long)tv->tv_sec) < 0) return 1; struct timeval *tv = data; timer_hist *t; int i; switch (type) { case KEY_VAL: STREAM("%s|%f|%lld\n", name, *(double*)value); break; case GAUGE: STREAM("%s|%f|%lld\n", name, ((gauge_t*)value)->value); break; case COUNTER: STREAM("%s|%f|%lld\n", name, counter_sum(value)); break; case SET: STREAM("%s|%lld|%lld\n", name, set_size(value)); break; case TIMER: t = (timer_hist*)value; STREAM("timers.%s.sum|%f|%lld\n", name, timer_sum(&t->tm)); STREAM("timers.%s.sum_sq|%f|%lld\n", name, timer_squared_sum(&t->tm)); STREAM("timers.%s.mean|%f|%lld\n", name, timer_mean(&t->tm)); STREAM("timers.%s.lower|%f|%lld\n", name, timer_min(&t->tm)); STREAM("timers.%s.upper|%f|%lld\n", name, timer_max(&t->tm)); STREAM("timers.%s.count|%lld|%lld\n", name, timer_count(&t->tm)); STREAM("timers.%s.stdev|%f|%lld\n", name, timer_stddev(&t->tm)); STREAM("timers.%s.median|%f|%lld\n", name, timer_query(&t->tm, 0.5)); STREAM("timers.%s.upper_90|%f|%lld\n", name, timer_query(&t->tm, 0.9)); STREAM("timers.%s.upper_95|%f|%lld\n", name, timer_query(&t->tm, 0.95)); STREAM("timers.%s.upper_99|%f|%lld\n", name, timer_query(&t->tm, 0.99)); // Stream the histogram values if (t->conf) { STREAM("%s.histogram.bin_<%0.2f|%u|%lld\n", name, t->conf->min_val, t->counts[0]); for (i=0; i < t->conf->num_bins-2; i++) { STREAM("%s.histogram.bin_%0.2f|%u|%lld\n", name, t->conf->min_val+(t->conf->bin_width*i), t->counts[i+1]); } STREAM("%s.histogram.bin_>%0.2f|%u|%lld\n", name, t->conf->max_val, t->counts[i+1]); } break; default: syslog(LOG_ERR, "Unknown metric type: %d", type); break; } return 0; }
/** * Streaming callback to format our output */ static int stream_formatter(FILE *pipe, void *data, metric_type type, char *name, void *value) { #define STREAM(...) if (fprintf(pipe, __VA_ARGS__, (long long)tv->tv_sec) < 0) return 1; struct config_time* ct = data; struct timeval *tv = ct->tv; timer_hist *t; int i; char *prefix = ct->global_config->prefixes_final[type]; switch (type) { case KEY_VAL: STREAM("%s%s|%f|%lld\n", prefix, name, *(double*)value); break; case GAUGE: STREAM("%s%s|%f|%lld\n", prefix, name, ((gauge_t*)value)->value); break; case COUNTER: if (ct->global_config->extended_counters) { STREAM("%s%s.count|%" PRIu64 "|%lld\n", prefix, name, counter_count(value)); STREAM("%s%s.mean|%f|%lld\n", prefix, name, counter_mean(value)); STREAM("%s%s.stdev|%f|%lld\n", prefix, name, counter_stddev(value)); STREAM("%s%s.sum|%f|%lld\n", prefix, name, counter_sum(value)); STREAM("%s%s.sum_sq|%f|%lld\n", prefix, name, counter_squared_sum(value)); STREAM("%s%s.lower|%f|%lld\n", prefix, name, counter_min(value)); STREAM("%s%s.upper|%f|%lld\n", prefix, name, counter_max(value)); STREAM("%s%s.rate|%f|%lld\n", prefix, name, counter_sum(value) / ct->global_config->flush_interval); } else { STREAM("%s%s|%f|%lld\n", prefix, name, counter_sum(value)); } break; case SET: STREAM("%s%s|%" PRIu64 "|%lld\n", prefix, name, set_size(value)); break; case TIMER: t = (timer_hist*)value; STREAM("%s%s.sum|%f|%lld\n", prefix, name, timer_sum(&t->tm)); STREAM("%s%s.sum_sq|%f|%lld\n", prefix, name, timer_squared_sum(&t->tm)); STREAM("%s%s.mean|%f|%lld\n", prefix, name, timer_mean(&t->tm)); STREAM("%s%s.lower|%f|%lld\n", prefix, name, timer_min(&t->tm)); STREAM("%s%s.upper|%f|%lld\n", prefix, name, timer_max(&t->tm)); STREAM("%s%s.count|%" PRIu64 "|%lld\n", prefix, name, timer_count(&t->tm)); STREAM("%s%s.stdev|%f|%lld\n", prefix, name, timer_stddev(&t->tm)); for (i=0; i < ct->global_config->num_quantiles; i++) { int percentile; double quantile = ct->global_config->quantiles[i]; if (quantile == 0.5) { STREAM("%s%s.median|%f|%lld\n", prefix, name, timer_query(&t->tm, 0.5)); } if (to_percentile(quantile, &percentile)) { syslog(LOG_ERR, "Invalid quantile: %lf", quantile); break; } STREAM("%s%s.p%d|%f|%lld\n", prefix, name, percentile, timer_query(&t->tm, quantile)); } STREAM("%s%s.rate|%f|%lld\n", prefix, name, timer_sum(&t->tm) / ct->global_config->flush_interval); STREAM("%s%s.sample_rate|%f|%lld\n", prefix, name, (double)timer_count(&t->tm) / ct->global_config->flush_interval); // Stream the histogram values if (t->conf) { STREAM("%s%s.histogram.bin_<%0.2f|%u|%lld\n", prefix, name, t->conf->min_val, t->counts[0]); for (i=0; i < t->conf->num_bins-2; i++) { STREAM("%s%s.histogram.bin_%0.2f|%u|%lld\n", prefix, name, t->conf->min_val+(t->conf->bin_width*i), t->counts[i+1]); } STREAM("%s%s.histogram.bin_>%0.2f|%u|%lld\n", prefix, name, t->conf->max_val, t->counts[i+1]); } break; default: syslog(LOG_ERR, "Unknown metric type: %d", type); break; } return 0; }
static int stream_formatter_bin(FILE *pipe, void *data, metric_type type, char *name, void *value) { #define STREAM_BIN(...) if (stream_bin_writer(pipe, ((struct timeval *)data)->tv_sec, __VA_ARGS__, name)) return 1; #define STREAM_UINT(val) if (!fwrite(&val, sizeof(unsigned int), 1, pipe)) return 1; timer_hist *t; int i; included_metrics_config* counters_config = &(GLOBAL_CONFIG->ext_counters_config); switch (type) { case KEY_VAL: STREAM_BIN(BIN_TYPE_KV, BIN_OUT_NO_TYPE, *(double*)value); break; case GAUGE: STREAM_BIN(BIN_TYPE_GAUGE, BIN_OUT_NO_TYPE, ((gauge_t*)value)->value); break; case COUNTER: if (counters_config->sum) { STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_SUM, counter_sum(value)); } if (counters_config->sum_sq) { STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_SUM_SQ, counter_squared_sum(value)); } if (counters_config->mean) { STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_MEAN, counter_mean(value)); } if (counters_config->count) { STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_COUNT, counter_count(value)); } if (counters_config->stdev) { STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_STDDEV, counter_stddev(value)); } if (counters_config->lower) { STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_MIN, counter_min(value)); } if (counters_config->upper) { STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_MAX, counter_max(value)); } if (counters_config->rate) { STREAM_BIN(BIN_TYPE_COUNTER, BIN_OUT_RATE, counter_sum(value) / GLOBAL_CONFIG->flush_interval); } break; case SET: STREAM_BIN(BIN_TYPE_SET, BIN_OUT_SUM, set_size(value)); break; case TIMER: t = (timer_hist*)value; STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_SUM, timer_sum(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_SUM_SQ, timer_squared_sum(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_MEAN, timer_mean(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_COUNT, timer_count(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_STDDEV, timer_stddev(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_MIN, timer_min(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_MAX, timer_max(&t->tm)); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_RATE, timer_sum(&t->tm) / GLOBAL_CONFIG->flush_interval); STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_SAMPLE_RATE, (double)timer_count(&t->tm) / GLOBAL_CONFIG->flush_interval); for (i=0; i < GLOBAL_CONFIG->num_quantiles; i++) { STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_PCT | (int)(GLOBAL_CONFIG->quantiles[i] * 100), timer_query(&t->tm, GLOBAL_CONFIG->quantiles[i])); } // Binary streaming for histograms if (t->conf) { STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_HIST_FLOOR, t->conf->min_val); STREAM_UINT(t->counts[0]); for (i=0; i < t->conf->num_bins-2; i++) { STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_HIST_BIN, t->conf->min_val+(t->conf->bin_width*i)); STREAM_UINT(t->counts[i+1]); } STREAM_BIN(BIN_TYPE_TIMER, BIN_OUT_HIST_CEIL, t->conf->max_val); STREAM_UINT(t->counts[i+1]); } break; default: syslog(LOG_ERR, "Unknown metric type: %d", type); break; } return 0; }
/** * Streaming callback to format our output */ static int stream_formatter(FILE *pipe, void *data, metric_type type, char *name, void *value) { #define STREAM(...) if (fprintf(pipe, __VA_ARGS__, (long long)tv->tv_sec) < 0) return 1; struct timeval *tv = data; timer_hist *t; int i; char *prefix = GLOBAL_CONFIG->prefixes_final[type]; extended_counters_config* counters_config = &(GLOBAL_CONFIG->ext_counters_config); switch (type) { case KEY_VAL: STREAM("%s%s|%f|%lld\n", prefix, name, *(double*)value); break; case GAUGE: STREAM("%s%s|%f|%lld\n", prefix, name, ((gauge_t*)value)->value); break; case COUNTER: if (GLOBAL_CONFIG->extended_counters) { if (counters_config->count) { STREAM("%s%s.count|%lld|%lld\n", prefix, name, counter_count(value)); } if (counters_config->mean) { STREAM("%s%s.mean|%f|%lld\n", prefix, name, counter_mean(value)); } if (counters_config->stdev) { STREAM("%s%s.stdev|%f|%lld\n", prefix, name, counter_stddev(value)); } if (counters_config->sum) { STREAM("%s%s.sum|%f|%lld\n", prefix, name, counter_sum(value)); } if (counters_config->sum_sq) { STREAM("%s%s.sum_sq|%f|%lld\n", prefix, name, counter_squared_sum(value)); } if (counters_config->lower) { STREAM("%s%s.lower|%f|%lld\n", prefix, name, counter_min(value)); } if (counters_config->upper) { STREAM("%s%s.upper|%f|%lld\n", prefix, name, counter_max(value)); } if (counters_config->rate) { STREAM("%s%s.rate|%f|%lld\n", prefix, name, counter_sum(value) / GLOBAL_CONFIG->flush_interval); } } else { STREAM("%s%s|%f|%lld\n", prefix, name, counter_sum(value)); } break; case SET: STREAM("%s%s|%lld|%lld\n", prefix, name, set_size(value)); break; case TIMER: t = (timer_hist*)value; STREAM("%s%s.sum|%f|%lld\n", prefix, name, timer_sum(&t->tm)); STREAM("%s%s.sum_sq|%f|%lld\n", prefix, name, timer_squared_sum(&t->tm)); STREAM("%s%s.mean|%f|%lld\n", prefix, name, timer_mean(&t->tm)); STREAM("%s%s.lower|%f|%lld\n", prefix, name, timer_min(&t->tm)); STREAM("%s%s.upper|%f|%lld\n", prefix, name, timer_max(&t->tm)); STREAM("%s%s.count|%lld|%lld\n", prefix, name, timer_count(&t->tm)); STREAM("%s%s.stdev|%f|%lld\n", prefix, name, timer_stddev(&t->tm)); for (i=0; i < GLOBAL_CONFIG->num_quantiles; i++) { if (GLOBAL_CONFIG->quantiles[i] == 0.5) { STREAM("%s%s.median|%f|%lld\n", prefix, name, timer_query(&t->tm, 0.5)); } STREAM("%s%s.p%0.0f|%f|%lld\n", prefix, name, GLOBAL_CONFIG->quantiles[i] * 100, timer_query(&t->tm, GLOBAL_CONFIG->quantiles[i])); } STREAM("%s%s.rate|%f|%lld\n", prefix, name, timer_sum(&t->tm) / GLOBAL_CONFIG->flush_interval); STREAM("%s%s.sample_rate|%f|%lld\n", prefix, name, (double)timer_count(&t->tm) / GLOBAL_CONFIG->flush_interval); // Stream the histogram values if (t->conf) { STREAM("%s%s.histogram.bin_<%0.2f|%u|%lld\n", prefix, name, t->conf->min_val, t->counts[0]); for (i=0; i < t->conf->num_bins-2; i++) { STREAM("%s%s.histogram.bin_%0.2f|%u|%lld\n", prefix, name, t->conf->min_val+(t->conf->bin_width*i), t->counts[i+1]); } STREAM("%s%s.histogram.bin_>%0.2f|%u|%lld\n", prefix, name, t->conf->max_val, t->counts[i+1]); } break; default: syslog(LOG_ERR, "Unknown metric type: %d", type); break; } return 0; }