ngx_int_t ngx_http_statsd_handler(ngx_http_request_t *r) { u_char *line, *p; uint line_len; size_t len; ngx_http_statsd_conf_t *ulcf; ngx_statsd_stat_t *stats; ngx_statsd_stat_t stat; ngx_uint_t c; ngx_uint_t n; ngx_str_t s; ngx_flag_t b; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http statsd handler"); ulcf = ngx_http_get_module_loc_conf(r, ngx_http_statsd_module); if (ulcf->off == 1 || ulcf->endpoint == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: handler off"); return NGX_OK; } // Use a random distribution to sample at sample rate. if (ulcf->sample_rate < 100 && (uint) (ngx_random() % 100) >= ulcf->sample_rate) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: skipping sample"); return NGX_OK; } line_len = 100; #if defined nginx_version && nginx_version >= 7003 line = ngx_pnalloc(r->pool, line_len); #else line = ngx_palloc(r->pool, line_len); #endif if (line == NULL) { return NGX_ERROR; } stats = ulcf->stats->elts; for (c = 0; c < ulcf->stats->nelts; c++) { stat = stats[c]; s = ngx_http_statsd_key_get_value(r, stat.ckey, stat.key); ngx_escape_statsd_key(s.data, s.data, s.len); n = ngx_http_statsd_metric_get_value(r, stat.cmetric, stat.metric); b = ngx_http_statsd_valid_get_value(r, stat.cvalid, stat.valid); if (b == 0 || s.len == 0 || n <= 0) { // Do not log if not valid, key is invalid, or valud is lte 0. ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: no value to send"); continue; }; len = s.len; len += sizeof(":") - 1; len += NGX_INT_T_LEN; len += sizeof("|c|@0.00") - 1; if (line_len < len) { // Redimension buffer. line_len = len; #if defined nginx_version && nginx_version >= 7003 line = ngx_pnalloc(r->pool, line_len); #else line = ngx_palloc(r->pool, line_len); #endif if (line == NULL) { return NGX_ERROR; }; }; if (stat.type == STATSD_TYPE_COUNTER) { if (ulcf->sample_rate < 100) { p = ngx_sprintf(line, "%V:%d|c|@0.%02d", &s, n, ulcf->sample_rate); } else { p = ngx_sprintf(line, "%V:%d|c", &s, n); } ngx_http_statsd_udp_send(ulcf->endpoint, line, p - line); } else if (stat.type == STATSD_TYPE_TIMING) { p = ngx_sprintf(line, "%V:%d|ms", &s, n); ngx_http_statsd_udp_send(ulcf->endpoint, line, p - line); } } return NGX_OK; }
ngx_int_t ngx_http_statsd_handler(ngx_http_request_t *r) { u_char line[STATSD_MAX_STR], *p; const char * metric_type; ngx_http_statsd_conf_t *ulcf; ngx_statsd_stat_t *stats; ngx_statsd_stat_t stat; ngx_uint_t c; ngx_uint_t n; ngx_str_t s; ngx_flag_t b; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http statsd handler"); ulcf = ngx_http_get_module_loc_conf(r, ngx_http_statsd_module); if (ulcf->off == 1 || ulcf->endpoint == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: handler off"); return NGX_OK; } // Use a random distribution to sample at sample rate. if (ulcf->sample_rate < 100 && (uint) (ngx_random() % 100) >= ulcf->sample_rate) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: skipping sample"); return NGX_OK; } stats = ulcf->stats->elts; for (c = 0; c < ulcf->stats->nelts; c++) { stat = stats[c]; s = ngx_http_statsd_key_get_value(r, stat.ckey, stat.key); ngx_escape_statsd_key(s.data, s.data, s.len); n = ngx_http_statsd_metric_get_value(r, stat.cmetric, stat.metric); b = ngx_http_statsd_valid_get_value(r, stat.cvalid, stat.valid); if (b == 0 || s.len == 0 || n <= 0) { // Do not log if not valid, key is invalid, or valud is lte 0. ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: no value to send"); continue; }; if (stat.type == STATSD_TYPE_COUNTER) { metric_type = "c"; } else if (stat.type == STATSD_TYPE_TIMING) { metric_type = "ms"; } else { metric_type = NULL; } 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); } else { p = ngx_snprintf(line, STATSD_MAX_STR, "%V:%d|%s", &s, n, metric_type); } ngx_http_statsd_udp_send(ulcf->endpoint, line, p - line); } } return NGX_OK; }
static ngx_int_t ngx_http_statsd_handler(ngx_http_request_t *r) { 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; ngx_statsd_stat_t stat; ngx_uint_t c; ngx_uint_t n; ngx_str_t set; ngx_str_t s; ngx_flag_t b; ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "http statsd handler"); ulcf = ngx_http_get_module_loc_conf(r, ngx_http_statsd_module); if (ulcf->off == 1 || ulcf->endpoint == NULL) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: handler off"); return NGX_OK; } // Use a random distribution to sample at sample rate. if (ulcf->sample_rate < 100 && (uint)(ngx_random() % 100) >= ulcf->sample_rate) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: skipping sample"); return NGX_OK; } stats = ulcf->stats->elts; line = startline; togo = STATSD_MAX_STR; for (c = 0; c < ulcf->stats->nelts; c++) { stat = stats[c]; s = ngx_http_statsd_key_get_value(r, stat.ckey, stat.key); ngx_escape_statsd_key(s.data, s.data, s.len); n = ngx_http_statsd_metric_get_value(r, stat.cmetric, stat.metric); b = ngx_http_statsd_valid_get_value(r, stat.cvalid, stat.valid); set = ngx_http_statsd_set_get_value(r, stat.cmetric_str, stat.metric_str); if (b == 0 || s.len == 0 || (n <= 0 && set.len == 0)) { // Do not log if not valid, key is invalid, or value is less than 0. ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "statsd: no value to send"); continue; }; if (stat.type == STATSD_TYPE_COUNTER) { metric_type = "c"; } else if (stat.type == STATSD_TYPE_TIMING) { metric_type = "ms"; } else if (stat.type == STATSD_TYPE_SET) { metric_type = "s"; } else { metric_type = NULL; } if (metric_type) { if (stat.type == STATSD_TYPE_SET) { // handle a set if (ulcf->sample_rate < 100) { p = ngx_snprintf(line, STATSD_MAX_STR, "%V:%V|s|@0.%02d", &s, &set, ulcf->sample_rate); } else { p = ngx_snprintf(line, STATSD_MAX_STR, "%V:%V|s", &s, &set); } ngx_http_statsd_udp_send(ulcf->endpoint, line, p - line); } else { if (ulcf->sample_rate < 100) { p = ngx_snprintf(line, togo, "%V:%d|%s|@0.%02d\n", &s, n, metric_type, ulcf->sample_rate); } else { 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; } } } if (togo < STATSD_MAX_STR) { ngx_http_statsd_udp_send(ulcf->endpoint, startline, line - startline - sizeof(char)); } } return NGX_OK; }