From bbc8091d44b31abb26cb94f35d628303375247a2 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Fri, 20 Dec 2024 02:37:44 +0800 Subject: [PATCH 1/3] misc: added metric for api errors --- backend/src/server/plugins/error-handler.ts | 24 +++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/backend/src/server/plugins/error-handler.ts b/backend/src/server/plugins/error-handler.ts index a6142cabca..7f9e161972 100644 --- a/backend/src/server/plugins/error-handler.ts +++ b/backend/src/server/plugins/error-handler.ts @@ -1,8 +1,10 @@ import { ForbiddenError, PureAbility } from "@casl/ability"; +import opentelemetry from "@opentelemetry/api"; import fastifyPlugin from "fastify-plugin"; import jwt from "jsonwebtoken"; import { ZodError } from "zod"; +import { getConfig } from "@app/lib/config/env"; import { BadRequestError, DatabaseError, @@ -35,8 +37,30 @@ enum HttpStatusCodes { } export const fastifyErrHandler = fastifyPlugin(async (server: FastifyZodProvider) => { + const appCfg = getConfig(); + + const apiMeter = opentelemetry.metrics.getMeter("API"); + const errorHistogram = apiMeter.createHistogram("API_errors", { + description: "API errors by type, status code, and name", + unit: "1" + }); + server.setErrorHandler((error, req, res) => { req.log.error(error); + if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) { + const { method } = req; + const route = req.routerPath; + const errorType = + error instanceof jwt.JsonWebTokenError ? "TokenError" : error.constructor.name || "UnknownError"; + + errorHistogram.record(1, { + route, + method, + type: errorType, + name: error.name + }); + } + if (error instanceof BadRequestError) { void res .status(HttpStatusCodes.BadRequest) From cde813aafb5504767926350b2c1dafc3fccb7d79 Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Fri, 20 Dec 2024 03:08:55 +0800 Subject: [PATCH 2/3] misc: added custom metrics for integration syncs --- backend/src/services/secret/secret-queue.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/backend/src/services/secret/secret-queue.ts b/backend/src/services/secret/secret-queue.ts index 57d32ab116..d4e857832d 100644 --- a/backend/src/services/secret/secret-queue.ts +++ b/backend/src/services/secret/secret-queue.ts @@ -1,4 +1,5 @@ /* eslint-disable no-await-in-loop */ +import opentelemetry from "@opentelemetry/api"; import { AxiosError } from "axios"; import { @@ -158,6 +159,12 @@ export const secretQueueFactory = ({ projectUserMembershipRoleDAL, projectKeyDAL }: TSecretQueueFactoryDep) => { + const integrationMeter = opentelemetry.metrics.getMeter("Integrations"); + const errorHistogram = integrationMeter.createHistogram("integration_secret_sync_errors", { + description: "Integration secret sync errors", + unit: "1" + }); + const removeSecretReminder = async (dto: TRemoveSecretReminderDTO) => { const appCfg = getConfig(); await queueService.stopRepeatableJob( @@ -933,6 +940,18 @@ export const secretQueueFactory = ({ `Secret integration sync error [projectId=${job.data.projectId}] [environment=${environment}] [secretPath=${job.data.secretPath}]` ); + const appCfg = getConfig(); + if (appCfg.OTEL_TELEMETRY_COLLECTION_ENABLED) { + errorHistogram.record(1, { + version: 1, + integration: integration.integration, + type: err instanceof AxiosError ? "AxiosError" : err?.constructor?.name || "UnknownError", + status: err instanceof AxiosError ? err.response?.status : undefined, + name: err instanceof Error ? err.name : undefined, + projectId: integration.projectId + }); + } + const message = // eslint-disable-next-line no-nested-ternary (err instanceof AxiosError From 2357f3bc1f614509f0477d2dbd98a9fdb72efe6a Mon Sep 17 00:00:00 2001 From: Sheen Capadngan Date: Fri, 20 Dec 2024 03:10:59 +0800 Subject: [PATCH 3/3] misc: added integration ID --- backend/src/services/secret/secret-queue.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/src/services/secret/secret-queue.ts b/backend/src/services/secret/secret-queue.ts index d4e857832d..9b2f802256 100644 --- a/backend/src/services/secret/secret-queue.ts +++ b/backend/src/services/secret/secret-queue.ts @@ -945,6 +945,7 @@ export const secretQueueFactory = ({ errorHistogram.record(1, { version: 1, integration: integration.integration, + integrationId: integration.id, type: err instanceof AxiosError ? "AxiosError" : err?.constructor?.name || "UnknownError", status: err instanceof AxiosError ? err.response?.status : undefined, name: err instanceof Error ? err.name : undefined,