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 START_TEST(test_counter_init_add) { counter c; int res = init_counter(&c); fail_unless(res == 0); fail_unless(counter_add_sample(&c, 100) == 0); fail_unless(counter_count(&c) == 1); fail_unless(counter_sum(&c) == 100); fail_unless(counter_mean(&c) == 100); fail_unless(counter_stddev(&c) == 0); }
END_TEST START_TEST(test_counter_add_loop) { counter c; int res = init_counter(&c); fail_unless(res == 0); for (int i=1; i<=100; i++) fail_unless(counter_add_sample(&c, i) == 0); fail_unless(counter_count(&c) == 100); fail_unless(counter_sum(&c) == 5050); fail_unless(counter_mean(&c) == 50.5); fail_unless(round(counter_stddev(&c)*1000)/1000 == 29.011); }
END_TEST START_TEST(test_counter_sample_rate) { counter c; int res = init_counter(&c); fail_unless(res == 0); for (int i=1; i<=100; i++) fail_unless(counter_add_sample(&c, i, 0.5) == 0); fail_unless(counter_count(&c) == 200); fail_unless(counter_sum(&c) == 5050); fail_unless(counter_mean(&c) == 50.5); fail_unless(round(counter_stddev(&c)*1000)/1000 == 29.011); fail_unless(counter_squared_sum(&c) == 338350); fail_unless(counter_min(&c) == 1); fail_unless(counter_max(&c) == 100); }
static int pkg_create_from_dir(struct pkg *pkg, const char *root, struct packing *pkg_archive) { char fpath[MAXPATHLEN]; struct pkg_file *file = NULL; struct pkg_dir *dir = NULL; int ret; struct stat st; int64_t flatsize = 0; int64_t nfiles; const char *relocation; hardlinks_t *hardlinks; if (pkg_is_valid(pkg) != EPKG_OK) { pkg_emit_error("the package is not valid"); return (EPKG_FATAL); } relocation = pkg_kv_get(&pkg->annotations, "relocated"); if (relocation == NULL) relocation = ""; if (pkg_rootdir != NULL) relocation = pkg_rootdir; /* * Get / compute size / checksum if not provided in the manifest */ nfiles = kh_count(pkg->filehash); counter_init("file sizes/checksums", nfiles); hardlinks = kh_init_hardlinks(); while (pkg_files(pkg, &file) == EPKG_OK) { snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", relocation, file->path); if (lstat(fpath, &st) == -1) { pkg_emit_error("file '%s' is missing", fpath); return (EPKG_FATAL); } if (file->size == 0) file->size = (int64_t)st.st_size; if (st.st_nlink == 1 || !check_for_hardlink(hardlinks, &st)) { flatsize += file->size; } file->sum = pkg_checksum_generate_file(fpath, PKG_HASH_TYPE_SHA256_HEX); if (file->sum == NULL) return (EPKG_FATAL); counter_count(); } kh_destroy_hardlinks(hardlinks); counter_end(); pkg->flatsize = flatsize; if (pkg->type == PKG_OLD_FILE) { pkg_emit_error("Cannot create an old format package"); return (EPKG_FATAL); } else { /* * Register shared libraries used by the package if * SHLIBS enabled in conf. Deletes shlib info if not. */ struct sbuf *b = sbuf_new_auto(); pkg_analyse_files(NULL, pkg, root); pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL); packing_append_buffer(pkg_archive, sbuf_data(b), "+COMPACT_MANIFEST", sbuf_len(b)); sbuf_clear(b); pkg_emit_manifest_sbuf(pkg, b, 0, NULL); sbuf_finish(b); packing_append_buffer(pkg_archive, sbuf_data(b), "+MANIFEST", sbuf_len(b)); sbuf_delete(b); } counter_init("packing files", nfiles); while (pkg_files(pkg, &file) == EPKG_OK) { snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", relocation, file->path); ret = packing_append_file_attr(pkg_archive, fpath, file->path, file->uname, file->gname, file->perm, file->fflags); if (developer_mode && ret != EPKG_OK) return (ret); counter_count(); } counter_end(); nfiles = kh_count(pkg->dirhash); counter_init("packing directories", nfiles); while (pkg_dirs(pkg, &dir) == EPKG_OK) { snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "", relocation, dir->path); ret = packing_append_file_attr(pkg_archive, fpath, dir->path, dir->uname, dir->gname, dir->perm, dir->fflags); if (developer_mode && ret != EPKG_OK) return (ret); counter_count(); } counter_end(); return (EPKG_OK); }
/** * 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; }
/** * 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]; 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) { STREAM("%s%s.count|%lld|%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) / 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)); STREAM("%s%s.median|%f|%lld\n", prefix, name, timer_query(&t->tm, 0.5)); STREAM("%s%s.p95|%f|%lld\n", prefix, name, timer_query(&t->tm, 0.95)); STREAM("%s%s.p99|%f|%lld\n", prefix, name, timer_query(&t->tm, 0.99)); STREAM("%s%s.rate|%f|%lld\n", prefix, name, timer_sum(&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; }
/** * 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]; included_metrics_config* counters_config = &(GLOBAL_CONFIG->ext_counters_config); included_metrics_config* timers_config = &(GLOBAL_CONFIG->timers_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.count|%"PRIu64"|%lld\n", name, counter_count(value)); //STREAM("%s%s.count|%"PRIu64"|%lld\n", prefix, name, counter_count(value)); } if (counters_config->mean) { STREAM("%s.mean|%f|%lld\n", name, counter_mean(value)); //STREAM("%s%s.mean|%f|%lld\n", prefix, name, counter_mean(value)); } if (counters_config->stdev) { STREAM("%s.stdev|%f|%lld\n", name, counter_stddev(value)); //STREAM("%s%s.stdev|%f|%lld\n", prefix, name, counter_stddev(value)); } if (counters_config->sum) { STREAM("%s.sum|%f|%lld\n", name, counter_sum(value)); //STREAM("%s%s.sum|%f|%lld\n", prefix, name, counter_sum(value)); } if (counters_config->sum_sq) { STREAM("%s.sum_sq|%f|%lld\n", name, counter_squared_sum(value)); //STREAM("%s%s.sum_sq|%f|%lld\n", prefix, name, counter_squared_sum(value)); } if (counters_config->lower) { STREAM("%s.lower|%f|%lld\n", name, counter_min(value)); //STREAM("%s%s.lower|%f|%lld\n", prefix, name, counter_min(value)); } if (counters_config->upper) { STREAM("%s.upper|%f|%lld\n", name, counter_max(value)); //STREAM("%s%s.upper|%f|%lld\n", prefix, name, counter_max(value)); } if (counters_config->rate) { STREAM("%s.rate|%f|%lld\n", name, counter_sum(value) / GLOBAL_CONFIG->flush_interval); //STREAM("%s%s.rate|%f|%lld\n", prefix, name, counter_sum(value) / GLOBAL_CONFIG->flush_interval); } } else { //update by liujun 2016/10/18 use rate replace sum() STREAM("%s|%f|%lld\n", name, counter_sum(value) / GLOBAL_CONFIG->flush_interval); //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; // if (timers_config->sum) { // STREAM("%s%s.sum|%f|%lld\n", prefix, name, timer_sum(&t->tm)); // } // if (timers_config->sum_sq) { // STREAM("%s%s.sum_sq|%f|%lld\n", prefix, name, timer_squared_sum(&t->tm)); // } if (timers_config->mean) { STREAM("%s%s.mean|%f|%lld\n", prefix, name, timer_mean(&t->tm)); } //if (timers_config->lower) { // STREAM("%s%s.lower|%f|%lld\n", prefix, name, timer_min(&t->tm)); // } // if (timers_config->upper) { // STREAM("%s%s.upper|%f|%lld\n", prefix, name, timer_max(&t->tm)); // } // if (timers_config->count) { // STREAM("%s%s.count|%"PRIu64"|%lld\n", prefix, name, timer_count(&t->tm)); // } if (timers_config->stdev) { STREAM("%s%s.stdev|%f|%lld\n", prefix, name, timer_stddev(&t->tm)); } // for (i=0; i < GLOBAL_CONFIG->num_quantiles; i++) { // if (timers_config->median && 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])); // } // if (timers_config->rate) { // STREAM("%s%s.rate|%f|%lld\n", prefix, name, timer_sum(&t->tm) / GLOBAL_CONFIG->flush_interval); // } // if (timers_config->sample_rate) { // 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; }
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; }