From 5522ac55ac00d4b809d942d0a8c58d15b0432fb8 Mon Sep 17 00:00:00 2001 From: Rainer Killinger Date: Wed, 8 Jun 2022 17:44:57 +0200 Subject: [PATCH] feat: added prometheus metrics support --- Dockerfile | 1 + config/default.ts | 3 ++- fixtures/metrics.template | 7 +++++++ nginx.conf | 3 +++ nginx.conf.template | 2 ++ src/common.ts | 10 +++++++++- src/main.ts | 11 +++++++++++ test/main.spec.ts | 11 +++++++++++ 8 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 fixtures/metrics.template diff --git a/Dockerfile b/Dockerfile index 08701f6f..843f9e39 100644 --- a/Dockerfile +++ b/Dockerfile @@ -6,6 +6,7 @@ RUN apk update && \ apk upgrade && \ apk add openssl && \ apk add nginx && \ + apk add nginx-mod-http-vts && \ rm -rf /var/cache/apk/* ADD . /app diff --git a/config/default.ts b/config/default.ts index 3c086908..7416fc84 100644 --- a/config/default.ts +++ b/config/default.ts @@ -16,8 +16,9 @@ import {ConfigFile} from '../src/common'; const config: ConfigFile = { - activeVersions: ['1\\.0\\.\\d+','2\\.0\\.\\d+'], + activeVersions: ['1\\.0\\.\\d+', '2\\.0\\.\\d+'], hiddenRoutes: ['/bulk'], + metrics: false, outdatedVersions: ['0\\.8\\.\\d+', '0\\.5\\.\\d+', '0\\.6\\.\\d+', '0\\.7\\.\\d+'], output: '/etc/nginx/http.d/default.conf', rateLimitAllowList: ['127.0.0.1/32'], diff --git a/fixtures/metrics.template b/fixtures/metrics.template new file mode 100644 index 00000000..09ce8ecf --- /dev/null +++ b/fixtures/metrics.template @@ -0,0 +1,7 @@ +server { + listen 8080; + location /metrics { + vhost_traffic_status_display; + vhost_traffic_status_display_format prometheus; + } +} diff --git a/nginx.conf b/nginx.conf index 7ed5f4a4..bd895a98 100644 --- a/nginx.conf +++ b/nginx.conf @@ -1,3 +1,5 @@ +load_module modules/ngx_http_vhost_traffic_status_module.so; + worker_processes 1; error_log stderr; @@ -9,6 +11,7 @@ events { } http { + vhost_traffic_status_zone; include mime.types; default_type application/octet-stream; access_log /dev/stdout; diff --git a/nginx.conf.template b/nginx.conf.template index bf6ef76a..34f570ee 100644 --- a/nginx.conf.template +++ b/nginx.conf.template @@ -1,3 +1,5 @@ +{{{ metrics }}} + {{{ dockerVersionMap }}} # create a custom request limit zone which can handle 160,000 IP-Addresses at the same time diff --git a/src/common.ts b/src/common.ts index 18af13d7..1a6e9f03 100644 --- a/src/common.ts +++ b/src/common.ts @@ -59,12 +59,16 @@ export interface ConfigFile { * List of hidden routes */ hiddenRoutes: string[]; + /** + * Enables metrics on /metrics route + */ + metrics: boolean; /** * List of outdated versions */ outdatedVersions: string[]; /** - * Output?! TODO + * Path the generated config will be written to */ output: string; /** @@ -93,6 +97,10 @@ export interface TemplateView { * Listener */ listener: string; + /** + * Local server with listener for /metrics route + */ + metrics: string; /** * Allow list for rate limiting */ diff --git a/src/main.ts b/src/main.ts index 573ff941..0ece216d 100644 --- a/src/main.ts +++ b/src/main.ts @@ -241,6 +241,16 @@ ${protocolHardeningParameters} return listener; } +/** + * Reads predefined server entry with metrics location + */ +export async function generateMetricsServer(enableMetrics: boolean): Promise { + if (!enableMetrics) { + return ''; + } + return asyncReadFile('./fixtures/metrics.template', 'utf8'); +} + /** * Render a mustache template file with given view object * @@ -300,6 +310,7 @@ export async function getTemplateView(containers: Dockerode.ContainerInfo[]): Pr ), hiddenRoutes: (await Promise.all(hiddenRoutesPromises)).join(''), listener: generateListener(configFile.sslFilePaths), + metrics: await generateMetricsServer(configFile.metrics), rateLimitAllowList: generateRateLimitAllowList(configFile.rateLimitAllowList), staticRoute: await renderTemplate(path.join('fixtures', 'staticRoute.template'), {cors}), visibleRoutes: (await Promise.all(visibleRoutesPromises)).join(''), diff --git a/test/main.spec.ts b/test/main.spec.ts index 53101cb2..65ff6b07 100644 --- a/test/main.spec.ts +++ b/test/main.spec.ts @@ -31,6 +31,7 @@ import { getGatewayOfStAppsBackend, getTemplateView, generateListener, + generateMetricsServer, getContainers, } from '../src/main'; import {resolve} from 'path'; @@ -399,6 +400,16 @@ Please check if docker is running and Node.js can access the docker socket (/var return true; } + @test + async 'include metrics config'() { + expect(await generateMetricsServer(true)).length.to.be.greaterThan(1); + } + + @test + async 'omit metrics config'() { + expect(await generateMetricsServer(false)).to.equal(''); + } + @test 'create listener faulty config'() { expect(