feat: decoupled prometheus exporter's calculation and output#12383
Conversation
…heus-exporter-concurrency
| -- config server status | ||
| local vars = ngx.var or {} | ||
| local hostname = vars.hostname or "" | ||
| local hostname = core.utils.gethostname() or "" |
There was a problem hiding this comment.
Because API disabled in the context of ngx.timer, context: ngx.timer.
| function _M.export_metrics() | ||
| if not prometheus then | ||
| core.response.exit(200, "{}") | ||
| return core.response.exit(200, "{}") |
| meta: | ||
| lua_shared_dict: # Nginx Lua shared memory zone. Size units are m or k. | ||
| prometheus-metrics: 15m | ||
| prometheus-cache: 10m |
There was a problem hiding this comment.
pls add some comments, tell users when they need to modify it
| core.log.error("Failed to collect metrics: ", res) | ||
| return | ||
| end | ||
| shdict_prometheus_cache:set(CACHED_METRICS_KEY, res) |
There was a problem hiding this comment.
need to capture the return value, it maybe fail
if err, tell user what is the reason, and tell the user to change the default size if the shdict is small
| local _, err, forcible = shdict_prometheus_cache:set(CACHED_METRICS_KEY, res) | ||
|
|
||
| if err then | ||
| core.log.error("Failed to save metrics to shdict: ", err) |
There was a problem hiding this comment.
need more information, eg: the name of shdict and the size of value
There was a problem hiding this comment.
if the value is to large, will fail when we call set method
|
|
||
| core.response.set_header("content_type", "text/plain") | ||
| return 200, core.table.concat(prometheus:metric_data()) | ||
| local cached_metrics_text = shdict_prometheus_cache:get(CACHED_METRICS_KEY) |
There was a problem hiding this comment.
just confirm, no "err" is returned?
There was a problem hiding this comment.
I checked the part code and found that the second return value, marked as "flags" in its documentation, actually returns an error when an error occurs.
Let me fix this part of the code.
|
|
||
| -- Clear the cached data after cache_exptime to prevent stale data in case of an error. | ||
| local _, err, forcible = shdict_prometheus_cache:set(CACHED_METRICS_KEY, res, cache_exptime) | ||
|
|
| require("apisix.plugins.prometheus.exporter").http_init(prometheus_enabled_in_stream) | ||
| elseif not is_http and core.table.array_find(stream_plugin_names, "prometheus") then | ||
| require("apisix.plugins.prometheus.exporter").stream_init() | ||
| if is_http and (enabled_in_http or enabled_in_stream) then |
There was a problem hiding this comment.
It might be better to add a link to this PR comment here.
|
|
||
|
|
||
| function _M.init_worker() | ||
| -- someone's plugin needs to be initialized after prometheus |
There was a problem hiding this comment.
Hi @SkyeYoung, I'm using Prometheus metrics in my custom plugin, and with this change, there is no guarantee that the prometheus plugin is loaded before mine. What is the correct approach for defining custom metrics now?
Sorry for commenting on a closed PR
There was a problem hiding this comment.
Hi @yurkovoznyak, could you please file an issue describing your problem in detail?
Description
This PR decouples the calculation and output processes of the Prometheus exporter. The "calculation" is performed in the privileged agent process at intervals defined by the
refresh_interval(default is 15s) and written to a shared dict, while the "output" (i.e., the/apisix/prometheus/metricsAPI) is moved to the worker process, which only reads and returns the cached data in the shared dict.The above are just the core changes. In fact, I encountered many other problems, which have been commented or annotated in the corresponding positions, and will not be repeated here.
For the testing part, since the Prometheus exporter currently refreshes data every 15 seconds, I used a smaller interval in the relevant tests to pass the original tests.
Which issue(s) this PR fixes:
Fixes #
Stress Testing
How to
./test.sh init-etcd), nginx(as upstream,./test.sh start-nginx)make run./test.sh create)./test.sh enable-prometheus)./test.sh benchmark)Results
Key Performance Indicators
Performance Impact Summary
Checklist