diff --git a/config b/config index 59a603d16..386969168 100644 --- a/config +++ b/config @@ -140,11 +140,10 @@ NGX_WASMX_DEPS="\ $ngx_addon_dir/src/common/shm/ngx_wa_shm.h \ $ngx_addon_dir/src/common/shm/ngx_wa_shm_kv.h \ $ngx_addon_dir/src/common/shm/ngx_wa_shm_queue.h \ + $ngx_addon_dir/src/common/metrics/ngx_wa_metrics.h \ $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm.h \ $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm_maps.h \ - $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm_properties.h \ - $ngx_addon_dir/src/common/metrics/ngx_wa_metrics.h \ - $ngx_addon_dir/src/common/metrics/ngx_wa_histogram.h" + $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm_properties.h" NGX_WASMX_SRCS="\ $ngx_addon_dir/src/ngx_wasmx.c \ @@ -154,13 +153,13 @@ NGX_WASMX_SRCS="\ $ngx_addon_dir/src/common/shm/ngx_wa_shm.c \ $ngx_addon_dir/src/common/shm/ngx_wa_shm_kv.c \ $ngx_addon_dir/src/common/shm/ngx_wa_shm_queue.c \ + $ngx_addon_dir/src/common/metrics/ngx_wa_metrics.c \ + $ngx_addon_dir/src/common/metrics/ngx_wa_histogram.c \ $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm.c \ $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm_host.c \ $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm_maps.c \ $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm_properties.c \ - $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm_util.c \ - $ngx_addon_dir/src/common/metrics/ngx_wa_metrics.c \ - $ngx_addon_dir/src/common/metrics/ngx_wa_histogram.c" + $ngx_addon_dir/src/common/proxy_wasm/ngx_proxy_wasm_util.c" # wasm diff --git a/src/common/metrics/ngx_wa_histogram.c b/src/common/metrics/ngx_wa_histogram.c index 668184995..d52e46cef 100644 --- a/src/common/metrics/ngx_wa_histogram.c +++ b/src/common/metrics/ngx_wa_histogram.c @@ -4,12 +4,7 @@ #include "ddebug.h" #include -#include - - -#define NGX_WA_BINS_INIT 5 -#define NGX_WA_BINS_MAX 18 -#define NGX_WA_BINS_INCREMENT 4 +#include static uint32_t @@ -40,14 +35,15 @@ histogram_grow(ngx_wa_metrics_t *metrics, ngx_wa_metrics_histogram_t *h, ngx_uint_t n; ngx_wa_metrics_histogram_t *new_h = NULL; - if (h->n_bins == NGX_WA_BINS_MAX) { + if (h->n_bins == NGX_WA_METRICS_BINS_MAX) { return NGX_ERROR; } ngx_log_debug0(NGX_LOG_DEBUG_WASM, metrics->shm->log, 0, "growing histogram"); - n = ngx_min(NGX_WA_BINS_INCREMENT, NGX_WA_BINS_MAX - h->n_bins); + n = ngx_min(NGX_WA_METRICS_BINS_INCREMENT, + NGX_WA_METRICS_BINS_MAX - h->n_bins); old_size = sizeof(ngx_wa_metrics_histogram_t) + sizeof(ngx_wa_metrics_bin_t) * h->n_bins; size = old_size + sizeof(ngx_wa_metrics_bin_t) * n; @@ -96,7 +92,8 @@ histogram_bin(ngx_wa_metrics_t *metrics, ngx_wa_metrics_histogram_t *h, return b; } - if (b->upper_bound == 0) { + if (b->upper_bound == NGX_MAX_UINT32_VALUE) { + i++; break; } } @@ -128,29 +125,29 @@ histogram_bin(ngx_wa_metrics_t *metrics, ngx_wa_metrics_histogram_t *h, static void histogram_log(ngx_wa_metrics_t *metrics, ngx_wa_metric_t *m, uint32_t mid) { - size_t i, size = sizeof(ngx_wa_metrics_histogram_t) - + sizeof(ngx_wa_metrics_bin_t) - * NGX_WA_BINS_MAX; + size_t i; + u_char *p; ngx_wa_metrics_bin_t *b; ngx_wa_metrics_histogram_t *h; - u_char *p, buf[size], s_buf[NGX_MAX_ERROR_STR]; + u_char h_buf[NGX_WA_METRICS_MAX_HISTOGRAM_SIZE]; + u_char s_buf[NGX_MAX_ERROR_STR]; - ngx_memzero(buf, size); + ngx_memzero(h_buf, sizeof(h_buf)); p = s_buf; - h = (ngx_wa_metrics_histogram_t *) buf; - h->n_bins = NGX_WA_BINS_MAX; + h = (ngx_wa_metrics_histogram_t *) h_buf; + h->n_bins = NGX_WA_METRICS_BINS_MAX; h->bins[0].upper_bound = NGX_MAX_UINT32_VALUE; ngx_wa_metrics_histogram_get(metrics, m, metrics->workers, h); for (i = 0; i < h->n_bins; i++) { b = &h->bins[i]; - if (b->upper_bound == 0) { + p = ngx_sprintf(p, " %uD: %uD;", b->upper_bound, b->count); + + if (b->upper_bound == NGX_MAX_UINT32_VALUE) { break; } - - p = ngx_sprintf(p, " %uD: %uD;", b->upper_bound, b->count); } ngx_log_debug3(NGX_LOG_DEBUG_WASM, metrics->shm->log, 0, @@ -165,7 +162,7 @@ ngx_wa_metrics_histogram_add_locked(ngx_wa_metrics_t *metrics, ngx_wa_metric_t *m) { size_t i; - static uint16_t n_bins = NGX_WA_BINS_INIT; + static uint16_t n_bins = NGX_WA_METRICS_BINS_INIT; ngx_wa_metrics_histogram_t **h; for (i = 0; i < metrics->workers; i++) { @@ -228,12 +225,12 @@ ngx_wa_metrics_histogram_get(ngx_wa_metrics_t *metrics, ngx_wa_metric_t *m, for (j = 0; j < h->n_bins; j++) { b = &h->bins[j]; - if (b->upper_bound == 0) { - break; - } - out_b = histogram_bin(metrics, out, b->upper_bound, NULL); out_b->count += b->count; + + if (b->upper_bound == NGX_MAX_UINT32_VALUE) { + break; + } } } } diff --git a/src/common/metrics/ngx_wa_histogram.h b/src/common/metrics/ngx_wa_histogram.h deleted file mode 100644 index 854b1ad57..000000000 --- a/src/common/metrics/ngx_wa_histogram.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _NGX_WA_HISTOGRAM_H_INCLUDED_ -#define _NGX_WA_HISTOGRAM_H_INCLUDED_ - - -#include - - -ngx_int_t ngx_wa_metrics_histogram_add_locked(ngx_wa_metrics_t *metrics, - ngx_wa_metric_t *m); -ngx_int_t ngx_wa_metrics_histogram_record(ngx_wa_metrics_t *metrics, - ngx_wa_metric_t *m, ngx_uint_t slot, uint32_t mid, ngx_uint_t n); -void ngx_wa_metrics_histogram_get(ngx_wa_metrics_t *metrics, ngx_wa_metric_t *m, - ngx_uint_t slots, ngx_wa_metrics_histogram_t *out); - - -#endif /* _NGX_WA_HISTOGRAM_H_INCLUDED_ */ diff --git a/src/common/metrics/ngx_wa_metrics.c b/src/common/metrics/ngx_wa_metrics.c index 75994c61d..e0579e693 100644 --- a/src/common/metrics/ngx_wa_metrics.c +++ b/src/common/metrics/ngx_wa_metrics.c @@ -5,7 +5,6 @@ #include #include -#include ngx_str_t * @@ -478,7 +477,8 @@ ngx_wa_metrics_record(ngx_wa_metrics_t *metrics, uint32_t mid, ngx_int_t n) * NGX_DECLINED: not found */ ngx_int_t -ngx_wa_metrics_get(ngx_wa_metrics_t *metrics, uint32_t mid, ngx_uint_t *out) +ngx_wa_metrics_get(ngx_wa_metrics_t *metrics, uint32_t mid, + ngx_wa_metric_t *out) { uint32_t cas; ngx_int_t rc; @@ -491,26 +491,32 @@ ngx_wa_metrics_get(ngx_wa_metrics_t *metrics, uint32_t mid, ngx_uint_t *out) } m = (ngx_wa_metric_t *) n->data; + out->type = m->type; switch (m->type) { case NGX_WA_METRIC_COUNTER: - *out = get_counter(m, metrics->workers); + out->slots[0].counter = get_counter(m, metrics->workers); break; case NGX_WA_METRIC_GAUGE: - *out = get_gauge(m, metrics->workers); + out->slots[0].gauge.value = get_gauge(m, metrics->workers); + break; + + case NGX_WA_METRIC_HISTOGRAM: + ngx_wa_metrics_histogram_get(metrics, m, metrics->workers, + out->slots[0].histogram); break; default: - ngx_wa_assert(m->type == NGX_WA_METRIC_HISTOGRAM); - rc = NGX_ABORT; + ngx_wa_assert(0); + rc = NGX_ERROR; break; } done: ngx_wa_assert(rc == NGX_OK - || rc == NGX_ABORT + || rc == NGX_ERROR || rc == NGX_DECLINED); return rc; diff --git a/src/common/metrics/ngx_wa_metrics.h b/src/common/metrics/ngx_wa_metrics.h index 5502138bf..00942b45c 100644 --- a/src/common/metrics/ngx_wa_metrics.h +++ b/src/common/metrics/ngx_wa_metrics.h @@ -5,6 +5,20 @@ #include +#define ngx_wa_metrics_counter(m) m->slots[0].counter +#define ngx_wa_metrics_gauge(m) m->slots[0].gauge.value + + +#define NGX_WA_METRICS_BINS_INIT 5 +#define NGX_WA_METRICS_BINS_MAX 18 +#define NGX_WA_METRICS_BINS_INCREMENT 4 +#define NGX_WA_METRICS_MAX_HISTOGRAM_SIZE sizeof(ngx_wa_metrics_histogram_t)\ + + sizeof(ngx_wa_metrics_bin_t) \ + * NGX_WA_METRICS_BINS_MAX +#define NGX_WA_METRICS_ONE_SLOT_METRIC_SIZE sizeof(ngx_wa_metric_t) \ + + sizeof(ngx_wa_metric_val_t) + + typedef struct ngx_wa_metrics_s ngx_wa_metrics_t; typedef enum { @@ -74,7 +88,26 @@ ngx_int_t ngx_wa_metrics_increment(ngx_wa_metrics_t *metrics, ngx_int_t ngx_wa_metrics_record(ngx_wa_metrics_t *metrics, uint32_t metric_id, ngx_int_t val); ngx_int_t ngx_wa_metrics_get(ngx_wa_metrics_t *metrics, uint32_t metric_id, - ngx_uint_t *out); + ngx_wa_metric_t *o); + +ngx_int_t ngx_wa_metrics_histogram_add_locked(ngx_wa_metrics_t *metrics, + ngx_wa_metric_t *m); +ngx_int_t ngx_wa_metrics_histogram_record(ngx_wa_metrics_t *metrics, + ngx_wa_metric_t *m, ngx_uint_t slot, uint32_t mid, ngx_uint_t n); +void ngx_wa_metrics_histogram_get(ngx_wa_metrics_t *metrics, ngx_wa_metric_t *m, + ngx_uint_t slots, ngx_wa_metrics_histogram_t *out); + + +static ngx_inline ngx_wa_metrics_histogram_t * +ngx_wa_metrics_histogram_set_buffer(ngx_wa_metric_t *m, u_char *b, size_t s) +{ + m->slots[0].histogram = (ngx_wa_metrics_histogram_t *) b; + m->slots[0].histogram->n_bins = (s - sizeof(ngx_wa_metrics_histogram_t)) + / sizeof(ngx_wa_metrics_bin_t); + m->slots[0].histogram->bins[0].upper_bound = NGX_MAX_UINT32_VALUE; + + return m->slots[0].histogram; +} #endif /* _NGX_WA_METRICS_H_INCLUDED_ */ diff --git a/src/common/proxy_wasm/ngx_proxy_wasm_host.c b/src/common/proxy_wasm/ngx_proxy_wasm_host.c index 5c8efe94a..cf0f6c3f7 100644 --- a/src/common/proxy_wasm/ngx_proxy_wasm_host.c +++ b/src/common/proxy_wasm/ngx_proxy_wasm_host.c @@ -1666,37 +1666,51 @@ ngx_proxy_wasm_hfuncs_get_metric(ngx_wavm_instance_t *instance, ngx_uint_t *ret_value; ngx_cycle_t *cycle = (ngx_cycle_t *) ngx_cycle; ngx_wa_metrics_t *metrics = ngx_wasmx_metrics(cycle); + ngx_wa_metric_t *m; ngx_proxy_wasm_exec_t *pwexec = ngx_proxy_wasm_instance2pwexec(instance); + u_char m_buf[NGX_WA_METRICS_ONE_SLOT_METRIC_SIZE]; + u_char h_buf[NGX_WA_METRICS_MAX_HISTOGRAM_SIZE]; u_char trapmsg[NGX_MAX_ERROR_STR]; + ngx_memzero(m_buf, sizeof(m_buf)); + ngx_memzero(h_buf, sizeof(h_buf)); + metric_id = args[0].of.i32; ret_value = NGX_WAVM_HOST_LIFT(instance, args[1].of.i32, ngx_uint_t); - rc = ngx_wa_metrics_get(metrics, metric_id, ret_value); - if (rc != NGX_OK) { - ngx_memzero(trapmsg, NGX_MAX_ERROR_STR); - p = ngx_sprintf(trapmsg, "could not retrieve metric id \"%ui\": ", - metric_id); + m = (ngx_wa_metric_t *) m_buf; + ngx_wa_metrics_histogram_set_buffer(m, h_buf, sizeof(h_buf)); - switch (rc) { - case NGX_DECLINED: - ngx_sprintf(p, "metric not found"); + rc = ngx_wa_metrics_get(metrics, metric_id, m); + if (rc == NGX_OK && m->type != NGX_WA_METRIC_HISTOGRAM) { + switch (m->type) { + case NGX_WA_METRIC_COUNTER: + *ret_value = ngx_wa_metrics_counter(m); break; - case NGX_ABORT: - ngx_sprintf(p, "metric is a histogram"); + case NGX_WA_METRIC_GAUGE: + *ret_value = ngx_wa_metrics_gauge(m); break; default: - ngx_wa_assert(rc == NGX_OK); break; } - return ngx_proxy_wasm_result_trap(pwexec, (char *) trapmsg, - rets, NGX_WAVM_ERROR); + return ngx_proxy_wasm_result_ok(rets); } - return ngx_proxy_wasm_result_ok(rets); + ngx_memzero(trapmsg, NGX_MAX_ERROR_STR); + p = ngx_sprintf(trapmsg, "could not retrieve metric id \"%ui\"", metric_id); + + if (rc == NGX_DECLINED) { + ngx_sprintf(p, ": metric not found"); + + } else if (m->type == NGX_WA_METRIC_HISTOGRAM) { + ngx_sprintf(p, ": metric is a histogram"); + } + + return ngx_proxy_wasm_result_trap(pwexec, (char *) trapmsg, + rets, NGX_WAVM_ERROR); }