From 316cd35ec2799f34552ba5ae323ee8cc580dc3f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20=C5=BBuraw?= <9116238+krzysztofzuraw@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:09:43 +0100 Subject: [PATCH 1/2] Add logs --- .../configuration/configuration.router.ts | 6 ++-- ...eate-segment-client-for-webhook-context.ts | 4 +-- .../trpc/protected-client-procedure.ts | 18 ++++------ .../src/pages/api/webhooks/order-cancelled.ts | 32 +++++++++++++----- .../src/pages/api/webhooks/order-created.ts | 33 ++++++++++++++----- .../pages/api/webhooks/order-fully-paid.ts | 33 ++++++++++++++----- .../src/pages/api/webhooks/order-refunded.ts | 31 ++++++++++++----- .../src/pages/api/webhooks/order-updated.ts | 31 ++++++++++++----- 8 files changed, 130 insertions(+), 58 deletions(-) diff --git a/apps/segment/src/modules/configuration/configuration.router.ts b/apps/segment/src/modules/configuration/configuration.router.ts index 7cec857ef..4f440c554 100644 --- a/apps/segment/src/modules/configuration/configuration.router.ts +++ b/apps/segment/src/modules/configuration/configuration.router.ts @@ -18,13 +18,11 @@ export const configurationRouter = router({ const config = await manager.get(); - logger.info("Fetched config"); + logger.debug("Successfully fetched config"); return config.getConfig(); }), setConfig: protectedClientProcedure.input(z.string().min(1)).mutation(async ({ input, ctx }) => { - logger.info("Request to set config"); - const manager = AppConfigMetadataManager.createFromAuthData({ appId: ctx.appId, saleorApiUrl: ctx.saleorApiUrl, @@ -37,6 +35,6 @@ export const configurationRouter = router({ await manager.set(config); - logger.info("Config set successfully"); + logger.debug("Successfully set config"); }), }); diff --git a/apps/segment/src/modules/create-segment-client-for-webhook-context.ts b/apps/segment/src/modules/create-segment-client-for-webhook-context.ts index 600eb5528..1fb3a793d 100644 --- a/apps/segment/src/modules/create-segment-client-for-webhook-context.ts +++ b/apps/segment/src/modules/create-segment-client-for-webhook-context.ts @@ -6,7 +6,7 @@ import { AppConfigMetadataManager } from "./configuration/app-config-metadata-ma import { SegmentClient } from "./segment/segment.client"; import { SegmentEventsTracker } from "./tracking-events/segment-events-tracker"; -export const SegmentNotConfiguredError = BaseError.subclass("SegmentNotConfiguredError"); +export const SegmentWriteKeyNotFoundError = BaseError.subclass("SegmentNotConfiguredError"); export const createSegmentClientForWebhookContext = async (context: { authData: AuthData }) => { const config = await AppConfigMetadataManager.createFromAuthData(context.authData).get(); @@ -14,7 +14,7 @@ export const createSegmentClientForWebhookContext = async (context: { authData: const segmentKey = config.getConfig()?.segmentWriteKey; if (!segmentKey) { - throw new SegmentNotConfiguredError("Segment write key not found in app config"); + throw new SegmentWriteKeyNotFoundError("Segment write key not found in app config"); } return new SegmentEventsTracker( diff --git a/apps/segment/src/modules/trpc/protected-client-procedure.ts b/apps/segment/src/modules/trpc/protected-client-procedure.ts index f99921654..2e69a683e 100644 --- a/apps/segment/src/modules/trpc/protected-client-procedure.ts +++ b/apps/segment/src/modules/trpc/protected-client-procedure.ts @@ -11,11 +11,9 @@ import { middleware, procedure } from "./trpc-server"; const REQUIRED_SALEOR_PERMISSIONS: Permission[] = ["MANAGE_APPS"]; -const logger = createLogger("ProtectedClientProcedure"); +const logger = createLogger("protectedClientProcedure"); const attachAppToken = middleware(async ({ ctx, next }) => { - logger.debug("attachAppToken middleware"); - if (!ctx.saleorApiUrl) { logger.debug("ctx.saleorApiUrl not found, throwing"); @@ -46,12 +44,9 @@ const attachAppToken = middleware(async ({ ctx, next }) => { }); const validateClientToken = middleware(async ({ ctx, next, meta }) => { - logger.debug( - { - permissions: meta?.requiredClientPermissions, - }, - "Calling validateClientToken middleware with permissions required", - ); + logger.debug("Calling validateClientToken middleware with permissions required", { + permissions: meta?.requiredClientPermissions, + }); if (!ctx.token) { throw new TRPCError({ @@ -77,8 +72,9 @@ const validateClientToken = middleware(async ({ ctx, next, meta }) => { if (!ctx.ssr) { try { - logger.debug("trying to verify JWT token from frontend"); - logger.debug({ token: ctx.token ? `${ctx.token[0]}...` : undefined }); + logger.debug("trying to verify JWT token from frontend", { + token: ctx.token ? `${ctx.token[0]}...` : undefined, + }); await verifyJWT({ appId: ctx.appId, diff --git a/apps/segment/src/pages/api/webhooks/order-cancelled.ts b/apps/segment/src/pages/api/webhooks/order-cancelled.ts index 979b79323..5addbae04 100644 --- a/apps/segment/src/pages/api/webhooks/order-cancelled.ts +++ b/apps/segment/src/pages/api/webhooks/order-cancelled.ts @@ -1,12 +1,13 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderUpdatedSubscriptionPayloadFragment } from "@/generated/graphql"; import { createLogger } from "@/logger"; import { loggerContext } from "@/logger-context"; import { createSegmentClientForWebhookContext, - SegmentNotConfiguredError, + SegmentWriteKeyNotFoundError, } from "@/modules/create-segment-client-for-webhook-context"; import { trackingEventFactory } from "@/modules/tracking-events/tracking-events"; import { orderCancelledAsyncWebhook } from "@/modules/webhooks/definitions/order-cancelled"; @@ -27,27 +28,42 @@ const handler: NextWebhookApiHandler = const { authData, payload } = context; if (!payload.order) { - return res.status(200).end(); + logger.info("Payload does not contain order data. Skipping."); + return res + .status(200) + .json({ message: "Payload does not contain order data. It will be skipped by app" }); } + loggerContext.set(ObservabilityAttributes.ORDER_ID, payload.order.id); + try { const segmentEventTracker = await createSegmentClientForWebhookContext({ authData }); - logger.info("Sending order cancelled event to Segment"); - await segmentEventTracker.trackEvent( trackingEventFactory.createOrderCancelledEvent(payload.order), ); - return res.status(200).end(); + logger.info("Order cancelled event successfully sent to Segment"); + + return res.status(200).json({ message: "Order cancelled event successfully sent to Segment" }); } catch (e) { - if (e instanceof SegmentNotConfiguredError) { + if (e instanceof SegmentWriteKeyNotFoundError) { // todo disable webhooks if not configured - return res.status(200).end(); + logger.warn( + "Segment write key is not set in app configuration. Contact client to fix the issue.", + ); + + return res.status(200).json({ + message: "Segment write key is not set in app configuration. Cannot send event to Segment.", + }); } - return res.status(500).end(); + logger.error("Error while sending order cancelled event to Segment", { error: e }); + + return res + .status(500) + .json({ message: "Error while sending order cancelled event to Segment" }); } }; diff --git a/apps/segment/src/pages/api/webhooks/order-created.ts b/apps/segment/src/pages/api/webhooks/order-created.ts index 1ed641f37..1d44e0558 100644 --- a/apps/segment/src/pages/api/webhooks/order-created.ts +++ b/apps/segment/src/pages/api/webhooks/order-created.ts @@ -1,12 +1,13 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderCreatedSubscriptionPayloadFragment } from "@/generated/graphql"; import { createLogger } from "@/logger"; import { loggerContext } from "@/logger-context"; import { createSegmentClientForWebhookContext, - SegmentNotConfiguredError, + SegmentWriteKeyNotFoundError, } from "@/modules/create-segment-client-for-webhook-context"; import { trackingEventFactory } from "@/modules/tracking-events/tracking-events"; import { orderCreatedAsyncWebhook } from "@/modules/webhooks/definitions/order-created"; @@ -17,7 +18,7 @@ export const config = { }, }; -const logger = createLogger("orderCreatedSyncWebhook"); +const logger = createLogger("orderCreatedAsyncWebhook"); const handler: NextWebhookApiHandler = async ( req, @@ -27,27 +28,41 @@ const handler: NextWebhookApiHandler = const { authData, payload } = context; if (!payload.order) { - return res.status(200).end(); + logger.info("Payload does not contain order data. Skipping."); + + return res + .status(200) + .json({ message: "Payload does not contain order data. It will be skipped by app" }); } + loggerContext.set(ObservabilityAttributes.ORDER_ID, payload.order.id); + try { const segmentEventTracker = await createSegmentClientForWebhookContext({ authData }); - logger.info("Sending order created event to Segment"); - await segmentEventTracker.trackEvent( trackingEventFactory.createOrderCreatedEvent(payload.order), ); - return res.status(200).end(); + logger.info("Order created event successfully sent to Segment"); + + return res.status(200).json({ message: "Order cancelled event successfully sent to Segment" }); } catch (e) { - if (e instanceof SegmentNotConfiguredError) { + if (e instanceof SegmentWriteKeyNotFoundError) { // todo disable webhooks if not configured - return res.status(200).end(); + logger.warn( + "Segment write key is not set in app configuration. Contact client to fix the issue.", + ); + + return res.status(200).json({ + message: "Segment write key is not set in app configuration. Cannot send event to Segment.", + }); } - return res.status(500).end(); + logger.error("Error while sending order created event to Segment", { error: e }); + + return res.status(500).json({ message: "Error while sending order created event to Segment" }); } }; diff --git a/apps/segment/src/pages/api/webhooks/order-fully-paid.ts b/apps/segment/src/pages/api/webhooks/order-fully-paid.ts index 3a0d22286..6bae0bb4d 100644 --- a/apps/segment/src/pages/api/webhooks/order-fully-paid.ts +++ b/apps/segment/src/pages/api/webhooks/order-fully-paid.ts @@ -1,12 +1,13 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderFullyPaidSubscriptionPayloadFragment } from "@/generated/graphql"; import { createLogger } from "@/logger"; import { loggerContext } from "@/logger-context"; import { createSegmentClientForWebhookContext, - SegmentNotConfiguredError, + SegmentWriteKeyNotFoundError, } from "@/modules/create-segment-client-for-webhook-context"; import { trackingEventFactory } from "@/modules/tracking-events/tracking-events"; import { orderFullyPaidAsyncWebhook } from "@/modules/webhooks/definitions/order-fully-paid"; @@ -27,27 +28,43 @@ const handler: NextWebhookApiHandler const { authData, payload } = context; if (!payload.order) { - return res.status(200).end(); + logger.info("Payload does not contain order data. Skipping."); + + return res + .status(200) + .json({ message: "Payload does not contain order data. It will be skipped by app" }); } + loggerContext.set(ObservabilityAttributes.ORDER_ID, payload.order.id); + try { const segmentEventTracker = await createSegmentClientForWebhookContext({ authData }); - logger.info("Sending order fully paid event to Segment"); - await segmentEventTracker.trackEvent( trackingEventFactory.createOrderCompletedEvent(payload.order), ); - return res.status(200).end(); + logger.info("Order fully paid event successfully sent to Segment"); + + return res.status(200).json({ message: "Order fully paid event successfully sent to Segment" }); } catch (e) { - if (e instanceof SegmentNotConfiguredError) { + if (e instanceof SegmentWriteKeyNotFoundError) { // todo disable webhooks if not configured - return res.status(200).end(); + logger.warn( + "Segment write key is not set in app configuration. Contact client to fix the issue.", + ); + + return res.status(200).json({ + message: "Segment write key is not set in app configuration. Cannot send event to Segment.", + }); } - return res.status(500).end(); + logger.error("Error while sending order fully paid event to Segment", { error: e }); + + return res + .status(500) + .json({ message: "Error while sending order fully paid event to Segment" }); } }; diff --git a/apps/segment/src/pages/api/webhooks/order-refunded.ts b/apps/segment/src/pages/api/webhooks/order-refunded.ts index b529e6bee..d3a6e55f1 100644 --- a/apps/segment/src/pages/api/webhooks/order-refunded.ts +++ b/apps/segment/src/pages/api/webhooks/order-refunded.ts @@ -1,12 +1,13 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderRefundedSubscriptionPayloadFragment } from "@/generated/graphql"; import { createLogger } from "@/logger"; import { loggerContext } from "@/logger-context"; import { createSegmentClientForWebhookContext, - SegmentNotConfiguredError, + SegmentWriteKeyNotFoundError, } from "@/modules/create-segment-client-for-webhook-context"; import { trackingEventFactory } from "@/modules/tracking-events/tracking-events"; import { orderRefundedAsyncWebhook } from "@/modules/webhooks/definitions/order-refunded"; @@ -27,27 +28,41 @@ const handler: NextWebhookApiHandler = const { authData, payload } = context; if (!payload.order) { - return res.status(400).end(); + logger.info("Payload does not contain order data. Skipping."); + + return res + .status(200) + .json({ message: "Payload does not contain order data. It will be skipped by app" }); } + loggerContext.set(ObservabilityAttributes.ORDER_ID, payload.order.id); + try { const segmentEventTracker = await createSegmentClientForWebhookContext({ authData }); - logger.info("Sending order refunded event to Segment"); - await segmentEventTracker.trackEvent( trackingEventFactory.createOrderRefundedEvent(payload.order), ); - return res.status(200).end(); + logger.info("Order refunded event successfully sent to Segment"); + + return res.status(200).json({ message: "Order refunded event successfully sent to Segment" }); } catch (e) { - if (e instanceof SegmentNotConfiguredError) { + if (e instanceof SegmentWriteKeyNotFoundError) { // todo disable webhooks if not configured - return res.status(200).end(); + logger.warn( + "Segment write key is not set in app configuration. Contact client to fix the issue.", + ); + + return res.status(200).json({ + message: "Segment write key is not set in app configuration. Cannot send event to Segment.", + }); } - return res.status(500).end(); + logger.error("Error while sending order refunded event to Segment", { error: e }); + + return res.status(500).json({ message: "Error while sending order refunded event to Segment" }); } }; diff --git a/apps/segment/src/pages/api/webhooks/order-updated.ts b/apps/segment/src/pages/api/webhooks/order-updated.ts index 7b77d8b11..49671a4bb 100644 --- a/apps/segment/src/pages/api/webhooks/order-updated.ts +++ b/apps/segment/src/pages/api/webhooks/order-updated.ts @@ -1,12 +1,13 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderUpdatedSubscriptionPayloadFragment } from "@/generated/graphql"; import { createLogger } from "@/logger"; import { loggerContext } from "@/logger-context"; import { createSegmentClientForWebhookContext, - SegmentNotConfiguredError, + SegmentWriteKeyNotFoundError, } from "@/modules/create-segment-client-for-webhook-context"; import { trackingEventFactory } from "@/modules/tracking-events/tracking-events"; import { orderUpdatedAsyncWebhook } from "@/modules/webhooks/definitions/order-updated"; @@ -27,27 +28,41 @@ const handler: NextWebhookApiHandler = const { authData, payload } = context; if (!payload.order) { - return res.status(200).end(); + logger.info("Payload does not contain order data. Skipping."); + + return res + .status(200) + .json({ message: "Payload does not contain order data. It will be skipped by app" }); } + loggerContext.set(ObservabilityAttributes.ORDER_ID, payload.order.id); + try { const segmentEventTracker = await createSegmentClientForWebhookContext({ authData }); - logger.info("Sending order updated event to Segment"); - await segmentEventTracker.trackEvent( trackingEventFactory.createOrderUpdatedEvent(payload.order), ); - return res.status(200).end(); + logger.info("Order updated event successfully sent to Segment"); + + return res.status(200).json({ message: "Order updated event successfully sent to Segment" }); } catch (e) { - if (e instanceof SegmentNotConfiguredError) { + if (e instanceof SegmentWriteKeyNotFoundError) { // todo disable webhooks if not configured - return res.status(200).end(); + logger.warn( + "Segment write key is not set in app configuration. Contact client to fix the issue.", + ); + + return res.status(200).json({ + message: "Segment write key is not set in app configuration. Cannot send event to Segment.", + }); } - return res.status(500).end(); + logger.error("Error while sending order updated event to Segment", { error: e }); + + return res.status(500).json({ message: "Error while sending order updated event to Segment" }); } }; From cd4c973e7b9ebd1ee571b211848b171b6d384b43 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krzysztof=20=C5=BBuraw?= <9116238+krzysztofzuraw@users.noreply.github.com> Date: Tue, 31 Dec 2024 11:34:31 +0100 Subject: [PATCH 2/2] Add OTEL & improve logs --- .changeset/real-shrimps-hunt.md | 5 ++ apps/segment/package.json | 13 ++++ .../src/pages/api/webhooks/order-cancelled.ts | 3 +- .../src/pages/api/webhooks/order-created.ts | 3 +- .../pages/api/webhooks/order-fully-paid.ts | 3 +- .../src/pages/api/webhooks/order-refunded.ts | 3 +- .../src/pages/api/webhooks/order-updated.ts | 3 +- pnpm-lock.yaml | 75 ++++++++++++++----- 8 files changed, 85 insertions(+), 23 deletions(-) create mode 100644 .changeset/real-shrimps-hunt.md diff --git a/.changeset/real-shrimps-hunt.md b/.changeset/real-shrimps-hunt.md new file mode 100644 index 000000000..8566cf867 --- /dev/null +++ b/.changeset/real-shrimps-hunt.md @@ -0,0 +1,5 @@ +--- +"segment": patch +--- + +Add OTEL & improve logs in Segment app diff --git a/apps/segment/package.json b/apps/segment/package.json index 578aa526d..595131efb 100644 --- a/apps/segment/package.json +++ b/apps/segment/package.json @@ -17,6 +17,19 @@ }, "dependencies": { "@hookform/resolvers": "^3.3.1", + "@opentelemetry/api": "../../node_modules/@opentelemetry/api", + "@opentelemetry/api-logs": "../../node_modules/@opentelemetry/api-logs", + "@opentelemetry/core": "../../node_modules/@opentelemetry/core", + "@opentelemetry/exporter-logs-otlp-http": "../../node_modules/@opentelemetry/exporter-logs-otlp-http", + "@opentelemetry/exporter-trace-otlp-http": "../../node_modules/@opentelemetry/exporter-trace-otlp-http", + "@opentelemetry/instrumentation-http": "../../node_modules/@opentelemetry/instrumentation-http", + "@opentelemetry/instrumentation-winston": "../../node_modules/@opentelemetry/instrumentation-winston", + "@opentelemetry/resources": "../../node_modules/@opentelemetry/resources", + "@opentelemetry/sdk-logs": "../../node_modules/@opentelemetry/sdk-logs", + "@opentelemetry/sdk-node": "../../node_modules/@opentelemetry/sdk-node", + "@opentelemetry/sdk-trace-base": "../../node_modules/@opentelemetry/sdk-trace-base", + "@opentelemetry/sdk-trace-node": "../../node_modules/@opentelemetry/sdk-trace-node", + "@opentelemetry/semantic-conventions": "../../node_modules/@opentelemetry/semantic-conventions", "@saleor/app-sdk": "link:../../node_modules/@saleor/app-sdk", "@saleor/apps-logger": "workspace:*", "@saleor/apps-otel": "workspace:*", diff --git a/apps/segment/src/pages/api/webhooks/order-cancelled.ts b/apps/segment/src/pages/api/webhooks/order-cancelled.ts index 5addbae04..61c44c2e6 100644 --- a/apps/segment/src/pages/api/webhooks/order-cancelled.ts +++ b/apps/segment/src/pages/api/webhooks/order-cancelled.ts @@ -1,5 +1,6 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { withOtel } from "@saleor/apps-otel"; import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderUpdatedSubscriptionPayloadFragment } from "@/generated/graphql"; @@ -68,6 +69,6 @@ const handler: NextWebhookApiHandler = }; export default wrapWithLoggerContext( - orderCancelledAsyncWebhook.createHandler(handler), + withOtel(orderCancelledAsyncWebhook.createHandler(handler), "/api/webhooks/order-cancelled"), loggerContext, ); diff --git a/apps/segment/src/pages/api/webhooks/order-created.ts b/apps/segment/src/pages/api/webhooks/order-created.ts index 1d44e0558..5a3feb04e 100644 --- a/apps/segment/src/pages/api/webhooks/order-created.ts +++ b/apps/segment/src/pages/api/webhooks/order-created.ts @@ -1,5 +1,6 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { withOtel } from "@saleor/apps-otel"; import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderCreatedSubscriptionPayloadFragment } from "@/generated/graphql"; @@ -67,6 +68,6 @@ const handler: NextWebhookApiHandler = }; export default wrapWithLoggerContext( - orderCreatedAsyncWebhook.createHandler(handler), + withOtel(orderCreatedAsyncWebhook.createHandler(handler), "/api/webhooks/order-created"), loggerContext, ); diff --git a/apps/segment/src/pages/api/webhooks/order-fully-paid.ts b/apps/segment/src/pages/api/webhooks/order-fully-paid.ts index 6bae0bb4d..a32e18012 100644 --- a/apps/segment/src/pages/api/webhooks/order-fully-paid.ts +++ b/apps/segment/src/pages/api/webhooks/order-fully-paid.ts @@ -1,5 +1,6 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { withOtel } from "@saleor/apps-otel"; import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderFullyPaidSubscriptionPayloadFragment } from "@/generated/graphql"; @@ -69,6 +70,6 @@ const handler: NextWebhookApiHandler }; export default wrapWithLoggerContext( - orderFullyPaidAsyncWebhook.createHandler(handler), + withOtel(orderFullyPaidAsyncWebhook.createHandler(handler), "/api/webhooks/order-fully-paid"), loggerContext, ); diff --git a/apps/segment/src/pages/api/webhooks/order-refunded.ts b/apps/segment/src/pages/api/webhooks/order-refunded.ts index d3a6e55f1..e668fe624 100644 --- a/apps/segment/src/pages/api/webhooks/order-refunded.ts +++ b/apps/segment/src/pages/api/webhooks/order-refunded.ts @@ -1,5 +1,6 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { withOtel } from "@saleor/apps-otel"; import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderRefundedSubscriptionPayloadFragment } from "@/generated/graphql"; @@ -67,6 +68,6 @@ const handler: NextWebhookApiHandler = }; export default wrapWithLoggerContext( - orderRefundedAsyncWebhook.createHandler(handler), + withOtel(orderRefundedAsyncWebhook.createHandler(handler), "/api/webhooks/order-refunded"), loggerContext, ); diff --git a/apps/segment/src/pages/api/webhooks/order-updated.ts b/apps/segment/src/pages/api/webhooks/order-updated.ts index 49671a4bb..c1f18a125 100644 --- a/apps/segment/src/pages/api/webhooks/order-updated.ts +++ b/apps/segment/src/pages/api/webhooks/order-updated.ts @@ -1,5 +1,6 @@ import { NextWebhookApiHandler } from "@saleor/app-sdk/handlers/next"; import { wrapWithLoggerContext } from "@saleor/apps-logger/node"; +import { withOtel } from "@saleor/apps-otel"; import { ObservabilityAttributes } from "@saleor/apps-otel/src/lib/observability-attributes"; import { OrderUpdatedSubscriptionPayloadFragment } from "@/generated/graphql"; @@ -67,6 +68,6 @@ const handler: NextWebhookApiHandler = }; export default wrapWithLoggerContext( - orderUpdatedAsyncWebhook.createHandler(handler), + withOtel(orderUpdatedAsyncWebhook.createHandler(handler), "/api/webhooks/order-updated"), loggerContext, ); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d2ca7cc96..a0ef0c21f 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -210,7 +210,7 @@ importers: version: 10.43.1(@trpc/server@10.43.1) '@trpc/next': specifier: 10.43.1 - version: 10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/react-query@10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/server@10.43.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.43.1)(next@14.2.3(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/react-query@10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/server@10.43.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.43.1)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@trpc/server': specifier: 10.43.1 version: 10.43.1 @@ -252,7 +252,7 @@ importers: version: 6.2.1 next: specifier: 14.2.3 - version: 14.2.3(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -475,7 +475,7 @@ importers: version: 20.0.3 next: specifier: 14.2.3 - version: 14.2.3(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) p-ratelimit: specifier: 1.0.1 version: 1.0.1 @@ -647,7 +647,7 @@ importers: version: 2.12.6(graphql@16.7.1) next: specifier: 14.2.3 - version: 14.2.3(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) node-fetch: specifier: ^3.2.6 version: 3.2.6 @@ -849,7 +849,7 @@ importers: version: 20.0.3 next: specifier: 14.2.3 - version: 14.2.3(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -1042,7 +1042,7 @@ importers: version: 2.12.6(graphql@16.7.1) next: specifier: 14.2.3 - version: 14.2.3(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -1128,6 +1128,45 @@ importers: '@hookform/resolvers': specifier: ^3.3.1 version: 3.3.1(react-hook-form@7.44.3(react@18.2.0)) + '@opentelemetry/api': + specifier: ../../node_modules/@opentelemetry/api + version: link:../../node_modules/@opentelemetry/api + '@opentelemetry/api-logs': + specifier: ../../node_modules/@opentelemetry/api-logs + version: link:../../node_modules/@opentelemetry/api-logs + '@opentelemetry/core': + specifier: ../../node_modules/@opentelemetry/core + version: link:../../node_modules/@opentelemetry/core + '@opentelemetry/exporter-logs-otlp-http': + specifier: ../../node_modules/@opentelemetry/exporter-logs-otlp-http + version: link:../../node_modules/@opentelemetry/exporter-logs-otlp-http + '@opentelemetry/exporter-trace-otlp-http': + specifier: ../../node_modules/@opentelemetry/exporter-trace-otlp-http + version: link:../../node_modules/@opentelemetry/exporter-trace-otlp-http + '@opentelemetry/instrumentation-http': + specifier: ../../node_modules/@opentelemetry/instrumentation-http + version: link:../../node_modules/@opentelemetry/instrumentation-http + '@opentelemetry/instrumentation-winston': + specifier: ../../node_modules/@opentelemetry/instrumentation-winston + version: link:../../node_modules/@opentelemetry/instrumentation-winston + '@opentelemetry/resources': + specifier: ../../node_modules/@opentelemetry/resources + version: link:../../node_modules/@opentelemetry/resources + '@opentelemetry/sdk-logs': + specifier: ../../node_modules/@opentelemetry/sdk-logs + version: link:../../node_modules/@opentelemetry/sdk-logs + '@opentelemetry/sdk-node': + specifier: ../../node_modules/@opentelemetry/sdk-node + version: link:../../node_modules/@opentelemetry/sdk-node + '@opentelemetry/sdk-trace-base': + specifier: ../../node_modules/@opentelemetry/sdk-trace-base + version: link:../../node_modules/@opentelemetry/sdk-trace-base + '@opentelemetry/sdk-trace-node': + specifier: ../../node_modules/@opentelemetry/sdk-trace-node + version: link:../../node_modules/@opentelemetry/sdk-trace-node + '@opentelemetry/semantic-conventions': + specifier: ../../node_modules/@opentelemetry/semantic-conventions + version: link:../../node_modules/@opentelemetry/semantic-conventions '@saleor/app-sdk': specifier: link:../../node_modules/@saleor/app-sdk version: link:../../node_modules/@saleor/app-sdk @@ -1175,7 +1214,7 @@ importers: version: 10.43.1(@trpc/server@10.43.1) '@trpc/next': specifier: 10.43.1 - version: 10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/react-query@10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/server@10.43.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.43.1)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/react-query@10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/server@10.43.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.43.1)(next@14.2.3(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@trpc/server': specifier: 10.43.1 version: 10.43.1 @@ -1205,7 +1244,7 @@ importers: version: 6.1.0(modern-errors@7.0.1) next: specifier: 14.2.3 - version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -1428,7 +1467,7 @@ importers: version: 6.2.1 next: specifier: 14.2.3 - version: 14.2.3(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) nodemailer: specifier: ^6.9.1 version: 6.9.1 @@ -1579,7 +1618,7 @@ importers: version: 12.1.1(eslint@node_modules+eslint) next: specifier: 14.2.3 - version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) typescript: specifier: 5.5.4 version: 5.5.4 @@ -1787,7 +1826,7 @@ importers: version: link:../eslint-config-saleor next: specifier: 14.2.3 - version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -1848,7 +1887,7 @@ importers: version: link:../eslint-config-saleor next: specifier: 14.2.3 - version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) typescript: specifier: 5.5.4 version: 5.5.4 @@ -1879,7 +1918,7 @@ importers: version: link:../eslint-config-saleor next: specifier: 14.2.3 - version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: specifier: 18.2.0 version: 18.2.0 @@ -1912,7 +1951,7 @@ importers: version: 6.1.0(modern-errors@7.0.1) next: specifier: 14.2.3 - version: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + version: 14.2.3(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) semver: specifier: 7.5.1 version: 7.5.1 @@ -20537,13 +20576,13 @@ snapshots: react-dom: 18.2.0(react@18.2.0) react-ssr-prepass: 1.5.0(react@18.2.0) - '@trpc/next@10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/react-query@10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/server@10.43.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.43.1)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': + '@trpc/next@10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/react-query@10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/server@10.43.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/server@10.43.1)(next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(react-dom@18.2.0(react@18.2.0))(react@18.2.0)': dependencies: '@tanstack/react-query': 4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@trpc/client': 10.43.1(@trpc/server@10.43.1) '@trpc/react-query': 10.43.1(@tanstack/react-query@4.29.19(react-dom@18.2.0(react@18.2.0))(react@18.2.0))(@trpc/client@10.43.1(@trpc/server@10.43.1))(@trpc/server@10.43.1)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) '@trpc/server': 10.43.1 - next: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) + next: 14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0) react: 18.2.0 react-dom: 18.2.0(react@18.2.0) react-ssr-prepass: 1.5.0(react@18.2.0) @@ -25941,7 +25980,7 @@ snapshots: neverthrow@6.2.1: {} - next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@1.9.0)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): + next@14.2.3(@babel/core@7.24.7)(@opentelemetry/api@node_modules+@opentelemetry+api)(react-dom@18.2.0(react@18.2.0))(react@18.2.0): dependencies: '@next/env': 14.2.3 '@swc/helpers': 0.5.5 @@ -25962,7 +26001,7 @@ snapshots: '@next/swc-win32-arm64-msvc': 14.2.3 '@next/swc-win32-ia32-msvc': 14.2.3 '@next/swc-win32-x64-msvc': 14.2.3 - '@opentelemetry/api': 1.9.0 + '@opentelemetry/api': link:node_modules/@opentelemetry/api transitivePeerDependencies: - '@babel/core' - babel-plugin-macros