diff --git a/core/metrics.c b/core/metrics.c index 3af7c186..b4107a9e 100644 --- a/core/metrics.c +++ b/core/metrics.c @@ -321,6 +321,7 @@ struct uwsgi_metric *uwsgi_register_keyval_metric(char *arg) { char *m_initial_value = NULL; char *m_children = NULL; char *m_alias = NULL; + char *m_reset_after_push = NULL; if (!strchr(arg, '=')) { m_name = uwsgi_str(arg); @@ -340,6 +341,7 @@ struct uwsgi_metric *uwsgi_register_keyval_metric(char *arg) { "arg3n", &m_arg3n, "children", &m_children, "alias", &m_alias, + "reset_after_push", &m_reset_after_push, NULL)) { uwsgi_log("invalid metric keyval syntax: %s\n", arg); exit(1); @@ -354,6 +356,7 @@ struct uwsgi_metric *uwsgi_register_keyval_metric(char *arg) { char *collector = NULL; uint32_t freq = 0; int64_t initial_value = 0; + uint8_t reset_after_push = 0; if (m_type) { if (!strcmp(m_type, "gauge")) { @@ -381,6 +384,10 @@ struct uwsgi_metric *uwsgi_register_keyval_metric(char *arg) { struct uwsgi_metric* um = uwsgi_register_metric(m_name, m_oid, type, collector, NULL, freq, NULL); um->initial_value = initial_value; + if (m_reset_after_push){ + um->reset_after_push = 1; + } + if (m_children) { char *p, *ctx = NULL; uwsgi_foreach_token(m_children, ";", p, ctx) { @@ -427,6 +434,7 @@ struct uwsgi_metric *uwsgi_register_keyval_metric(char *arg) { if (m_initial_value) free(m_initial_value); if (m_children) free(m_children); if (m_alias) free(m_alias); + if (m_reset_after_push) free(m_reset_after_push); return um; } diff --git a/plugins/carbon/carbon.c b/plugins/carbon/carbon.c index 48e82471..80298d73 100644 --- a/plugins/carbon/carbon.c +++ b/plugins/carbon/carbon.c @@ -380,6 +380,11 @@ metrics_loop: uwsgi_rlock(uwsgi.metrics_lock); wok = carbon_write(fd, "%s%s.%s.%.*s %llu %llu\n", u_carbon.root_node, u_carbon.hostname, u_carbon.id, um->name_len, um->name, (unsigned long long) *um->value, (unsigned long long) now); uwsgi_rwunlock(uwsgi.metrics_lock); + if (um->reset_after_push){ + uwsgi_wlock(uwsgi.metrics_lock); + *um->value = 0; + uwsgi_unlock(uwsgi.metrics_lock); + } if (!wok) goto clear; um = um->next; } diff --git a/plugins/rrdtool/rrdtool.c b/plugins/rrdtool/rrdtool.c index 11671903..bfa4f512 100644 --- a/plugins/rrdtool/rrdtool.c +++ b/plugins/rrdtool/rrdtool.c @@ -150,6 +150,11 @@ static void rrdtool_push(struct uwsgi_stats_pusher_instance *uspi, time_t now, c uwsgi_rlock(uwsgi.metrics_lock); int ret = snprintf(buf, 1024, "N:%lld", (long long) (*um->value)); uwsgi_rwunlock(uwsgi.metrics_lock); + if (um->reset_after_push){ + uwsgi_wlock(uwsgi.metrics_lock); + *um->value = 0; + uwsgi_unlock(uwsgi.metrics_lock); + } if (ret < 3 || ret >= 1024) { uwsgi_log("unable to update rrdtool metric for %s\n", um->name); goto next; diff --git a/plugins/stats_pusher_socket/plugin.c b/plugins/stats_pusher_socket/plugin.c index 5c947d98..d204cd18 100644 --- a/plugins/stats_pusher_socket/plugin.c +++ b/plugins/stats_pusher_socket/plugin.c @@ -92,6 +92,11 @@ static void stats_pusher_socket(struct uwsgi_stats_pusher_instance *uspi, time_t uwsgi_rlock(uwsgi.metrics_lock); socket_send_metric(ub, uspi, um); uwsgi_rwunlock(uwsgi.metrics_lock); + if (um->reset_after_push){ + uwsgi_wlock(uwsgi.metrics_lock); + *um->value = 0; + uwsgi_unlock(uwsgi.metrics_lock); + } um = um->next; } uwsgi_buffer_destroy(ub); diff --git a/plugins/stats_pusher_statsd/plugin.c b/plugins/stats_pusher_statsd/plugin.c index d9bd6430..4579ccf2 100644 --- a/plugins/stats_pusher_statsd/plugin.c +++ b/plugins/stats_pusher_statsd/plugin.c @@ -95,6 +95,11 @@ static void stats_pusher_statsd(struct uwsgi_stats_pusher_instance *uspi, time_t statsd_send_metric(ub, uspi, um->name, um->name_len, *um->value, "|m"); } uwsgi_rwunlock(uwsgi.metrics_lock); + if (um->reset_after_push){ + uwsgi_wlock(uwsgi.metrics_lock); + *um->value = 0; + uwsgi_unlock(uwsgi.metrics_lock); + } um = um->next; } uwsgi_buffer_destroy(ub); diff --git a/plugins/zabbix/plugin.c b/plugins/zabbix/plugin.c index 5229ace3..5d307903 100644 --- a/plugins/zabbix/plugin.c +++ b/plugins/zabbix/plugin.c @@ -94,6 +94,11 @@ static void stats_pusher_zabbix(struct uwsgi_stats_pusher_instance *uspi, time_t if (uwsgi_buffer_append(zn->ub, "\",\"value\":\"", 11)) { error = 1; goto end;} if (uwsgi_buffer_num64(zn->ub, *um->value)) { error = 1; goto end;} if (uwsgi_buffer_append(zn->ub, "\"}", 2)) { error = 1; goto end;} + if (um->reset_after_push){ + uwsgi_wlock(uwsgi.metrics_lock); + *um->value = 0; + uwsgi_unlock(uwsgi.metrics_lock); + } um = um->next; if (um) { if (uwsgi_buffer_append(zn->ub, ",", 1)) { error = 1; goto end;} diff --git a/uwsgi.h b/uwsgi.h index 8c8ce5cb..d73c0c68 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -4685,6 +4685,9 @@ struct uwsgi_metric { struct uwsgi_metric_threshold *thresholds; struct uwsgi_metric *next; + + // allow to reset metrics after each push + uint8_t reset_after_push; }; struct uwsgi_metric_child {