Skip to content

Commit 1f30247

Browse files
rcastleyjulianocosta89puckpuck
authored
Variable paymentservice error rate and introduce loyalty level attributes (#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]>
1 parent e54439d commit 1f30247

File tree

4 files changed

+60
-18
lines changed

4 files changed

+60
-18
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ the release.
77

88
## Unreleased
99

10+
* [flagd] Update `paymentServiceFailure` to use a list of variants.
11+
* [paymentservice] Add loyalty level attributes to spans.
12+
Added `service.name` to logs.
13+
([#1815](https://github.com/open-telemetry/opentelemetry-demo/pull/1815))
1014
* [grafana] Update grafana to 11.3.0
1115
([#1764](https://github.com/open-telemetry/opentelemetry-demo/pull/1764))
1216
* [chore] Move build args to .env file

src/flagd/demo.flagd.json

+8-3
Original file line numberDiff line numberDiff line change
@@ -65,11 +65,16 @@
6565
"defaultVariant": "off"
6666
},
6767
"paymentServiceFailure": {
68-
"description": "Fail payment service charge requests",
68+
"description": "Fail payment service charge requests n%",
6969
"state": "ENABLED",
7070
"variants": {
71-
"on": true,
72-
"off": false
71+
"100%": 1.00,
72+
"90%": 0.95,
73+
"75%": 0.75,
74+
"50%": 0.50,
75+
"25%": 0.25,
76+
"10%": 0.10,
77+
"off": 0.00
7378
},
7479
"defaultVariant": "off"
7580
},

src/paymentservice/charge.js

+33-13
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,41 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
3-
const {context, propagation, trace, metrics} = require('@opentelemetry/api');
3+
const { context, propagation, trace, metrics } = require('@opentelemetry/api');
44
const cardValidator = require('simple-card-validator');
55
const { v4: uuidv4 } = require('uuid');
66

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

1111
const logger = require('./logger');
1212
const tracer = trace.getTracer('paymentservice');
1313
const meter = metrics.getMeter('paymentservice');
14-
const transactionsCounter = meter.createCounter('app.payment.transactions')
14+
const transactionsCounter = meter.createCounter('app.payment.transactions');
15+
16+
const LOYALTY_LEVEL = ['platinum', 'gold', 'silver', 'bronze'];
17+
18+
/** Return random element from given array */
19+
function random(arr) {
20+
const index = Math.floor(Math.random() * arr.length);
21+
return arr[index];
22+
}
1523

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

1927
await OpenFeature.setProviderAndWait(flagProvider);
20-
if (await OpenFeature.getClient().getBooleanValue("paymentServiceFailure", false)) {
21-
throw new Error("PaymentService Fail Feature Flag Enabled");
28+
29+
const numberVariant = await OpenFeature.getClient().getNumberValue("paymentServiceFailure", 0);
30+
31+
if (numberVariant > 0) {
32+
// n% chance to fail with app.loyalty.level=gold
33+
if (Math.random() < numberVariant) {
34+
span.setAttributes({'app.loyalty.level': 'gold' });
35+
span.end();
36+
37+
throw new Error('Payment request failed. Invalid token. app.loyalty.level=gold');
38+
}
2239
}
2340

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

54+
const loyalty_level = random(LOYALTY_LEVEL);
55+
3756
span.setAttributes({
3857
'app.payment.card_type': cardType,
39-
'app.payment.card_valid': valid
58+
'app.payment.card_valid': valid,
59+
'app.loyalty.level': loyalty_level
4060
});
4161

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

54-
// check baggage for synthetic_request=true, and add charged attribute accordingly
74+
// Check baggage for synthetic_request=true, and add charged attribute accordingly
5575
const baggage = propagation.getBaggage(context.active());
56-
if (baggage && baggage.getEntry("synthetic_request") && baggage.getEntry("synthetic_request").value === "true") {
76+
if (baggage && baggage.getEntry('synthetic_request') && baggage.getEntry('synthetic_request').value === 'true') {
5777
span.setAttribute('app.payment.charged', false);
5878
} else {
5979
span.setAttribute('app.payment.charged', true);
6080
}
6181

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

64-
const { units, nanos, currencyCode } = request.amount;
65-
logger.info({transactionId, cardType, lastFourDigits, amount: { units, nanos, currencyCode }}, "Transaction complete.");
66-
transactionsCounter.add(1, {"app.payment.currency": currencyCode})
67-
return { transactionId }
68-
}
87+
return { transactionId };
88+
};

src/paymentservice/logger.js

+15-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
// Copyright The OpenTelemetry Authors
22
// SPDX-License-Identifier: Apache-2.0
33

4-
const pino = require('pino');
4+
const pino = require('pino')
55

6-
module.exports = pino();
6+
const logger = pino({
7+
mixin() {
8+
return {
9+
'service.name': process.env['OTEL_SERVICE_NAME'],
10+
}
11+
},
12+
formatters: {
13+
level: (label) => {
14+
return { 'level': label };
15+
},
16+
},
17+
});
18+
19+
module.exports = logger;

0 commit comments

Comments
 (0)