Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

sending multiple metrics in a packet #19

Open
ct16k opened this issue Nov 2, 2015 · 0 comments
Open

sending multiple metrics in a packet #19

ct16k opened this issue Nov 2, 2015 · 0 comments

Comments

@ct16k
Copy link

ct16k commented Nov 2, 2015

While looking for a quick and easy way to send some nginx data to statsd I came upon this module and while it's doing its job properly, there is one thing that was bothering me: for each configured metric it would generate a separate UDP packet. This would mean that when used in a relatively large farm with multiple vhosts, each with multiple metrics defined, it would generate a flurry of packets, even when not under heavy load, that would hammer the statsd service. One obvious solution to this was to combine multiple metrics in a single packet, and the following patch tries to do just that.

--- ngx_http_statsd.c.orig  2015-11-02 22:07:22.736000288 +0000
+++ ngx_http_statsd.c   2015-11-02 22:20:44.615986241 +0000
@@ -18,7 +18,7 @@
 #define STATSD_TYPE_COUNTER    0x0001
 #define STATSD_TYPE_TIMING  0x0002

-#define STATSD_MAX_STR 256
+#define STATSD_MAX_STR 1432

 #define ngx_conf_merge_ptr_value(conf, prev, default)                  \
    if (conf == NGX_CONF_UNSET_PTR) {                                   \
@@ -235,7 +235,8 @@
 ngx_int_t
 ngx_http_statsd_handler(ngx_http_request_t *r)
 {
-    u_char                    line[STATSD_MAX_STR], *p;
+    u_char                    startline[STATSD_MAX_STR], *p, *line;
+    size_t                    togo;
     const char *              metric_type;
     ngx_http_statsd_conf_t   *ulcf;
    ngx_statsd_stat_t        *stats;
@@ -262,6 +263,8 @@
    }

    stats = ulcf->stats->elts;
+   line = startline;
+   togo = STATSD_MAX_STR;
    for (c = 0; c < ulcf->stats->nelts; c++) {

        stat = stats[c];
@@ -287,13 +290,26 @@

        if (metric_type) {
            if (ulcf->sample_rate < 100) {
-               p = ngx_snprintf(line, STATSD_MAX_STR, "%V:%d|%s|@0.%02d", &s, n, metric_type, ulcf->sample_rate);
+               p = ngx_snprintf(line, togo, "%V:%d|%s|@0.%02d\n", &s, n, metric_type, ulcf->sample_rate);
            } else {
-               p = ngx_snprintf(line, STATSD_MAX_STR, "%V:%d|%s", &s, n, metric_type);
+               p = ngx_snprintf(line, togo, "%V:%d|%s\n", &s, n, metric_type);
+           }
+           if (p - line >= togo) {
+               if (line != startline) {
+                   ngx_http_statsd_udp_send(ulcf->endpoint, startline, line - startline - sizeof(char));
+                   c--;
+               }
+               line = startline;
+               togo = STATSD_MAX_STR;
+           } else {
+               togo -= p - line;
+               line = p;
            }
-           ngx_http_statsd_udp_send(ulcf->endpoint, line, p - line);
        }
    }
+   if (togo < STATSD_MAX_STR) {
+       ngx_http_statsd_udp_send(ulcf->endpoint, startline, line - startline - sizeof(char));
+   }

     return NGX_OK;
 }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant