diff --git a/src/paymentservice/charge.js b/src/paymentservice/charge.js index 2e1fa40c50..bf5ef5bd7c 100644 --- a/src/paymentservice/charge.js +++ b/src/paymentservice/charge.js @@ -15,6 +15,8 @@ const cardValidator = require('simple-card-validator'); const { v4: uuidv4 } = require('uuid'); const pino = require('pino'); +const opentelemetry = require('@opentelemetry/api'); +const tracer = opentelemetry.trace.getTracer("paymentservice"); const logger = pino({ name: 'paymentservice-charge', @@ -56,6 +58,9 @@ class ExpiredCreditCard extends CreditCardError { * @return transaction_id - a random uuid v4. */ module.exports = function charge (request) { + // create and start span + const span = tracer.startSpan("charge") + const { amount, credit_card: creditCard } = request; const cardNumber = creditCard.credit_card_number; const cardInfo = cardValidator(cardNumber); @@ -63,6 +68,10 @@ module.exports = function charge (request) { card_type: cardType, valid } = cardInfo.getCardDetails(); + span.setAttributes({ + "app.payment.charge.cardType": cardType, + "app.payment.charge.valid": valid + }) if (!valid) { throw new InvalidCreditCard(); } @@ -79,5 +88,9 @@ module.exports = function charge (request) { logger.info(`Transaction processed: ${cardType} ending ${cardNumber.substr(-4)} \ Amount: ${amount.currency_code}${amount.units}.${amount.nanos}`); + span.setAttribute("app.payment.charged", true); + // a manually created span needs to be ended + span.end(); + return { transaction_id: uuidv4() }; }; diff --git a/src/paymentservice/server.js b/src/paymentservice/server.js index 7e695e2d04..406022c874 100644 --- a/src/paymentservice/server.js +++ b/src/paymentservice/server.js @@ -16,6 +16,7 @@ const path = require('path'); const grpc = require('@grpc/grpc-js'); const pino = require('pino'); const protoLoader = require('@grpc/proto-loader'); +const opentelemetry = require('@opentelemetry/api'); const charge = require('./charge'); @@ -45,11 +46,23 @@ class HipsterShopServer { * @param {*} callback fn(err, ChargeResponse) */ static ChargeServiceHandler(call, callback) { + // get the current auto-instrumented span in context + const span = opentelemetry.trace.getSpan(opentelemetry.context.active()) try { + const amount = call.request.amount; + span.setAttributes({ + "app.payment.currency": amount.currency_code, + "app.payment.cost": parseFloat(amount.units + "." + amount.nanos) + }); logger.info(`PaymentService#Charge invoked with request ${JSON.stringify(call.request)}`); + const response = charge(call.request); callback(null, response); + } catch (err) { + // record exception in span (will create a span event) + span.recordException(err); + span.setStatus({code: opentelemetry.SpanStatusCode.ERROR}) console.warn(err); callback(err); }