Skip to content

Commit b4ed42c

Browse files
Wrap calls to OTEL external tracer in proxy (#1820)
1 parent 318f3bc commit b4ed42c

File tree

17 files changed

+231
-85
lines changed

17 files changed

+231
-85
lines changed

.changeset/four-melons-grin.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@saleor/apps-otel": patch
3+
---
4+
5+
Add `PATH`, `SALEOR_EVENT` & `TENANT_DOMAIN` to observability attributes

.changeset/six-apes-camp.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"saleor-app-avatax": patch
3+
---
4+
5+
Added wrapper for external OTEL tracer. Wrapper is responsible for enhanced error serialization, custom attribute injection & proper span lifecycle management.

.changeset/tender-cars-count.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@saleor/apps-logger": patch
3+
---
4+
5+
Added new methods on `LoggerContext` responsible for getting tenant domain & Saleor api url.

apps/avatax/eslint.config.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,19 @@ export default [
1212
},
1313
rules: {
1414
"n/no-process-env": "error",
15+
"@typescript-eslint/no-restricted-imports": [
16+
"error",
17+
{
18+
paths: [
19+
{
20+
name: "@opentelemetry/api",
21+
importNames: ["trace"],
22+
message:
23+
"Importing trace from @opentelemetry/api is not allowed. Use `@lib/tracing` module instead.",
24+
},
25+
],
26+
},
27+
],
1528
},
1629
},
1730
{

apps/avatax/src/app/api/webhooks/checkout-calculate-taxes/route.ts

Lines changed: 3 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@ import { captureException, setTag } from "@sentry/nextjs";
77

88
import { AppConfigExtractor } from "@/lib/app-config-extractor";
99
import { AppConfigurationLogger } from "@/lib/app-configuration-logger";
10-
import { appInternalTracer } from "@/lib/app-internal-tracer";
1110
import { metadataCache, wrapWithMetadataCache } from "@/lib/app-metadata-cache";
1211
import { SubscriptionPayloadErrorChecker } from "@/lib/error-utils";
12+
import { appExternalTracer } from "@/lib/tracing";
1313
import { createLogger } from "@/logger";
1414
import { loggerContext, withLoggerContext } from "@/logger-context";
1515
import { AvataxCalculateTaxesPayloadLinesTransformer } from "@/modules/avatax/calculate-taxes/avatax-calculate-taxes-payload-lines-transformer";
@@ -26,7 +26,7 @@ const checkoutCalculateTaxesSyncWebhookReponse =
2626
buildSyncWebhookResponsePayload<"CHECKOUT_CALCULATE_TAXES">;
2727

2828
const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) => {
29-
return appInternalTracer.startActiveSpan(
29+
return appExternalTracer.startActiveSpan(
3030
"executing checkoutCalculateTaxes webhook handler",
3131
{
3232
kind: SpanKind.SERVER,
@@ -54,8 +54,6 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
5454
try {
5555
const { payload, authData } = ctx;
5656

57-
span.setAttribute(ObservabilityAttributes.SALEOR_API_URL, authData.saleorApiUrl);
58-
5957
subscriptionErrorChecker.checkPayload(payload);
6058

6159
loggerContext.set(ObservabilityAttributes.CHANNEL_SLUG, ctx.payload.taxBase.channel.slug);
@@ -64,7 +62,6 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
6462
if (payload.version) {
6563
setTag(ObservabilityAttributes.SALEOR_VERSION, payload.version);
6664
loggerContext.set(ObservabilityAttributes.SALEOR_VERSION, payload.version);
67-
span.setAttribute(ObservabilityAttributes.SALEOR_VERSION, payload.version);
6865
}
6966

7067
logger.info("Handler for CHECKOUT_CALCULATE_TAXES webhook called");
@@ -105,7 +102,6 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
105102
code: SpanStatusCode.ERROR,
106103
message: "App configuration is broken",
107104
});
108-
span.end();
109105

110106
return Response.json(
111107
{
@@ -122,7 +118,6 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
122118
code: SpanStatusCode.OK,
123119
message: "Taxes calculated successfully",
124120
});
125-
span.end();
126121

127122
return Response.json(checkoutCalculateTaxesSyncWebhookReponse(value), {
128123
status: 200,
@@ -138,7 +133,6 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
138133
code: SpanStatusCode.ERROR,
139134
message: "Failed to calculate taxes: error from AvaTax API",
140135
});
141-
span.end();
142136

143137
return Response.json(
144138
{
@@ -153,7 +147,6 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
153147
code: SpanStatusCode.ERROR,
154148
message: "Failed to calculate taxes: invalid configuration",
155149
});
156-
span.end();
157150

158151
return Response.json(
159152
{
@@ -166,9 +159,8 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
166159
case CalculateTaxesUseCase.ExpectedIncompletePayloadError: {
167160
span.setStatus({
168161
code: SpanStatusCode.ERROR,
169-
message: "Failed to calucalted taxes: incomplete payload",
162+
message: "Failed to calculate taxes: incomplete payload",
170163
});
171-
span.end();
172164

173165
return Response.json(
174166
{
@@ -186,7 +178,6 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
186178
code: SpanStatusCode.ERROR,
187179
message: "Failed to calculate taxes: unhandled error",
188180
});
189-
span.end();
190181

191182
return Response.json(
192183
{
@@ -212,7 +203,6 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
212203
code: SpanStatusCode.ERROR,
213204
message: "Failed to calculate taxes: error from AvaTax API",
214205
});
215-
span.end();
216206

217207
return Response.json(
218208
{
@@ -228,7 +218,6 @@ const handler = checkoutCalculateTaxesSyncWebhook.createHandler(async (_req, ctx
228218
code: SpanStatusCode.ERROR,
229219
message: "Failed to calculate taxes: unhandled error",
230220
});
231-
span.end();
232221

233222
return Response.json({ message: "Unhandled error" }, { status: 500 });
234223
}

apps/avatax/src/app/api/webhooks/order-calculate-taxes/route.ts

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import { captureException, setTag } from "@sentry/nextjs";
88

99
import { AppConfigExtractor } from "@/lib/app-config-extractor";
1010
import { AppConfigurationLogger } from "@/lib/app-configuration-logger";
11-
import { appInternalTracer } from "@/lib/app-internal-tracer";
1211
import { metadataCache, wrapWithMetadataCache } from "@/lib/app-metadata-cache";
1312
import { SubscriptionPayloadErrorChecker } from "@/lib/error-utils";
13+
import { appExternalTracer } from "@/lib/tracing";
1414
import { createLogger } from "@/logger";
1515
import { loggerContext, withLoggerContext } from "@/logger-context";
1616
import { AvataxClient } from "@/modules/avatax/avatax-client";
@@ -101,7 +101,7 @@ async function calculateTaxes({
101101
}
102102

103103
const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) => {
104-
return appInternalTracer.startActiveSpan(
104+
return appExternalTracer.startActiveSpan(
105105
"executing orderCalculateTaxes webhook handler",
106106
{
107107
kind: SpanKind.SERVER,
@@ -114,11 +114,9 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
114114
const appMetadata = ctx.payload.recipient?.privateMetadata ?? [];
115115

116116
metadataCache.setMetadata(appMetadata);
117-
const { payload, authData } = ctx;
117+
const { payload } = ctx;
118118

119119
try {
120-
span.setAttribute(ObservabilityAttributes.SALEOR_API_URL, authData.saleorApiUrl);
121-
122120
subscriptionErrorChecker.checkPayload(payload);
123121

124122
loggerContext.set("channelSlug", channelSlug);
@@ -127,7 +125,6 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
127125
if (payload.version) {
128126
setTag(ObservabilityAttributes.SALEOR_VERSION, payload.version);
129127
loggerContext.set(ObservabilityAttributes.SALEOR_VERSION, payload.version);
130-
span.setAttribute(ObservabilityAttributes.SALEOR_VERSION, payload.version);
131128
}
132129

133130
logger.info("Handler for ORDER_CALCULATE_TAXES webhook called");
@@ -151,9 +148,8 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
151148
span.recordException(payloadVerificationResult.error);
152149
span.setStatus({
153150
code: SpanStatusCode.ERROR,
154-
message: "Failed to calucalted taxes due to incomplete payload",
151+
message: "Failed to calculate taxes due to incomplete payload",
155152
});
156-
span.end();
157153

158154
return Response.json(
159155
{
@@ -205,7 +201,6 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
205201
code: SpanStatusCode.ERROR,
206202
message: "Failed to calculate taxes: invalid configuration",
207203
});
208-
span.end();
209204

210205
return Response.json(
211206
{
@@ -232,7 +227,6 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
232227
code: SpanStatusCode.ERROR,
233228
message: "Failed to calculate taxes: invalid configuration",
234229
});
235-
span.end();
236230

237231
return Response.json(
238232
{
@@ -264,7 +258,6 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
264258
code: SpanStatusCode.OK,
265259
message: "Taxes calculated successfully",
266260
});
267-
span.end();
268261

269262
return Response.json(orderCalculateTaxesSyncWebhookReponse(calculatedTaxes), {
270263
status: 200,
@@ -293,7 +286,6 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
293286
code: SpanStatusCode.ERROR,
294287
message: "Failed to calculate taxes: error from AvaTax API",
295288
});
296-
span.end();
297289

298290
return Response.json(
299291
{
@@ -323,7 +315,6 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
323315
code: SpanStatusCode.ERROR,
324316
message: "Failed to calculate taxes: error from AvaTax API",
325317
});
326-
span.end();
327318

328319
return Response.json(
329320
{
@@ -354,7 +345,6 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
354345
code: SpanStatusCode.ERROR,
355346
message: "Failed to calculate taxes: error from AvaTax API",
356347
});
357-
span.end();
358348

359349
return Response.json(
360350
{
@@ -383,7 +373,6 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
383373
code: SpanStatusCode.ERROR,
384374
message: "Failed to calculate taxes: error from AvaTax API",
385375
});
386-
span.end();
387376

388377
return Response.json(
389378
{
@@ -408,7 +397,6 @@ const handler = orderCalculateTaxesSyncWebhook.createHandler(async (_req, ctx) =
408397
code: SpanStatusCode.ERROR,
409398
message: "Failed to calculate taxes: unhandled error",
410399
});
411-
span.end();
412400

413401
return Response.json({ message: "Unhandled error" }, { status: 500 });
414402
}

apps/avatax/src/app/api/webhooks/order-cancelled/route.ts

Lines changed: 3 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,9 @@ import { captureException, setTag } from "@sentry/nextjs";
66

77
import { AppConfigExtractor } from "@/lib/app-config-extractor";
88
import { AppConfigurationLogger } from "@/lib/app-configuration-logger";
9-
import { appInternalTracer } from "@/lib/app-internal-tracer";
109
import { metadataCache, wrapWithMetadataCache } from "@/lib/app-metadata-cache";
1110
import { SubscriptionPayloadErrorChecker } from "@/lib/error-utils";
11+
import { appExternalTracer } from "@/lib/tracing";
1212
import { createLogger } from "@/logger";
1313
import { loggerContext, withLoggerContext } from "@/logger-context";
1414
import { AvataxOrderCancelledAdapter } from "@/modules/avatax/order-cancelled/avatax-order-cancelled-adapter";
@@ -30,15 +30,13 @@ const subscriptionErrorChecker = new SubscriptionPayloadErrorChecker(logger, cap
3030
const logsWriterFactory = new LogWriterFactory();
3131

3232
const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
33-
return appInternalTracer.startActiveSpan(
33+
return appExternalTracer.startActiveSpan(
3434
"executing orderCancelled webhook handler",
3535
{
3636
kind: SpanKind.SERVER,
3737
},
3838
async (span) => {
39-
const { payload, authData } = ctx;
40-
41-
span.setAttribute(ObservabilityAttributes.SALEOR_API_URL, authData.saleorApiUrl);
39+
const { payload } = ctx;
4240

4341
const logWriter = logsWriterFactory.createWriter(ctx.authData);
4442

@@ -49,7 +47,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
4947
if (payload.version) {
5048
setTag(ObservabilityAttributes.SALEOR_VERSION, payload.version);
5149
loggerContext.set(ObservabilityAttributes.SALEOR_VERSION, payload.version);
52-
span.setAttribute(ObservabilityAttributes.SALEOR_VERSION, payload.version);
5350
}
5451

5552
logger.info("Handler called with payload");
@@ -77,7 +74,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
7774
code: SpanStatusCode.ERROR,
7875
message: "Failed to void AvaTax transaction: missing order data from Saleor",
7976
});
80-
span.end();
8177

8278
return Response.json(
8379
{ message: `Invalid order payload for order: ${payload.order?.id}` },
@@ -103,7 +99,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
10399
message:
104100
"Failed to void AvaTax transaction: missing avataxId field in order metadata",
105101
});
106-
span.end();
107102

108103
return Response.json(
109104
{ message: "Invalid order payload. Likely not an AvaTax order." },
@@ -127,7 +122,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
127122
code: SpanStatusCode.ERROR,
128123
message: "Failed to void AvaTax transaction: error parsing Saleor event payload",
129124
});
130-
span.end();
131125

132126
return Response.json(
133127
{ message: `Invalid order payload for order: ${payload.order?.id}` },
@@ -152,7 +146,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
152146
code: SpanStatusCode.ERROR,
153147
message: "Failed to void AvaTax transaction: unhandled error",
154148
});
155-
span.end();
156149

157150
return Response.json(
158151
{ message: `Unhandled error for order: ${payload.order?.id}` },
@@ -206,7 +199,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
206199
code: SpanStatusCode.ERROR,
207200
message: "Failed to void AvaTax transaction: invalid configuration",
208201
});
209-
span.end();
210202

211203
return Response.json(
212204
{ message: `App configuration is broken for order: ${payload.order?.id}` },
@@ -233,7 +225,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
233225
code: SpanStatusCode.ERROR,
234226
message: "Failed to void AvaTax transaction: invalid configuration",
235227
});
236-
span.end();
237228

238229
return Response.json(
239230
{ message: `App is not configured properly for order: ${payload.order?.id}` },
@@ -272,7 +263,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
272263
code: SpanStatusCode.ERROR,
273264
message: "AvaTax transaction was not found in AvaTax",
274265
});
275-
span.end();
276266

277267
return Response.json(
278268
{ message: "AvaTax responded with DocumentNotFound. Please consult AvaTax docs" },
@@ -298,7 +288,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
298288
code: SpanStatusCode.OK,
299289
message: "AvaTax transaction was already cancelled in AvaTax",
300290
});
301-
span.end();
302291

303292
return Response.json(
304293
{ message: "Order was already cancelled in AvaTax" },
@@ -340,7 +329,6 @@ const handler = orderCancelledAsyncWebhook.createHandler(async (_req, ctx) => {
340329
code: SpanStatusCode.OK,
341330
message: "Succesfully voided order in AvaTax",
342331
});
343-
span.end();
344332

345333
return Response.json({ message: "Success" }, { status: 200 });
346334
},

0 commit comments

Comments
 (0)