From 60d748c2ad0a6607c1ca519d39c404c223927118 Mon Sep 17 00:00:00 2001 From: Luna Date: Sat, 19 Nov 2022 21:30:19 +0000 Subject: [PATCH] Add metrics instrumentation. I sure hope this works --- package.json | 2 ++ src/index.ts | 28 +++++++++++++++++- src/tracing.ts | 80 ++++++++++++++++++++++++++++++++++++++++++-------- yarn.lock | 26 +++++++++++++++- 4 files changed, 121 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index ca7a7eb..2058c0d 100644 --- a/package.json +++ b/package.json @@ -22,7 +22,9 @@ "dependencies": { "@opentelemetry/api": "^1.3.0", "@opentelemetry/auto-instrumentations-node": "^0.35.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "^0.34.0", "@opentelemetry/exporter-trace-otlp-grpc": "^0.34.0", + "@opentelemetry/sdk-metrics": "^1.8.0", "@opentelemetry/sdk-node": "^0.34.0", "@opentelemetry/semantic-conventions": "^1.8.0", "@prisma/client": "^4.0.0", diff --git a/src/index.ts b/src/index.ts index 9777428..5a8ebea 100644 --- a/src/index.ts +++ b/src/index.ts @@ -5,9 +5,12 @@ import process from 'process'; import * as dotenv from "dotenv"; dotenv.config({path: __dirname + '/.env'}); +let tracing: any = {}; + if (process.env.OPENTELEMETRY_ENABLED === "true") { console.log('Enabling OpenTelemetry-compatible tracing...'); - require('./tracing'); + tracing = require('./tracing'); + tracing.startTracing(); } import express, { Router } from 'express'; @@ -61,6 +64,29 @@ if (useSentry) { }); } +if (process.env.OPENTELEMETRY_ENABLED === "true") { + tracing.startHttpMetrics([ + { + app, + options: { + appName: 'service' + } + }, + { + app: muchaApp, + options: { + appName: 'mucha' + } + }, + { + app: allnetApp, + options: { + appName: 'allnet' + } + } + ]); +} + // Get the current timestamp let timestamp: string = common.getTimeStamp(); diff --git a/src/tracing.ts b/src/tracing.ts index e7a319a..1afc166 100644 --- a/src/tracing.ts +++ b/src/tracing.ts @@ -7,20 +7,74 @@ import { OTLPTraceExporter } from '@opentelemetry/exporter-trace-otlp-grpc'; import { Resource } from '@opentelemetry/resources'; import { SemanticResourceAttributes } from '@opentelemetry/semantic-conventions'; import process from 'process'; +import {Request, Response, Application} from 'express'; +import { AggregationTemporality, MeterProvider, PeriodicExportingMetricReader } from '@opentelemetry/sdk-metrics'; +import { OTLPMetricExporter } from '@opentelemetry/exporter-metrics-otlp-grpc'; -diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO); +export function startTracing() { + diag.setLogger(new DiagConsoleLogger(), DiagLogLevel.INFO); -const sdk = new opentelemetry.NodeSDK({ - traceExporter: new OTLPTraceExporter({ + const sdk = new opentelemetry.NodeSDK({ + traceExporter: new OTLPTraceExporter({ + url: process.env.OPENTELEMETRY_OTLP_URI, + headers: {} + }), + resource: new Resource({ + [SemanticResourceAttributes.SERVICE_NAME]: 'bayshore', + [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: + process.env.NODE_ENV !== undefined ? process.env.NODE_ENV : 'development', + }), + instrumentations: [getNodeAutoInstrumentations()] + }); + + sdk.start(); +} + +interface MiddlewareOpts { + appName: string, +} + +interface HttpMetricsParameter { + app: Application, + options: MiddlewareOpts +} + +// TODO: Implement stuff in such a way to make it be possible to view data like +// time attack clears per hour, story stuff etc etc. Not now tho, later +export function startHttpMetrics(apps: HttpMetricsParameter[]) { + const provider = new MeterProvider(); + + function configureMiddleware(opts: MiddlewareOpts) { + let meter = provider.getMeter(opts.appName); + var counter = meter.createCounter('requests_made', { + description: 'Number of requests registered to application' + }); + + return function(req: Request, res: Response, next: CallableFunction) { + counter.add(1, { + url: req.url + }); + next(); + } + } + + console.log('Registering middleware metrics'); + + for (let appObj of apps) { + console.log(`Registered metrics application for ${appObj.options.appName}`); + appObj.app.use(configureMiddleware(appObj.options)); + } + + const exporter = new OTLPMetricExporter({ url: process.env.OPENTELEMETRY_OTLP_URI, - headers: {} - }), - resource: new Resource({ - [SemanticResourceAttributes.SERVICE_NAME]: 'bayshore', - [SemanticResourceAttributes.DEPLOYMENT_ENVIRONMENT]: - process.env.NODE_ENV !== undefined ? process.env.NODE_ENV : 'development', - }), - instrumentations: [getNodeAutoInstrumentations()] -}); + temporalityPreference: AggregationTemporality.DELTA, + }); -sdk.start(); \ No newline at end of file + provider.addMetricReader(new PeriodicExportingMetricReader({ + exporter, + exportIntervalMillis: 1500, + exportTimeoutMillis: 1000, + })); + + console.log('Metrics started'); +} \ No newline at end of file diff --git a/yarn.lock b/yarn.lock index a523905..fbd5d4a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -198,6 +198,30 @@ "@opentelemetry/semantic-conventions" "1.8.0" jaeger-client "^3.15.0" +"@opentelemetry/exporter-metrics-otlp-grpc@^0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.34.0.tgz#3a84f4e2c21ce5c9dce507ff36715cc2536bfa87" + integrity sha512-9INc1TBJ7OwpMsImqUjpPEvQeRyyU9tEiFQIYQ53kKQK7V8MqB5koyDeb5/qBSbNu4ZxSpukAOLPgBOEMDK6Qw== + dependencies: + "@grpc/grpc-js" "^1.7.1" + "@opentelemetry/core" "1.8.0" + "@opentelemetry/exporter-metrics-otlp-http" "0.34.0" + "@opentelemetry/otlp-grpc-exporter-base" "0.34.0" + "@opentelemetry/otlp-transformer" "0.34.0" + "@opentelemetry/resources" "1.8.0" + "@opentelemetry/sdk-metrics" "1.8.0" + +"@opentelemetry/exporter-metrics-otlp-http@0.34.0": + version "0.34.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.34.0.tgz#f890a83f695b60719e54492e72bcbfa21d2968ee" + integrity sha512-ToRJA4frErHGiKKnPCI3+cvdyK8rksRI+mV6xZ6Yt7HiIrArY9eDX7QaCEZcTLbQIib09LTlCX87TKEL3TToWQ== + dependencies: + "@opentelemetry/core" "1.8.0" + "@opentelemetry/otlp-exporter-base" "0.34.0" + "@opentelemetry/otlp-transformer" "0.34.0" + "@opentelemetry/resources" "1.8.0" + "@opentelemetry/sdk-metrics" "1.8.0" + "@opentelemetry/exporter-trace-otlp-grpc@0.34.0", "@opentelemetry/exporter-trace-otlp-grpc@^0.34.0": version "0.34.0" resolved "https://registry.yarnpkg.com/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.34.0.tgz#6ec4a897f263e371f4ce8e3b1aa83167fe6aedc2" @@ -638,7 +662,7 @@ "@opentelemetry/core" "1.8.0" "@opentelemetry/semantic-conventions" "1.8.0" -"@opentelemetry/sdk-metrics@1.8.0": +"@opentelemetry/sdk-metrics@1.8.0", "@opentelemetry/sdk-metrics@^1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@opentelemetry/sdk-metrics/-/sdk-metrics-1.8.0.tgz#d061060f03861ab3f345d0f924922bc1a6396157" integrity sha512-+KYb+uj0vHhl8xzJO+oChS4oP1e+/2Wl3SXoHoIdcEjd1TQfDV+lxOm4oqxWq6wykXvI35/JHyejxSoT+qxGmg==