From e918c3720f3b2dc1e9ad1919ca626e29022c3424 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fredrik=20Adel=C3=B6w?= Date: Sun, 28 May 2023 21:07:48 +0200 Subject: [PATCH] added an opentelemetry prometheus exporter and example config to the example backend MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Fredrik Adelöw --- packages/backend/package.json | 3 ++ packages/backend/prometheus.yml | 21 +++++++++++ packages/backend/src/index.ts | 15 ++++++-- yarn.lock | 63 +++++++++++++++++++++++++++++++-- 4 files changed, 98 insertions(+), 4 deletions(-) create mode 100644 packages/backend/prometheus.yml diff --git a/packages/backend/package.json b/packages/backend/package.json index f225e35d98..2d0b615db0 100644 --- a/packages/backend/package.json +++ b/packages/backend/package.json @@ -73,6 +73,9 @@ "@backstage/plugin-todo-backend": "workspace:^", "@gitbeaker/node": "^35.1.0", "@octokit/rest": "^19.0.3", + "@opentelemetry/api": "^1.4.1", + "@opentelemetry/exporter-prometheus": "^0.39.1", + "@opentelemetry/sdk-metrics": "^1.13.0", "azure-devops-node-api": "^11.0.1", "better-sqlite3": "^8.0.0", "dockerode": "^3.3.1", diff --git a/packages/backend/prometheus.yml b/packages/backend/prometheus.yml new file mode 100644 index 0000000000..bdb0964a2f --- /dev/null +++ b/packages/backend/prometheus.yml @@ -0,0 +1,21 @@ +# This is an example configuration file for Prometheus, that is set to scrape +# the metrics endpoint exposed by the example backend. +# +# If you want to run a docker based Prometheus instance locally to try it out, +# run the following command in the Backstage root: +# +# docker run --mount type=bind,source=./packages/backend/prometheus.yml,destination=/etc/prometheus/prometheus.yml --publish published=9090,target=9090,protocol=tcp prom/prometheus +# +# After this, you have a Prometheus instance on http://localhost:9090 + +global: + scrape_interval: 15s + evaluation_interval: 15s + +scrape_configs: + - job_name: 'prometheus' + static_configs: + # This target address specifically works on Docker for MacOS - you may + # need to change it to another host depending on your OS and Docker + # engine. + - targets: ['host.docker.internal:9464'] diff --git a/packages/backend/src/index.ts b/packages/backend/src/index.ts index 976ad9a577..5d22ec92e8 100644 --- a/packages/backend/src/index.ts +++ b/packages/backend/src/index.ts @@ -30,7 +30,7 @@ import { loadBackendConfig, notFoundHandler, DatabaseManager, - SingleHostDiscovery, + HostDiscovery, UrlReaders, useHotMemoize, ServerTokenManager, @@ -69,11 +69,22 @@ import { PluginEnvironment } from './types'; import { ServerPermissionClient } from '@backstage/plugin-permission-node'; import { DefaultIdentityClient } from '@backstage/plugin-auth-node'; import { DefaultEventBroker } from '@backstage/plugin-events-backend'; +import { PrometheusExporter } from '@opentelemetry/exporter-prometheus'; +import { MeterProvider } from '@opentelemetry/sdk-metrics'; +import { metrics } from '@opentelemetry/api'; + +// Expose opentelemetry metrics using a Prometheus exporter on +// http://localhost:9464/metrics . See prometheus.yml in packages/backend for +// more information on how to scrape it. +const exporter = new PrometheusExporter(); +const meterProvider = new MeterProvider(); +metrics.setGlobalMeterProvider(meterProvider); +meterProvider.addMetricReader(exporter); function makeCreateEnv(config: Config) { const root = getRootLogger(); const reader = UrlReaders.default({ logger: root, config }); - const discovery = SingleHostDiscovery.fromConfig(config); + const discovery = HostDiscovery.fromConfig(config); const tokenManager = ServerTokenManager.fromConfig(config, { logger: root }); const permissions = ServerPermissionClient.fromConfig(config, { discovery, diff --git a/yarn.lock b/yarn.lock index 8415e4b6ae..92a6a868db 100644 --- a/yarn.lock +++ b/yarn.lock @@ -14004,13 +14004,69 @@ __metadata: languageName: node linkType: hard -"@opentelemetry/api@npm:^1.0.1, @opentelemetry/api@npm:^1.3.0": +"@opentelemetry/api@npm:^1.0.1, @opentelemetry/api@npm:^1.3.0, @opentelemetry/api@npm:^1.4.1": version: 1.4.1 resolution: "@opentelemetry/api@npm:1.4.1" checksum: e783c40d1a518abf9c4c5d65223237c1392cd9a6c53ac6e2c3ef0c05ff7266e3dfc4fd9874316dae0dcb7a97950878deb513bcbadfaad653d48f0215f2a0911b languageName: node linkType: hard +"@opentelemetry/core@npm:1.13.0": + version: 1.13.0 + resolution: "@opentelemetry/core@npm:1.13.0" + dependencies: + "@opentelemetry/semantic-conventions": 1.13.0 + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.5.0" + checksum: a69916bcb710f1241e98a58ac5f5dfbc3372fdcd6cb2a4b2d33cdeb941765ecbdeea029f60f650a5743a56f583b0f06b672566467b89db84a24f1304bf2e5205 + languageName: node + linkType: hard + +"@opentelemetry/exporter-prometheus@npm:^0.39.1": + version: 0.39.1 + resolution: "@opentelemetry/exporter-prometheus@npm:0.39.1" + dependencies: + "@opentelemetry/core": 1.13.0 + "@opentelemetry/resources": 1.13.0 + "@opentelemetry/sdk-metrics": 1.13.0 + peerDependencies: + "@opentelemetry/api": ^1.3.0 + checksum: 97697926ef26e3dca9654b6ea8d2ab8e7fc7fc33ce617d25a6eb70c0ef2e2fe47192fcede15cbe45179d0ade67e55769bbed11c691d34f9e59ebd50aab22add7 + languageName: node + linkType: hard + +"@opentelemetry/resources@npm:1.13.0": + version: 1.13.0 + resolution: "@opentelemetry/resources@npm:1.13.0" + dependencies: + "@opentelemetry/core": 1.13.0 + "@opentelemetry/semantic-conventions": 1.13.0 + peerDependencies: + "@opentelemetry/api": ">=1.0.0 <1.5.0" + checksum: ef0a11596f27b5e1c13b74357da06c5c2725a1056df0a583562dbcc739927ad85bb8bdec4e01f4b43f348b448c0146c033b135840a7d388b75cc751a33a6364e + languageName: node + linkType: hard + +"@opentelemetry/sdk-metrics@npm:1.13.0, @opentelemetry/sdk-metrics@npm:^1.13.0": + version: 1.13.0 + resolution: "@opentelemetry/sdk-metrics@npm:1.13.0" + dependencies: + "@opentelemetry/core": 1.13.0 + "@opentelemetry/resources": 1.13.0 + lodash.merge: 4.6.2 + peerDependencies: + "@opentelemetry/api": ">=1.3.0 <1.5.0" + checksum: 2f87444b6c789acdde3465383b4255b072e201cf9bed642e82970540bfe913d76d4c4ebf8cc1ff3da383d3235dd8399cd6407fac86085a9ac9ff5b5b3afc9f38 + languageName: node + linkType: hard + +"@opentelemetry/semantic-conventions@npm:1.13.0": + version: 1.13.0 + resolution: "@opentelemetry/semantic-conventions@npm:1.13.0" + checksum: 9cccf1d73315fed3920bb2201c0e82f66e58dddfa475314b6613780c2804570d6f657be3894eb8b84a2a543c9b8cd520587f5d6cd4b62bc6731d7299b4c5ee69 + languageName: node + linkType: hard + "@oriflame/backstage-plugin-score-card@npm:^0.6.0": version: 0.6.3 resolution: "@oriflame/backstage-plugin-score-card@npm:0.6.3" @@ -24425,6 +24481,9 @@ __metadata: "@backstage/plugin-todo-backend": "workspace:^" "@gitbeaker/node": ^35.1.0 "@octokit/rest": ^19.0.3 + "@opentelemetry/api": ^1.4.1 + "@opentelemetry/exporter-prometheus": ^0.39.1 + "@opentelemetry/sdk-metrics": ^1.13.0 "@types/dockerode": ^3.3.0 "@types/express": ^4.17.6 "@types/express-serve-static-core": ^4.17.5 @@ -30244,7 +30303,7 @@ __metadata: languageName: node linkType: hard -"lodash.merge@npm:^4.6.2": +"lodash.merge@npm:4.6.2, lodash.merge@npm:^4.6.2": version: 4.6.2 resolution: "lodash.merge@npm:4.6.2" checksum: ad580b4bdbb7ca1f7abf7e1bce63a9a0b98e370cf40194b03380a46b4ed799c9573029599caebc1b14e3f24b111aef72b96674a56cfa105e0f5ac70546cdc005