From b93cf2b5fc6a84ff6e16d1af134d68e5ecee9a00 Mon Sep 17 00:00:00 2001 From: "marc.pichler" Date: Tue, 15 Nov 2022 14:03:32 +0100 Subject: [PATCH 1/6] [paymentservice] add basic metrics support --- docker-compose.yml | 2 + src/paymentservice/Dockerfile | 2 +- src/paymentservice/charge.js | 12 +- src/paymentservice/opentelemetry.js | 15 ++ src/paymentservice/package-lock.json | 266 ++++++++++++++++++++------- src/paymentservice/package.json | 7 +- src/paymentservice/tracing.js | 10 - 7 files changed, 231 insertions(+), 83 deletions(-) create mode 100644 src/paymentservice/opentelemetry.js delete mode 100644 src/paymentservice/tracing.js diff --git a/docker-compose.yml b/docker-compose.yml index f8c6b3a480..b647319cad 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -286,6 +286,8 @@ services: environment: - PAYMENT_SERVICE_PORT - OTEL_EXPORTER_OTLP_TRACES_ENDPOINT + - OTEL_EXPORTER_OTLP_METRICS_ENDPOINT + - OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE - OTEL_SERVICE_NAME=paymentservice depends_on: - otelcol diff --git a/src/paymentservice/Dockerfile b/src/paymentservice/Dockerfile index 6c03e62579..4f690d4c7c 100644 --- a/src/paymentservice/Dockerfile +++ b/src/paymentservice/Dockerfile @@ -33,4 +33,4 @@ COPY ./src/paymentservice/ ./ COPY ./pb/demo.proto ./ EXPOSE ${PAYMENT_SERVICE_PORT} -ENTRYPOINT [ "node", "--require", "./tracing.js", "./index.js" ] +ENTRYPOINT [ "npm", "run", "start" ] diff --git a/src/paymentservice/charge.js b/src/paymentservice/charge.js index de8aafbcac..55df65c872 100644 --- a/src/paymentservice/charge.js +++ b/src/paymentservice/charge.js @@ -13,16 +13,20 @@ // limitations under the License. const {context, propagation, trace} = require('@opentelemetry/api'); +const { metrics } = require('@opentelemetry/api-metrics'); const cardValidator = require('simple-card-validator'); const { v4: uuidv4 } = require('uuid'); const logger = require('./logger'); const tracer = trace.getTracer('paymentservice'); +const meter = metrics.getMeter('paymentservice'); +const transactionsCounter = meter.createCounter('app.payment.transactions') module.exports.charge = request => { const span = tracer.startSpan('charge'); - const { creditCardNumber: number, + const { + creditCardNumber: number, creditCardExpirationYear: year, creditCardExpirationMonth: month } = request.creditCard; @@ -32,7 +36,7 @@ module.exports.charge = request => { const transactionId = uuidv4(); const card = cardValidator(number); - const {card_type: cardType, valid } = card.getCardDetails(); + const { card_type: cardType, valid } = card.getCardDetails(); span.setAttributes({ 'app.payment.card_type': cardType, @@ -53,7 +57,7 @@ module.exports.charge = request => { // check baggage for synthetic_request=true, and add charged attribute accordingly const baggage = propagation.getBaggage(context.active()); - if (baggage && baggage.getEntry("synthetic_request") && baggage.getEntry("synthetic_request").value == "true") { + if (baggage && baggage.getEntry("synthetic_request") && baggage.getEntry("synthetic_request").value === "true") { span.setAttribute('app.payment.charged', false); } else { span.setAttribute('app.payment.charged', true); @@ -63,6 +67,6 @@ module.exports.charge = request => { const { units, nanos, currencyCode } = request.amount; logger.info({transactionId, cardType, lastFourDigits, amount: { units, nanos, currencyCode }}, "Transaction complete."); - + transactionsCounter.add(1, {"app.payment.currency": currencyCode}) return { transactionId } } diff --git a/src/paymentservice/opentelemetry.js b/src/paymentservice/opentelemetry.js new file mode 100644 index 0000000000..16402fe747 --- /dev/null +++ b/src/paymentservice/opentelemetry.js @@ -0,0 +1,15 @@ +const opentelemetry = require("@opentelemetry/sdk-node") +const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node") +const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc') +const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc') +const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); + +const sdk = new opentelemetry.NodeSDK({ + traceExporter: new OTLPTraceExporter(), + instrumentations: [ getNodeAutoInstrumentations() ], + metricReader: new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter() + }), +}) + +sdk.start().then(() => require("./index")); diff --git a/src/paymentservice/package-lock.json b/src/paymentservice/package-lock.json index 2a401d4d96..23858ae5d9 100644 --- a/src/paymentservice/package-lock.json +++ b/src/paymentservice/package-lock.json @@ -11,8 +11,11 @@ "dependencies": { "@grpc/grpc-js": "1.7.3", "@grpc/proto-loader": "^0.7.3", + "@opentelemetry/api": "^1.2.0", + "@opentelemetry/api-metrics": "^0.33.0", "@opentelemetry/auto-instrumentations-node": "0.33.1", "@opentelemetry/core": "1.7.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "^0.33.0", "@opentelemetry/exporter-trace-otlp-grpc": "0.33.0", "@opentelemetry/sdk-node": "0.33.0", "grpc-js-health-check": "^1.0.2", @@ -172,9 +175,10 @@ } }, "node_modules/@opentelemetry/api-metrics": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.32.0.tgz", - "integrity": "sha512-g1WLhpG8B6iuDyZJFRGsR+JKyZ94m5LEmY2f+duEJ9Xb4XRlLHrZvh6G34OH6GJ8iDHxfHb/sWjJ1ZpkI9yGMQ==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.33.0.tgz", + "integrity": "sha512-78evfPRRRnJA6uZ3xuBuS3VZlXTO/LRs+Ff1iv3O/7DgibCtq9k27T6Zlj8yRdJDFmcjcbQrvC0/CpDpWHaZYA==", + "deprecated": "Please use @opentelemetry/api >= 1.3.0", "dependencies": { "@opentelemetry/api": "^1.0.0" }, @@ -261,6 +265,89 @@ "node": ">=14" } }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.33.0.tgz", + "integrity": "sha512-UBKPsLR7pcwU64yc+9ZKX/bwWPuzdYYR2iSwwPqjQ8IxI2et2668xG2ESXhzRlYLcoK/AyjTagEp1egBQVHXKg==", + "dependencies": { + "@grpc/grpc-js": "^1.5.9", + "@grpc/proto-loader": "^0.6.9", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc/node_modules/@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "dependencies": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + }, + "bin": { + "proto-loader-gen-types": "build/bin/proto-loader-gen-types.js" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-grpc/node_modules/protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "hasInstallScript": true, + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + }, + "bin": { + "pbjs": "bin/pbjs", + "pbts": "bin/pbts" + } + }, + "node_modules/@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.33.0.tgz", + "integrity": "sha512-zFwE3mEQ0UIaAqWqf/FjZ4AJh7mTjg5uv5XG7Z2R2brNLTBBBfFkq/GTkmzfGDjQabXo4Ic5eDTZ/I28H6eFqg==", + "dependencies": { + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/otlp-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.0.0" + } + }, "node_modules/@opentelemetry/exporter-trace-otlp-grpc": { "version": "0.33.0", "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.33.0.tgz", @@ -551,6 +638,18 @@ "@opentelemetry/api": "^1.0.0" } }, + "node_modules/@opentelemetry/instrumentation-grpc/node_modules/@opentelemetry/api-metrics": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.32.0.tgz", + "integrity": "sha512-g1WLhpG8B6iuDyZJFRGsR+JKyZ94m5LEmY2f+duEJ9Xb4XRlLHrZvh6G34OH6GJ8iDHxfHb/sWjJ1ZpkI9yGMQ==", + "deprecated": "Please use @opentelemetry/api >= 1.3.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@opentelemetry/instrumentation-hapi": { "version": "0.30.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-hapi/-/instrumentation-hapi-0.30.0.tgz", @@ -863,6 +962,18 @@ "@opentelemetry/api": "^1.0.0" } }, + "node_modules/@opentelemetry/instrumentation/node_modules/@opentelemetry/api-metrics": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.32.0.tgz", + "integrity": "sha512-g1WLhpG8B6iuDyZJFRGsR+JKyZ94m5LEmY2f+duEJ9Xb4XRlLHrZvh6G34OH6GJ8iDHxfHb/sWjJ1ZpkI9yGMQ==", + "deprecated": "Please use @opentelemetry/api >= 1.3.0", + "dependencies": { + "@opentelemetry/api": "^1.0.0" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/@opentelemetry/otlp-exporter-base": { "version": "0.33.0", "resolved": "https://registry.npmjs.org/@opentelemetry/otlp-exporter-base/-/otlp-exporter-base-0.33.0.tgz", @@ -955,17 +1066,6 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0" } }, - "node_modules/@opentelemetry/otlp-transformer/node_modules/@opentelemetry/api-metrics": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.33.0.tgz", - "integrity": "sha512-78evfPRRRnJA6uZ3xuBuS3VZlXTO/LRs+Ff1iv3O/7DgibCtq9k27T6Zlj8yRdJDFmcjcbQrvC0/CpDpWHaZYA==", - "dependencies": { - "@opentelemetry/api": "^1.0.0" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/@opentelemetry/propagation-utils": { "version": "0.29.0", "resolved": "https://registry.npmjs.org/@opentelemetry/propagation-utils/-/propagation-utils-0.29.0.tgz", @@ -1059,17 +1159,6 @@ "@opentelemetry/api": "^1.0.0" } }, - "node_modules/@opentelemetry/sdk-metrics/node_modules/@opentelemetry/api-metrics": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.33.0.tgz", - "integrity": "sha512-78evfPRRRnJA6uZ3xuBuS3VZlXTO/LRs+Ff1iv3O/7DgibCtq9k27T6Zlj8yRdJDFmcjcbQrvC0/CpDpWHaZYA==", - "dependencies": { - "@opentelemetry/api": "^1.0.0" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/@opentelemetry/sdk-node": { "version": "0.33.0", "resolved": "https://registry.npmjs.org/@opentelemetry/sdk-node/-/sdk-node-0.33.0.tgz", @@ -1090,17 +1179,6 @@ "@opentelemetry/api": ">=1.0.0 <1.3.0" } }, - "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/api-metrics": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.33.0.tgz", - "integrity": "sha512-78evfPRRRnJA6uZ3xuBuS3VZlXTO/LRs+Ff1iv3O/7DgibCtq9k27T6Zlj8yRdJDFmcjcbQrvC0/CpDpWHaZYA==", - "dependencies": { - "@opentelemetry/api": "^1.0.0" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/@opentelemetry/sdk-node/node_modules/@opentelemetry/instrumentation": { "version": "0.33.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.33.0.tgz", @@ -2532,9 +2610,9 @@ "integrity": "sha512-0nBr+VZNKm9tvNDZFstI3Pq1fCTEDK5OZTnVKNvBNAKgd0yIvmwsP4m61rEv7ZP+tOUjWJhROpxK5MsnlF911g==" }, "@opentelemetry/api-metrics": { - "version": "0.32.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.32.0.tgz", - "integrity": "sha512-g1WLhpG8B6iuDyZJFRGsR+JKyZ94m5LEmY2f+duEJ9Xb4XRlLHrZvh6G34OH6GJ8iDHxfHb/sWjJ1ZpkI9yGMQ==", + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.33.0.tgz", + "integrity": "sha512-78evfPRRRnJA6uZ3xuBuS3VZlXTO/LRs+Ff1iv3O/7DgibCtq9k27T6Zlj8yRdJDFmcjcbQrvC0/CpDpWHaZYA==", "requires": { "@opentelemetry/api": "^1.0.0" } @@ -2600,6 +2678,68 @@ } } }, + "@opentelemetry/exporter-metrics-otlp-grpc": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-grpc/-/exporter-metrics-otlp-grpc-0.33.0.tgz", + "integrity": "sha512-UBKPsLR7pcwU64yc+9ZKX/bwWPuzdYYR2iSwwPqjQ8IxI2et2668xG2ESXhzRlYLcoK/AyjTagEp1egBQVHXKg==", + "requires": { + "@grpc/grpc-js": "^1.5.9", + "@grpc/proto-loader": "^0.6.9", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/exporter-metrics-otlp-http": "0.33.0", + "@opentelemetry/otlp-grpc-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0" + }, + "dependencies": { + "@grpc/proto-loader": { + "version": "0.6.13", + "resolved": "https://registry.npmjs.org/@grpc/proto-loader/-/proto-loader-0.6.13.tgz", + "integrity": "sha512-FjxPYDRTn6Ec3V0arm1FtSpmP6V50wuph2yILpyvTKzjc76oDdoihXqM1DzOW5ubvCC8GivfCnNtfaRE8myJ7g==", + "requires": { + "@types/long": "^4.0.1", + "lodash.camelcase": "^4.3.0", + "long": "^4.0.0", + "protobufjs": "^6.11.3", + "yargs": "^16.2.0" + } + }, + "protobufjs": { + "version": "6.11.3", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-6.11.3.tgz", + "integrity": "sha512-xL96WDdCZYdU7Slin569tFX712BxsxslWwAfAhCYjQKGTq7dAU91Lomy6nLLhh/dyGhk/YH4TwTSRxTzhuHyZg==", + "requires": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/long": "^4.0.1", + "@types/node": ">=13.7.0", + "long": "^4.0.0" + } + } + } + }, + "@opentelemetry/exporter-metrics-otlp-http": { + "version": "0.33.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-metrics-otlp-http/-/exporter-metrics-otlp-http-0.33.0.tgz", + "integrity": "sha512-zFwE3mEQ0UIaAqWqf/FjZ4AJh7mTjg5uv5XG7Z2R2brNLTBBBfFkq/GTkmzfGDjQabXo4Ic5eDTZ/I28H6eFqg==", + "requires": { + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/core": "1.7.0", + "@opentelemetry/otlp-exporter-base": "0.33.0", + "@opentelemetry/otlp-transformer": "0.33.0", + "@opentelemetry/resources": "1.7.0", + "@opentelemetry/sdk-metrics": "0.33.0" + } + }, "@opentelemetry/exporter-trace-otlp-grpc": { "version": "0.33.0", "resolved": "https://registry.npmjs.org/@opentelemetry/exporter-trace-otlp-grpc/-/exporter-trace-otlp-grpc-0.33.0.tgz", @@ -2657,6 +2797,16 @@ "require-in-the-middle": "^5.0.3", "semver": "^7.3.2", "shimmer": "^1.2.1" + }, + "dependencies": { + "@opentelemetry/api-metrics": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.32.0.tgz", + "integrity": "sha512-g1WLhpG8B6iuDyZJFRGsR+JKyZ94m5LEmY2f+duEJ9Xb4XRlLHrZvh6G34OH6GJ8iDHxfHb/sWjJ1ZpkI9yGMQ==", + "requires": { + "@opentelemetry/api": "^1.0.0" + } + } } }, "@opentelemetry/instrumentation-amqplib": { @@ -2789,6 +2939,16 @@ "@opentelemetry/api-metrics": "0.32.0", "@opentelemetry/instrumentation": "0.32.0", "@opentelemetry/semantic-conventions": "1.6.0" + }, + "dependencies": { + "@opentelemetry/api-metrics": { + "version": "0.32.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.32.0.tgz", + "integrity": "sha512-g1WLhpG8B6iuDyZJFRGsR+JKyZ94m5LEmY2f+duEJ9Xb4XRlLHrZvh6G34OH6GJ8iDHxfHb/sWjJ1ZpkI9yGMQ==", + "requires": { + "@opentelemetry/api": "^1.0.0" + } + } } }, "@opentelemetry/instrumentation-hapi": { @@ -3048,16 +3208,6 @@ "@opentelemetry/resources": "1.7.0", "@opentelemetry/sdk-metrics": "0.33.0", "@opentelemetry/sdk-trace-base": "1.7.0" - }, - "dependencies": { - "@opentelemetry/api-metrics": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.33.0.tgz", - "integrity": "sha512-78evfPRRRnJA6uZ3xuBuS3VZlXTO/LRs+Ff1iv3O/7DgibCtq9k27T6Zlj8yRdJDFmcjcbQrvC0/CpDpWHaZYA==", - "requires": { - "@opentelemetry/api": "^1.0.0" - } - } } }, "@opentelemetry/propagation-utils": { @@ -3115,16 +3265,6 @@ "@opentelemetry/core": "1.7.0", "@opentelemetry/resources": "1.7.0", "lodash.merge": "4.6.2" - }, - "dependencies": { - "@opentelemetry/api-metrics": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.33.0.tgz", - "integrity": "sha512-78evfPRRRnJA6uZ3xuBuS3VZlXTO/LRs+Ff1iv3O/7DgibCtq9k27T6Zlj8yRdJDFmcjcbQrvC0/CpDpWHaZYA==", - "requires": { - "@opentelemetry/api": "^1.0.0" - } - } } }, "@opentelemetry/sdk-node": { @@ -3141,14 +3281,6 @@ "@opentelemetry/sdk-trace-node": "1.7.0" }, "dependencies": { - "@opentelemetry/api-metrics": { - "version": "0.33.0", - "resolved": "https://registry.npmjs.org/@opentelemetry/api-metrics/-/api-metrics-0.33.0.tgz", - "integrity": "sha512-78evfPRRRnJA6uZ3xuBuS3VZlXTO/LRs+Ff1iv3O/7DgibCtq9k27T6Zlj8yRdJDFmcjcbQrvC0/CpDpWHaZYA==", - "requires": { - "@opentelemetry/api": "^1.0.0" - } - }, "@opentelemetry/instrumentation": { "version": "0.33.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.33.0.tgz", diff --git a/src/paymentservice/package.json b/src/paymentservice/package.json index e1ca7e5cd9..a74dab2a7d 100644 --- a/src/paymentservice/package.json +++ b/src/paymentservice/package.json @@ -6,7 +6,8 @@ "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", - "lint": "semistandard *.js" + "lint": "semistandard *.js", + "start": "node opentelemetry.js" }, "author": "Jonathan Lui", "license": "ISC", @@ -15,7 +16,11 @@ "@grpc/proto-loader": "^0.7.3", "@opentelemetry/auto-instrumentations-node": "0.33.1", "@opentelemetry/core": "1.7.0", + "@opentelemetry/api": "^1.2.0", + "@opentelemetry/api-metrics": "0.33.0", + "@opentelemetry/sdk-metrics": "0.33.0", "@opentelemetry/exporter-trace-otlp-grpc": "0.33.0", + "@opentelemetry/exporter-metrics-otlp-grpc": "0.33.0", "@opentelemetry/sdk-node": "0.33.0", "grpc-js-health-check": "^1.0.2", "pino": "8.7.0", diff --git a/src/paymentservice/tracing.js b/src/paymentservice/tracing.js deleted file mode 100644 index baac9859c7..0000000000 --- a/src/paymentservice/tracing.js +++ /dev/null @@ -1,10 +0,0 @@ -const opentelemetry = require("@opentelemetry/sdk-node") -const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node") -const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc') - -const sdk = new opentelemetry.NodeSDK({ - traceExporter: new OTLPTraceExporter(), - instrumentations: [getNodeAutoInstrumentations()] -}) - -sdk.start() From 35a68f0f610e61e031b48c4a38519d8c5787b834 Mon Sep 17 00:00:00 2001 From: "marc.pichler" Date: Tue, 15 Nov 2022 15:06:51 +0100 Subject: [PATCH 2/6] add changelog add changelog --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 43d43282d2..7f9d3e4353 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -138,3 +138,5 @@ significant modifications will be credited to OpenTelemetry Authors. ([#569](https://github.com/open-telemetry/opentelemetry-demo/pull/569)) * Optimize GitHub Builds and fix broken emulation of featureflag ([#536](https://github.com/open-telemetry/opentelemetry-demo/pull/536)) +* Add basic metrics support for payment service +([#583](https://github.com/open-telemetry/opentelemetry-demo/pull/583)) From 9a62a6ba690a857ad1117d1fe4e54bfaedbd4560 Mon Sep 17 00:00:00 2001 From: "marc.pichler" Date: Wed, 16 Nov 2022 08:14:49 +0100 Subject: [PATCH 3/6] update docs --- docs/metric_service_features.md | 2 +- docs/services/paymentservice.md | 48 +++++++++++++++++++++++---------- 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/docs/metric_service_features.md b/docs/metric_service_features.md index 464ffb6802..d5660536fa 100644 --- a/docs/metric_service_features.md +++ b/docs/metric_service_features.md @@ -15,7 +15,7 @@ Emoji Legend | Email | Ruby | :construction: | :construction: | :construction: | :construction: | :construction: | :construction: | | Feature Flag | Erlang / Elixir | :construction: | :construction: | :construction: | :construction: | :construction: | :construction: | | Frontend | JavaScript | :construction: | :construction: | :construction: | :construction: | :construction: | :construction: | -| Payment | JavaScript | :construction: | :construction: | :construction: | :construction: | :construction: | :construction: | +| Payment | JavaScript | :construction: | :100: | :construction: | :construction: | :construction: | :construction: | | Product Catalog | Go | :construction: | :construction: | :construction: | :construction: | :construction: | :construction: | | Recommendation | Python | :100: | :100: | :construction: | :construction: | :construction: | :construction: | | Shipping | Rust | :construction: | :construction: | :construction: | :construction: | :construction: | :construction: | diff --git a/docs/services/paymentservice.md b/docs/services/paymentservice.md index 07a2f10e77..bdf223c5ad 100644 --- a/docs/services/paymentservice.md +++ b/docs/services/paymentservice.md @@ -8,33 +8,39 @@ processed. ## Initializing OpenTelemetry -It is recommended to use a Node required module when starting your NodeJS -application to initialize the SDK and auto-instrumentation. When initializing -the OpenTelemetry NodeJS SDK, you optionally specify which auto-instrumentation -libraries to leverage, or make use of the `getNodeAutoInstrumentations()` -function which includes most popular frameworks. The `tracing.js` contains all -code required to initialize the SDK and auto-instrumentation based on standard -OpenTelemetry environment variables for OTLP export, resource attributes, and -service name. +It is recommended to use wrap your app using an OpenTelemetry initialization +wrapper when starting your NodeJS application to initialize the SDK and auto- +instrumentation. When initializing the OpenTelemetry NodeJS SDK, you optionally +specify which auto-instrumentation libraries to leverage, or make use of the +`getNodeAutoInstrumentations()` function which includes most popular frameworks. +The `opentelemetry.js` file contains all code required to initialize the SDK and +auto-instrumentation based on standard OpenTelemetry environment variables for +OTLP export, resource attributes, and service name. It then `require`s your app +to start it up once the SDK is initialized. ```javascript const opentelemetry = require("@opentelemetry/sdk-node") const { getNodeAutoInstrumentations } = require("@opentelemetry/auto-instrumentations-node") -const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc') +const { OTLPTraceExporter } = require('@opentelemetry/exporter-trace-otlp-grpc') +const { OTLPMetricExporter } = require('@opentelemetry/exporter-metrics-otlp-grpc') +const { PeriodicExportingMetricReader } = require('@opentelemetry/sdk-metrics'); const sdk = new opentelemetry.NodeSDK({ traceExporter: new OTLPTraceExporter(), - instrumentations: [ getNodeAutoInstrumentations() ] + instrumentations: [ getNodeAutoInstrumentations() ], + metricReader: new PeriodicExportingMetricReader({ + exporter: new OTLPMetricExporter() + }), }) -sdk.start() +sdk.start().then(() => require("./index")); ``` -Node required modules are loaded using the `--require` command line argument. +You can then use `opentelemetry.js` to start your app. This can be done in the `ENTRYPOINT` command for the service's `Dockerfile`. ```dockerfile -ENTRYPOINT [ "node", "--require", "./tracing.js", "./index.js" ] +ENTRYPOINT [ "node", "./opentelemetry.js" ] ``` ## Traces @@ -72,7 +78,21 @@ be sure to set the span's status accordingly. You can see this in the ## Metrics -TBD +### Creating Meters and Instruments + +Meters can be created using the `@opentelemetry/api-metrics` package. You can +create meters as seen below, and then use the created meter to create +instruments. + +```javascript +const { metrics } = require('@opentelemetry/api-metrics'); + +const meter = metrics.getMeter('paymentservice'); +const transactionsCounter = meter.createCounter('app.payment.transactions') +``` + +Meters and Instruments are supposed to stick around. This means you should +get a Meter or an Instrument once, and then re-use it as needed. ## Logs From bec6b2e9a2505f6800e0b27d61dc0c6bc4f0112c Mon Sep 17 00:00:00 2001 From: "marc.pichler" Date: Wed, 16 Nov 2022 08:24:15 +0100 Subject: [PATCH 4/6] fix typos. --- docs/services/paymentservice.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/services/paymentservice.md b/docs/services/paymentservice.md index bdf223c5ad..bad38fcdc3 100644 --- a/docs/services/paymentservice.md +++ b/docs/services/paymentservice.md @@ -8,15 +8,15 @@ processed. ## Initializing OpenTelemetry -It is recommended to use wrap your app using an OpenTelemetry initialization -wrapper when starting your NodeJS application to initialize the SDK and auto- -instrumentation. When initializing the OpenTelemetry NodeJS SDK, you optionally -specify which auto-instrumentation libraries to leverage, or make use of the +It is recommended to use an OpenTelemetry initialization wrapper when starting +your NodeJS application to initialize the SDK and auto-instrumentation. +When initializing the OpenTelemetry NodeJS SDK, you optionally specify which +auto-instrumentation libraries to leverage, or make use of the `getNodeAutoInstrumentations()` function which includes most popular frameworks. The `opentelemetry.js` file contains all code required to initialize the SDK and auto-instrumentation based on standard OpenTelemetry environment variables for OTLP export, resource attributes, and service name. It then `require`s your app -to start it up once the SDK is initialized. +at `./index.js` to start it up once the SDK is initialized. ```javascript const opentelemetry = require("@opentelemetry/sdk-node") @@ -92,7 +92,7 @@ const transactionsCounter = meter.createCounter('app.payment.transactions') ``` Meters and Instruments are supposed to stick around. This means you should -get a Meter or an Instrument once, and then re-use it as needed. +get a Meter or an Instrument once , and then re-use it as needed, if possible. ## Logs From 86d21d85c43afe0446f1a734743d8459d146782b Mon Sep 17 00:00:00 2001 From: "marc.pichler" Date: Wed, 16 Nov 2022 08:27:34 +0100 Subject: [PATCH 5/6] fix linting errors --- docs/services/paymentservice.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/docs/services/paymentservice.md b/docs/services/paymentservice.md index bad38fcdc3..29d7af6721 100644 --- a/docs/services/paymentservice.md +++ b/docs/services/paymentservice.md @@ -8,10 +8,10 @@ processed. ## Initializing OpenTelemetry -It is recommended to use an OpenTelemetry initialization wrapper when starting -your NodeJS application to initialize the SDK and auto-instrumentation. -When initializing the OpenTelemetry NodeJS SDK, you optionally specify which -auto-instrumentation libraries to leverage, or make use of the +It is recommended to use an OpenTelemetry initialization wrapper when starting +your NodeJS application to initialize the SDK and auto-instrumentation. +When initializing the OpenTelemetry NodeJS SDK, you optionally specify which +auto-instrumentation libraries to leverage, or make use of the `getNodeAutoInstrumentations()` function which includes most popular frameworks. The `opentelemetry.js` file contains all code required to initialize the SDK and auto-instrumentation based on standard OpenTelemetry environment variables for From b626a9c80d23b13a8b99be475e9093e4aa0c749b Mon Sep 17 00:00:00 2001 From: "marc.pichler" Date: Wed, 16 Nov 2022 14:52:43 +0100 Subject: [PATCH 6/6] clarify 'wrapper' approach --- docs/services/paymentservice.md | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/docs/services/paymentservice.md b/docs/services/paymentservice.md index 29d7af6721..5973da6464 100644 --- a/docs/services/paymentservice.md +++ b/docs/services/paymentservice.md @@ -8,15 +8,16 @@ processed. ## Initializing OpenTelemetry -It is recommended to use an OpenTelemetry initialization wrapper when starting -your NodeJS application to initialize the SDK and auto-instrumentation. -When initializing the OpenTelemetry NodeJS SDK, you optionally specify which +It is recommended to `require` Node.js app using an initializer file that +initializes the SDK and auto-instrumentation. When initializing the +OpenTelemetry NodeJS SDK in that module, you optionally specify which auto-instrumentation libraries to leverage, or make use of the `getNodeAutoInstrumentations()` function which includes most popular frameworks. -The `opentelemetry.js` file contains all code required to initialize the SDK and -auto-instrumentation based on standard OpenTelemetry environment variables for -OTLP export, resource attributes, and service name. It then `require`s your app -at `./index.js` to start it up once the SDK is initialized. +The below example of an intiailizer file (`opentelemetry.js`) contains all code +required to initialize the SDK and auto-instrumentation based on standard +OpenTelemetry environment variables for OTLP export, resource attributes, and +service name. It then `require`s your app at `./index.js` to start it up once +the SDK is initialized. ```javascript const opentelemetry = require("@opentelemetry/sdk-node")