diff --git a/CHANGELOG.md b/CHANGELOG.md index 127771a1..829147aa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -16,6 +16,8 @@ project adheres to [Semantic Versioning](http://semver.org/). ### Added +- Allow Pushgateway to now require job names for compatibility with Gravel Gateway. + ## [15.0.0] - 2023-10-09 ### Breaking diff --git a/README.md b/README.md index 9125dd37..a0d0684d 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..8ea65569 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 = 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..f7a510e9 100644 --- a/test/pushgatewayTest.js +++ b/test/pushgatewayTest.js @@ -96,6 +96,23 @@ 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 = new Pushgateway( + 'http://192.168.99.100:9091', + { + timeout: 10, + requireJobName: false, + }, + registry, + ); + + return instance.pushAdd().then(() => expect(mockHttp.isDone())); + }); }); describe('push', () => {