aboutsummaryrefslogtreecommitdiffstats
path: root/packages/trpc/lib
diff options
context:
space:
mode:
Diffstat (limited to 'packages/trpc/lib')
-rw-r--r--packages/trpc/lib/tracing.ts63
1 files changed, 63 insertions, 0 deletions
diff --git a/packages/trpc/lib/tracing.ts b/packages/trpc/lib/tracing.ts
new file mode 100644
index 00000000..7b4fb39f
--- /dev/null
+++ b/packages/trpc/lib/tracing.ts
@@ -0,0 +1,63 @@
+import { SpanKind } from "@opentelemetry/api";
+
+import {
+ getTracer,
+ setSpanAttributes,
+ withSpan,
+} from "@karakeep/shared-server";
+import serverConfig from "@karakeep/shared/config";
+
+import type { Context } from "../index";
+
+const tracer = getTracer("@karakeep/trpc");
+
+/**
+ * tRPC middleware that creates a span for each procedure call.
+ * This integrates OpenTelemetry tracing into the tRPC layer.
+ */
+export function createTracingMiddleware() {
+ return async function tracingMiddleware<T>(opts: {
+ ctx: Context;
+ type: "query" | "mutation" | "subscription";
+ path: string;
+ input: unknown;
+ next: () => Promise<T>;
+ }): Promise<T> {
+ // Skip if tracing is disabled
+ if (!serverConfig.tracing.enabled) {
+ return opts.next();
+ }
+
+ const spanName = `trpc.${opts.type}.${opts.path}`;
+
+ return withSpan(
+ tracer,
+ spanName,
+ {
+ kind: SpanKind.SERVER,
+ attributes: {
+ "rpc.system": "trpc",
+ "rpc.method": opts.path,
+ "rpc.type": opts.type,
+ "user.id": opts.ctx.user?.id ?? "anonymous",
+ "user.role": opts.ctx.user?.role ?? "none",
+ },
+ },
+ async () => {
+ return await opts.next();
+ },
+ );
+ };
+}
+
+/**
+ * Helper to add tracing attributes within a tRPC procedure.
+ * Use this to add custom attributes to the current span.
+ */
+export function addTracingAttributes(
+ attributes: Record<string, string | number | boolean>,
+): void {
+ if (serverConfig.tracing.enabled) {
+ setSpanAttributes(attributes);
+ }
+}