Skip to content

Commit

Permalink
Variable paymentservice error rate and introduce loyalty level attrib…
Browse files Browse the repository at this point in the history
…utes (open-telemetry#1815)

* 75% error by version number included tenant.level as span attribute

* Include service.name in logs and change level to from numeric to text

* Updated to reflect changes to paymentservice

* Added pull request

* Added variants for % failure

* Change to loyalty_level and service.version

* Change to use app.variant

* Updated log entry

* Revert changes as deployment YAML is generated after Helm release

* Remove app.variant and tidy code for app.loyalty.level

* Fixed markdown linting

* Typo correction

* Add gold back into array and also include loyalty_level in success log

---------

Co-authored-by: Juliano Costa <[email protected]>
Co-authored-by: Pierre Tessier <[email protected]>
  • Loading branch information
3 people authored Dec 12, 2024
1 parent e54439d commit 1f30247
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 18 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ the release.

## Unreleased

* [flagd] Update `paymentServiceFailure` to use a list of variants.
* [paymentservice] Add loyalty level attributes to spans.
Added `service.name` to logs.
([#1815](https://github.com/open-telemetry/opentelemetry-demo/pull/1815))
* [grafana] Update grafana to 11.3.0
([#1764](https://github.com/open-telemetry/opentelemetry-demo/pull/1764))
* [chore] Move build args to .env file
Expand Down
11 changes: 8 additions & 3 deletions src/flagd/demo.flagd.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,16 @@
"defaultVariant": "off"
},
"paymentServiceFailure": {
"description": "Fail payment service charge requests",
"description": "Fail payment service charge requests n%",
"state": "ENABLED",
"variants": {
"on": true,
"off": false
"100%": 1.00,
"90%": 0.95,
"75%": 0.75,
"50%": 0.50,
"25%": 0.25,
"10%": 0.10,
"off": 0.00
},
"defaultVariant": "off"
},
Expand Down
46 changes: 33 additions & 13 deletions src/paymentservice/charge.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,41 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0
const {context, propagation, trace, metrics} = require('@opentelemetry/api');
const { context, propagation, trace, metrics } = require('@opentelemetry/api');
const cardValidator = require('simple-card-validator');
const { v4: uuidv4 } = require('uuid');

const { OpenFeature } = require('@openfeature/server-sdk');
const { FlagdProvider} = require('@openfeature/flagd-provider');
const { FlagdProvider } = require('@openfeature/flagd-provider');
const flagProvider = new FlagdProvider();

const logger = require('./logger');
const tracer = trace.getTracer('paymentservice');
const meter = metrics.getMeter('paymentservice');
const transactionsCounter = meter.createCounter('app.payment.transactions')
const transactionsCounter = meter.createCounter('app.payment.transactions');

const LOYALTY_LEVEL = ['platinum', 'gold', 'silver', 'bronze'];

/** Return random element from given array */
function random(arr) {
const index = Math.floor(Math.random() * arr.length);
return arr[index];
}

module.exports.charge = async request => {
const span = tracer.startSpan('charge');

await OpenFeature.setProviderAndWait(flagProvider);
if (await OpenFeature.getClient().getBooleanValue("paymentServiceFailure", false)) {
throw new Error("PaymentService Fail Feature Flag Enabled");

const numberVariant = await OpenFeature.getClient().getNumberValue("paymentServiceFailure", 0);

if (numberVariant > 0) {
// n% chance to fail with app.loyalty.level=gold
if (Math.random() < numberVariant) {
span.setAttributes({'app.loyalty.level': 'gold' });
span.end();

throw new Error('Payment request failed. Invalid token. app.loyalty.level=gold');
}
}

const {
Expand All @@ -34,9 +51,12 @@ module.exports.charge = async request => {
const card = cardValidator(number);
const { card_type: cardType, valid } = card.getCardDetails();

const loyalty_level = random(LOYALTY_LEVEL);

span.setAttributes({
'app.payment.card_type': cardType,
'app.payment.card_valid': valid
'app.payment.card_valid': valid,
'app.loyalty.level': loyalty_level
});

if (!valid) {
Expand All @@ -51,18 +71,18 @@ module.exports.charge = async request => {
throw new Error(`The credit card (ending ${lastFourDigits}) expired on ${month}/${year}.`);
}

// check baggage for synthetic_request=true, and add charged attribute accordingly
// 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);
}

const { units, nanos, currencyCode } = request.amount;
logger.info({ transactionId, cardType, lastFourDigits, amount: { units, nanos, currencyCode }, loyalty_level }, 'Transaction complete.');
transactionsCounter.add(1, { 'app.payment.currency': currencyCode });
span.end();

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 }
}
return { transactionId };
};
17 changes: 15 additions & 2 deletions src/paymentservice/logger.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

const pino = require('pino');
const pino = require('pino')

module.exports = pino();
const logger = pino({
mixin() {
return {
'service.name': process.env['OTEL_SERVICE_NAME'],
}
},
formatters: {
level: (label) => {
return { 'level': label };
},
},
});

module.exports = logger;

0 comments on commit 1f30247

Please sign in to comment.