Beispiel #1
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;
}
Beispiel #2
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);
}
Beispiel #3
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);
}
Beispiel #4
0
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);

}
Beispiel #5
0
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);
}
Beispiel #6
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;
}
Beispiel #7
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;
}
Beispiel #8
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;
}
Beispiel #9
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;
}