Skip to content

Commit 4e1d05a

Browse files
authored
feat: dist tracing 4 (calcom#25574)
* feat: distributed tracing 2 * feat: distributed tracing 2 * refactor: feedback * refactor: feedback * fix: type error * fix: trpc error * feat: distributed tracing - 3 * chore: translation * refactor: improvements * fix: feedback * chore: remove * feat: dist tracing 4 * fix: type errors * fix: type errors * fix: remove string type * fix: type errors
1 parent 0d4108d commit 4e1d05a

15 files changed

Lines changed: 127 additions & 26 deletions

File tree

apps/web/test/lib/confirm.handler.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
import { describe, it, beforeEach, vi, expect } from "vitest";
1010

1111
import * as handleConfirmationModule from "@calcom/features/bookings/lib/handleConfirmation";
12+
import { distributedTracing } from "@calcom/lib/tracing/factory";
1213
import { BookingStatus } from "@calcom/prisma/enums";
1314
import { confirmHandler } from "@calcom/trpc/server/routers/viewer/bookings/confirm.handler";
1415
import type { TrpcSessionUser } from "@calcom/trpc/server/types";
@@ -92,6 +93,7 @@ describe("confirmHandler", () => {
9293
timeZone: organizer.timeZone,
9394
username: organizer.username,
9495
} as NonNullable<TrpcSessionUser>,
96+
traceContext: distributedTracing.createTrace("test_confirm_handler"),
9597
};
9698

9799
const res = await confirmHandler({

apps/web/test/utils/bookingScenario/bookingScenario.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { z } from "zod";
1010

1111
import { appStoreMetadata } from "@calcom/app-store/appStoreMetaData";
1212
import { handleStripePaymentSuccess } from "@calcom/features/ee/payments/api/webhook";
13+
import { distributedTracing } from "@calcom/lib/tracing/factory";
1314
import { ProfileRepository } from "@calcom/features/profile/repositories/ProfileRepository";
1415
import { weekdayToWeekIndex, type WeekDays } from "@calcom/lib/dayjs";
1516
import type { HttpError } from "@calcom/lib/http-error";
@@ -2287,7 +2288,8 @@ export function getMockedStripePaymentEvent({ paymentIntentId }: { paymentIntent
22872288
export async function mockPaymentSuccessWebhookFromStripe({ externalId }: { externalId: string }) {
22882289
let webhookResponse = null;
22892290
try {
2290-
await handleStripePaymentSuccess(getMockedStripePaymentEvent({ paymentIntentId: externalId }));
2291+
const traceContext = distributedTracing.createTrace("test_stripe_webhook");
2292+
await handleStripePaymentSuccess(getMockedStripePaymentEvent({ paymentIntentId: externalId }), traceContext);
22912293
} catch (e) {
22922294
log.silly("mockPaymentSuccessWebhookFromStripe:catch", JSON.stringify(e));
22932295
webhookResponse = e as HttpError;

packages/app-store/_utils/payments/handlePaymentSuccess.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,19 @@ import { getPlatformParams } from "@calcom/features/platform-oauth-client/get-pl
1010
import { PlatformOAuthClientRepository } from "@calcom/features/platform-oauth-client/platform-oauth-client.repository";
1111
import { HttpError as HttpCode } from "@calcom/lib/http-error";
1212
import logger from "@calcom/lib/logger";
13+
import type { TraceContext } from "@calcom/lib/tracing";
14+
import { distributedTracing } from "@calcom/lib/tracing/factory";
1315
import prisma from "@calcom/prisma";
1416
import type { Prisma } from "@calcom/prisma/client";
1517
import { BookingStatus } from "@calcom/prisma/enums";
1618
import type { EventTypeMetadata } from "@calcom/prisma/zod-utils";
1719

1820
const log = logger.getSubLogger({ prefix: ["[handlePaymentSuccess]"] });
19-
export async function handlePaymentSuccess(paymentId: number, bookingId: number) {
21+
export async function handlePaymentSuccess(paymentId: number, bookingId: number, traceContext: TraceContext) {
22+
const updatedTraceContext = distributedTracing.updateTrace(traceContext, {
23+
bookingId,
24+
paymentId,
25+
});
2026
log.debug(`handling payment success for bookingId ${bookingId}`);
2127
const { booking, user: userWithCredentials, evt, eventType } = await getBooking(bookingId);
2228

@@ -87,6 +93,7 @@ export async function handlePaymentSuccess(paymentId: number, bookingId: number)
8793
booking,
8894
paid: true,
8995
platformClientParams: platformOAuthClient ? getPlatformParams(platformOAuthClient) : undefined,
96+
traceContext: updatedTraceContext,
9097
});
9198
} else {
9299
await handleBookingRequested({

packages/app-store/alby/api/webhook.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import getRawBody from "raw-body";
33
import { z } from "zod";
44

55
import { handlePaymentSuccess } from "@calcom/app-store/_utils/payments/handlePaymentSuccess";
6+
import { distributedTracing } from "@calcom/lib/tracing/factory";
67
import { albyCredentialKeysSchema } from "@calcom/app-store/alby/lib";
78
import parseInvoice from "@calcom/app-store/alby/lib/parseInvoice";
89
import { IS_PRODUCTION } from "@calcom/lib/constants";
@@ -88,7 +89,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
8889
throw new HttpCode({ statusCode: 400, message: "invoice amount does not match payment amount" });
8990
}
9091

91-
return await handlePaymentSuccess(payment.id, payment.bookingId);
92+
const traceContext = distributedTracing.createTrace("alby_webhook", {
93+
meta: { paymentId: payment.id, bookingId: payment.bookingId },
94+
});
95+
return await handlePaymentSuccess(payment.id, payment.bookingId, traceContext);
9296
} catch (_err) {
9397
const err = getServerErrorFromUnknown(_err);
9498
console.error(`Webhook Error: ${err.message}`);

packages/app-store/btcpayserver/api/webhook.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import getRawBody from "raw-body";
44
import { z } from "zod";
55

66
import { handlePaymentSuccess } from "@calcom/app-store/_utils/payments/handlePaymentSuccess";
7+
import { distributedTracing } from "@calcom/lib/tracing/factory";
78
import { IS_PRODUCTION } from "@calcom/lib/constants";
89
import { HttpError as HttpCode } from "@calcom/lib/http-error";
910
import { getServerErrorFromUnknown } from "@calcom/lib/server/getServerErrorFromUnknown";
@@ -87,7 +88,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
8788
);
8889
if (!isValid) throw new HttpCode({ statusCode: 400, message: "signature mismatch" });
8990

90-
await handlePaymentSuccess(payment.id, payment.bookingId);
91+
const traceContext = distributedTracing.createTrace("btcpayserver_webhook", {
92+
meta: { paymentId: payment.id, bookingId: payment.bookingId },
93+
});
94+
await handlePaymentSuccess(payment.id, payment.bookingId, traceContext);
9195
return res.status(200).json({ success: true });
9296
} catch (_err) {
9397
const err = getServerErrorFromUnknown(_err);

packages/app-store/hitpay/api/webhook.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type { NextApiRequest, NextApiResponse } from "next";
33
import type z from "zod";
44

55
import { handlePaymentSuccess } from "@calcom/app-store/_utils/payments/handlePaymentSuccess";
6+
import { distributedTracing } from "@calcom/lib/tracing/factory";
67
import { IS_PRODUCTION } from "@calcom/lib/constants";
78
import { HttpError as HttpCode } from "@calcom/lib/http-error";
89
import { getServerErrorFromUnknown } from "@calcom/lib/server/getServerErrorFromUnknown";
@@ -109,7 +110,10 @@ export default async function handler(req: NextApiRequest, res: NextApiResponse)
109110
if (excluded.status !== "completed") {
110111
throw new HttpCode({ statusCode: 204, message: `Payment is ${excluded.status}` });
111112
}
112-
return await handlePaymentSuccess(payment.id, payment.bookingId);
113+
const traceContext = distributedTracing.createTrace("hitpay_webhook", {
114+
meta: { paymentId: payment.id, bookingId: payment.bookingId },
115+
});
116+
return await handlePaymentSuccess(payment.id, payment.bookingId, traceContext);
113117
} catch (_err) {
114118
const err = getServerErrorFromUnknown(_err);
115119
console.error(`Webhook Error: ${err.message}`);

packages/app-store/paypal/api/webhook.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import getRawBody from "raw-body";
33
import { z } from "zod";
44

55
import { handlePaymentSuccess } from "@calcom/app-store/_utils/payments/handlePaymentSuccess";
6+
import { distributedTracing } from "@calcom/lib/tracing/factory";
67
import { paypalCredentialKeysSchema } from "@calcom/app-store/paypal/lib";
78
import Paypal from "@calcom/app-store/paypal/lib/Paypal";
89
import { IS_PRODUCTION } from "@calcom/lib/constants";
@@ -62,7 +63,10 @@ export async function handlePaypalPaymentSuccess(
6263
},
6364
});
6465

65-
return await handlePaymentSuccess(payment.id, payment.bookingId);
66+
const traceContext = distributedTracing.createTrace("paypal_webhook", {
67+
meta: { paymentId: payment.id, bookingId: payment.bookingId },
68+
});
69+
return await handlePaymentSuccess(payment.id, payment.bookingId, traceContext);
6670
}
6771

6872
export default async function handler(req: NextApiRequest, res: NextApiResponse) {

packages/features/bookings/lib/handleConfirmation.ts

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import getOrgIdFromMemberOrTeamId from "@calcom/lib/getOrgIdFromMemberOrTeamId";
2020
import { getTeamIdFromEventType } from "@calcom/lib/getTeamIdFromEventType";
2121
import logger from "@calcom/lib/logger";
2222
import { safeStringify } from "@calcom/lib/safeStringify";
23+
import type { TraceContext } from "@calcom/lib/tracing";
24+
import { distributedTracing } from "@calcom/lib/tracing/factory";
2325
import type { PrismaClient } from "@calcom/prisma";
2426
import type { Prisma } from "@calcom/prisma/client";
2527
import type { SchedulingType } from "@calcom/prisma/enums";
@@ -74,6 +76,7 @@ export async function handleConfirmation(args: {
7476
paid?: boolean;
7577
emailsEnabled?: boolean;
7678
platformClientParams?: PlatformClientParams;
79+
traceContext: TraceContext;
7780
}) {
7881
const {
7982
user,
@@ -85,6 +88,7 @@ export async function handleConfirmation(args: {
8588
paid,
8689
emailsEnabled = true,
8790
platformClientParams,
91+
traceContext,
8892
} = args;
8993
const eventType = booking.eventType;
9094
const eventTypeMetadata = EventTypeMetaDataSchema.parse(eventType?.metadata || {});
@@ -96,13 +100,17 @@ export async function handleConfirmation(args: {
96100
const metadata: AdditionalInformation = {};
97101
const workflows = await getAllWorkflowsFromEventType(eventType, booking.userId);
98102

103+
const spanContext = distributedTracing.createSpan(traceContext, "handle_confirmation");
104+
105+
const tracingLogger = distributedTracing.getTracingLogger(spanContext);
106+
99107
if (results.length > 0 && results.every((res) => !res.success)) {
100108
const error = {
101109
errorCode: "BookingCreatingMeetingFailed",
102110
message: "Booking failed",
103111
};
104112

105-
log.error(`Booking ${user.username} failed`, safeStringify({ error, results }));
113+
tracingLogger.error(`Booking ${user.username} failed`, safeStringify({ error, results }));
106114
} else {
107115
if (results.length) {
108116
// TODO: Handle created event metadata more elegantly
@@ -139,7 +147,7 @@ export async function handleConfirmation(args: {
139147
);
140148
}
141149
} catch (error) {
142-
log.error(error);
150+
tracingLogger.error(error);
143151
}
144152
}
145153
let updatedBookings: {
@@ -358,6 +366,7 @@ export async function handleConfirmation(args: {
358366
hideBranding: !!updatedBookings[index].eventType?.owner?.hideBranding,
359367
seatReferenceUid: evt.attendeeSeatId,
360368
isPlatformNoEmail: !emailsEnabled && Boolean(platformClientParams?.platformClientId),
369+
traceContext: spanContext,
361370
});
362371
}
363372

@@ -487,7 +496,7 @@ export async function handleConfirmation(args: {
487496
sub,
488497
payload
489498
).catch((e) => {
490-
log.error(
499+
tracingLogger.error(
491500
`Error executing webhook for event: ${WebhookTriggerEvents.BOOKING_CREATED}, URL: ${sub.subscriberUrl}, bookingId: ${evt.bookingId}, bookingUid: ${evt.uid}, platformClientId: ${platformClientParams?.platformClientId}`,
492501
safeStringify(e)
493502
);
@@ -547,7 +556,7 @@ export async function handleConfirmation(args: {
547556
sub,
548557
payload
549558
).catch((e) => {
550-
log.error(
559+
tracingLogger.error(
551560
`Error executing webhook for event: ${WebhookTriggerEvents.BOOKING_PAID}, URL: ${sub.subscriberUrl}, bookingId: ${evt.bookingId}, bookingUid: ${evt.uid}`,
552561
safeStringify(e)
553562
);
@@ -586,7 +595,10 @@ export async function handleConfirmation(args: {
586595
creditCheckFn: creditService.hasAvailableCredits.bind(creditService),
587596
});
588597
} catch (error) {
589-
log.error("Error while scheduling workflow reminders for booking paid", safeStringify(error));
598+
tracingLogger.error(
599+
"Error while scheduling workflow reminders for booking paid",
600+
safeStringify(error)
601+
);
590602
}
591603
}
592604
} catch (error) {

packages/features/bookings/lib/handleSeats/handleSeats.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ const handleSeats = async (newSeatedBookingObject: NewSeatedBookingObject) => {
3434
rescheduledBy,
3535
rescheduleReason,
3636
isDryRun = false,
37+
traceContext,
3738
} = newSeatedBookingObject;
3839
// TODO: We could allow doing more things to support good dry run for seats
3940
if (isDryRun) return;
@@ -160,7 +161,7 @@ const handleSeats = async (newSeatedBookingObject: NewSeatedBookingObject) => {
160161
rescheduledBy,
161162
};
162163

163-
await handleWebhookTrigger({ subscriberOptions, eventTrigger, webhookData, isDryRun });
164+
await handleWebhookTrigger({ subscriberOptions, eventTrigger, webhookData, isDryRun, traceContext });
164165
}
165166

166167
return resultBooking;

packages/features/bookings/lib/handleSeats/types.d.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type z from "zod";
22

33
import type { Workflow } from "@calcom/features/ee/workflows/lib/types";
4+
import type { TraceContext } from "@calcom/lib/tracing";
45
import type { Prisma } from "@calcom/prisma/client";
56
import type { AppsStatus, CalendarEvent } from "@calcom/types/Calendar";
67

@@ -58,6 +59,7 @@ export type NewSeatedBookingObject = {
5859
rescheduledBy?: string;
5960
workflows: Workflow[];
6061
isDryRun?: boolean;
62+
traceContext: TraceContext;
6163
};
6264

6365
export type RescheduleSeatedBookingObject = NewSeatedBookingObject & { rescheduleUid: string };

0 commit comments

Comments
 (0)