aboutsummaryrefslogtreecommitdiffstats
path: root/packages/trpc
diff options
context:
space:
mode:
Diffstat (limited to 'packages/trpc')
-rw-r--r--packages/trpc/index.ts5
-rw-r--r--packages/trpc/lib/tracing.ts63
2 files changed, 67 insertions, 1 deletions
diff --git a/packages/trpc/index.ts b/packages/trpc/index.ts
index 555ca3ba..178703f0 100644
--- a/packages/trpc/index.ts
+++ b/packages/trpc/index.ts
@@ -6,6 +6,7 @@ import type { db } from "@karakeep/db";
import serverConfig from "@karakeep/shared/config";
import { createRateLimitMiddleware } from "./lib/rateLimit";
+import { createTracingMiddleware } from "./lib/tracing";
import {
apiErrorsTotalCounter,
apiRequestDurationSummary,
@@ -86,7 +87,9 @@ export const procedure = t.procedure
});
end();
return res;
- });
+ })
+ // OpenTelemetry tracing middleware
+ .use(createTracingMiddleware());
// Default public procedure rate limiting
export const publicProcedure = procedure.use(
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);
+ }
+}