From d1637a5e82bd4f0c81c3a8b0f9b0296a3298d946 Mon Sep 17 00:00:00 2001 From: Geof Holbrook Date: Thu, 26 Oct 2023 11:45:28 -0400 Subject: [PATCH] pushgateway: adds configuration for omitting job name (for gravel gateway compatibility, etc.) --- README.md | 10 ++++++++++ lib/pushgateway.js | 26 ++++++++++++++++---------- test/pushgatewayTest.js | 13 +++++++++++++ 3 files changed, 39 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 9125dd37..f5ce0981 100644 --- a/README.md +++ b/README.md @@ -581,6 +581,16 @@ gateway = new client.Pushgateway('http://127.0.0.1:9091', { }); ``` +Some gateways such as [Gravel Gateway](https://github.com/sinkingpoint/prometheus-gravel-gateway) do not support grouping by job name, exposing a plain `/metrics` endpoint instead of `/metrics/job/`. It's possible to configure a gateway instance to not require a jobName in the options argument. + +```js + gravelGateway = new client.Pushgateway('http://127.0.0.1:9091', { + timeout: 5000, + requireJobName: false + }); + gravelGateway.pushAdd(); +``` + ### Bucket Generators For convenience, there are two bucket generator functions - linear and diff --git a/lib/pushgateway.js b/lib/pushgateway.js index d2bc64d5..9c37e72f 100644 --- a/lib/pushgateway.js +++ b/lib/pushgateway.js @@ -13,27 +13,32 @@ class Pushgateway { } this.registry = registry; this.gatewayUrl = gatewayUrl; - this.requestOptions = Object.assign({}, options); + const { requireJobName, ...requestOptions } = { + requireJobName: true, + ...options, + }; + this.requireJobName = requireJobName; + this.requestOptions = Object.assign({}, requestOptions); } - pushAdd(params) { - if (!params || !params.jobName) { + pushAdd(params = {}) { + if (this.requireJobName && !params.jobName) { throw new Error('Missing jobName parameter'); } return useGateway.call(this, 'POST', params.jobName, params.groupings); } - push(params) { - if (!params || !params.jobName) { + push(params = {}) { + if (this.requireJobName && !params.jobName) { throw new Error('Missing jobName parameter'); } return useGateway.call(this, 'PUT', params.jobName, params.groupings); } - delete(params) { - if (!params || !params.jobName) { + delete(params = {}) { + if (this.requireJobName && !params.jobName) { throw new Error('Missing jobName parameter'); } @@ -48,9 +53,10 @@ async function useGateway(method, job, groupings) { gatewayUrlParsed.pathname && gatewayUrlParsed.pathname !== '/' ? gatewayUrlParsed.pathname : ''; - const path = `${gatewayUrlPath}/metrics/job/${encodeURIComponent( - job, - )}${generateGroupings(groupings)}`; + const jobPath = job + ? `/job/${encodeURIComponent(job)}${generateGroupings(groupings)}` + : ''; + const path = `${gatewayUrlPath}/metrics${jobPath}`; // eslint-disable-next-line node/no-deprecated-api const target = url.resolve(this.gatewayUrl, path); diff --git a/test/pushgatewayTest.js b/test/pushgatewayTest.js index 03ab68a3..2171d861 100644 --- a/test/pushgatewayTest.js +++ b/test/pushgatewayTest.js @@ -96,6 +96,19 @@ describe.each([ expect(err.message).toStrictEqual('Pushgateway request timed out'); }); }); + + it('should be possible to configure for gravel gateway integration (no job name required in path)', async () => { + const mockHttp = nock('http://192.168.99.100:9091') + .post('/metrics', body) + .reply(200); + + instance.requireJobName = false; + + return instance.pushAdd().then(() => { + instance.requireJobName = true; + return expect(mockHttp.isDone()); + }); + }); }); describe('push', () => {