diff options
| author | Mohamed Bassem <me@mbassem.com> | 2025-07-06 18:07:56 +0000 |
|---|---|---|
| committer | Mohamed Bassem <me@mbassem.com> | 2025-07-06 18:09:05 +0000 |
| commit | b60ece578304df21602d39c7022a7a4dbc6437e0 (patch) | |
| tree | a5e3395b0b3b5c9bb01566bf68aa21334fd13784 /packages/trpc/index.ts | |
| parent | cfa0385b4dcd37f9cc29a15f94a59a4f48dd05fb (diff) | |
| download | karakeep-b60ece578304df21602d39c7022a7a4dbc6437e0.tar.zst | |
feat: Add prometheus monitoring. Fixes #758
Diffstat (limited to 'packages/trpc/index.ts')
| -rw-r--r-- | packages/trpc/index.ts | 42 |
1 files changed, 34 insertions, 8 deletions
diff --git a/packages/trpc/index.ts b/packages/trpc/index.ts index e34e56eb..90f37ae4 100644 --- a/packages/trpc/index.ts +++ b/packages/trpc/index.ts @@ -5,6 +5,12 @@ import { ZodError } from "zod"; import type { db } from "@karakeep/db"; import serverConfig from "@karakeep/shared/config"; +import { + apiErrorsTotalCounter, + apiRequestDurationSummary, + apiRequestsTotalCounter, +} from "./stats"; + interface User { id: string; name?: string | null | undefined; @@ -36,6 +42,11 @@ const t = initTRPC.context<Context>().create({ transformer: superjson, errorFormatter(opts) { const { shape, error } = opts; + apiErrorsTotalCounter.inc({ + type: opts.type, + path: opts.path, + code: error.code, + }); return { ...shape, data: { @@ -51,15 +62,30 @@ const t = initTRPC.context<Context>().create({ export const createCallerFactory = t.createCallerFactory; // Base router and procedure helpers export const router = t.router; -export const procedure = t.procedure.use(function isDemoMode(opts) { - if (serverConfig.demoMode && opts.type == "mutation") { - throw new TRPCError({ - message: "Mutations are not allowed in demo mode", - code: "FORBIDDEN", +export const procedure = t.procedure + .use(function isDemoMode(opts) { + if (serverConfig.demoMode && opts.type == "mutation") { + throw new TRPCError({ + message: "Mutations are not allowed in demo mode", + code: "FORBIDDEN", + }); + } + return opts.next(); + }) + .use(async (opts) => { + const end = apiRequestDurationSummary.startTimer({ + path: opts.path, + type: opts.type, }); - } - return opts.next(); -}); + const res = await opts.next(); + apiRequestsTotalCounter.inc({ + type: opts.type, + path: opts.path, + is_error: res.ok ? 0 : 1, + }); + end(); + return res; + }); export const publicProcedure = procedure; export const authedProcedure = procedure.use(function isAuthed(opts) { |
