From 0e4b94b5737551ac2d2b587758c03e0f70a71975 Mon Sep 17 00:00:00 2001 From: Himanshu Dixit Date: Thu, 12 Dec 2024 21:32:02 +0530 Subject: [PATCH] fix: add telemetry events (#985) Co-authored-by: Apoorv Taneja --- js/package.json | 2 +- js/src/constants.js | 2 +- js/src/frameworks/cloudflare.ts | 19 ++++++++++++- js/src/frameworks/langchain.ts | 9 ++++++ js/src/frameworks/openai.ts | 37 ++++++++++++++++++++++++ js/src/frameworks/vercel.ts | 15 ++++++++++ js/src/sdk/index.ts | 13 ++++++++- js/src/sdk/models/Entity.ts | 39 ++++++++++++++++++++++++++ js/src/sdk/models/actions.ts | 28 ++++++++++++++++++ js/src/sdk/models/activeTriggers.ts | 24 +++++++++++++++- js/src/sdk/models/apps.ts | 23 +++++++++++++++ js/src/sdk/models/connectedAccounts.ts | 33 ++++++++++++++++++++++ js/src/sdk/models/integrations.ts | 28 ++++++++++++++++++ js/src/sdk/models/triggers.ts | 33 ++++++++++++++++++++++ js/src/sdk/utils/common.ts | 9 +++++- js/src/sdk/utils/errors/index.ts | 4 +-- js/src/sdk/utils/telemetry/index.ts | 18 ++++-------- js/src/utils/external.ts | 12 ++++++-- 18 files changed, 326 insertions(+), 22 deletions(-) diff --git a/js/package.json b/js/package.json index 122f23f3398..75c4c953b55 100644 --- a/js/package.json +++ b/js/package.json @@ -1,6 +1,6 @@ { "name": "composio-core", - "version": "0.4.1-beta", + "version": "0.4.3-beta", "description": "", "main": "dist/index.js", "scripts": { diff --git a/js/src/constants.js b/js/src/constants.js index 60a088273e0..8ca17b29c42 100644 --- a/js/src/constants.js +++ b/js/src/constants.js @@ -8,7 +8,7 @@ const ACTIONS = { // actions list end here }; -const COMPOSIO_VERSION = `0.4.1-beta`; +const COMPOSIO_VERSION = `0.4.3-beta`; module.exports = { APPS, diff --git a/js/src/frameworks/cloudflare.ts b/js/src/frameworks/cloudflare.ts index e943be50225..27fddd7c810 100644 --- a/js/src/frameworks/cloudflare.ts +++ b/js/src/frameworks/cloudflare.ts @@ -7,7 +7,8 @@ import { import { COMPOSIO_BASE_URL } from "../sdk/client/core/OpenAPI"; import { WorkspaceConfig } from "../env/config"; import { Workspace } from "../env"; -import { ActionsListResponseDTO } from "../sdk/client"; +import { TELEMETRY_LOGGER } from "../sdk/utils/telemetry"; +import { TELEMETRY_EVENTS } from "../sdk/utils/telemetry/events"; // Type definitions type Optional = T | null; @@ -21,6 +22,7 @@ export class CloudflareToolSet extends BaseComposioToolSet { // Class constants static FRAMEWORK_NAME = "cloudflare"; static DEFAULT_ENTITY_ID = "default"; + fileName: string = "js/src/frameworks/cloudflare.ts"; /** * Initialize a new CloudflareToolSet instance @@ -58,6 +60,11 @@ export class CloudflareToolSet extends BaseComposioToolSet { usecaseLimit?: Optional; filterByAvailableApps?: Optional; }): Promise> { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getTools", + file: this.fileName, + params: filters, + }); const actions = await this.getToolsSchema(filters); return ( actions.map((action) => { @@ -99,6 +106,11 @@ export class CloudflareToolSet extends BaseComposioToolSet { }, entityId: Optional = null ): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "executeToolCall", + file: this.fileName, + params: { tool, entityId }, + }); return JSON.stringify( await this.executeAction({ action: tool.name, @@ -122,6 +134,11 @@ export class CloudflareToolSet extends BaseComposioToolSet { result: AiTextGenerationOutput, entityId: Optional = null ): Promise> { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "handleToolCall", + file: this.fileName, + params: { result, entityId }, + }); const outputs = []; if ("tool_calls" in result && Array.isArray(result.tool_calls)) { for (const tool_call of result.tool_calls) { diff --git a/js/src/frameworks/langchain.ts b/js/src/frameworks/langchain.ts index ab979249d5c..c6e512058aa 100644 --- a/js/src/frameworks/langchain.ts +++ b/js/src/frameworks/langchain.ts @@ -5,6 +5,8 @@ import { COMPOSIO_BASE_URL } from "../sdk/client/core/OpenAPI"; import type { Optional, Dict, Sequence } from "../sdk/types"; import { WorkspaceConfig } from "../env/config"; import { Workspace } from "../env"; +import { TELEMETRY_EVENTS } from "../sdk/utils/telemetry/events"; +import { TELEMETRY_LOGGER } from "../sdk/utils/telemetry"; export class LangchainToolSet extends BaseComposioToolSet { /** @@ -13,6 +15,7 @@ export class LangchainToolSet extends BaseComposioToolSet { */ static FRAMEWORK_NAME = "langchain"; static DEFAULT_ENTITY_ID = "default"; + fileName: string = "js/src/frameworks/langchain.ts"; constructor( config: { @@ -72,6 +75,12 @@ export class LangchainToolSet extends BaseComposioToolSet { }, entityId: Optional = null ): Promise> { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getTools", + file: this.fileName, + params: { filters, entityId }, + }); + const tools = await this.getToolsSchema(filters, entityId); return tools.map((tool) => this._wrapTool(tool, entityId || this.entityId)); } diff --git a/js/src/frameworks/openai.ts b/js/src/frameworks/openai.ts index 535a52e0e81..dc3d9ec0753 100644 --- a/js/src/frameworks/openai.ts +++ b/js/src/frameworks/openai.ts @@ -7,6 +7,8 @@ import { Workspace } from "../env"; import logger from "../utils/logger"; import { ActionsListResponseDTO } from "../sdk/client"; import { Stream } from "openai/streaming"; +import { TELEMETRY_LOGGER } from "../sdk/utils/telemetry"; +import { TELEMETRY_EVENTS } from "../sdk/utils/telemetry/events"; type Optional = T | null; type Sequence = Array; @@ -15,6 +17,8 @@ export class OpenAIToolSet extends BaseComposioToolSet { static FRAMEWORK_NAME = "openai"; static DEFAULT_ENTITY_ID = "default"; + fileName: string = "js/src/frameworks/openai.ts"; + /** * Composio toolset for OpenAI framework. * @@ -51,6 +55,12 @@ export class OpenAIToolSet extends BaseComposioToolSet { }, entityId?: Optional ): Promise> { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getTools", + file: this.fileName, + params: filters, + }); + const mainActions = await this.getToolsSchema(filters, entityId); return ( mainActions.map( @@ -74,6 +84,11 @@ export class OpenAIToolSet extends BaseComposioToolSet { tool: OpenAI.ChatCompletionMessageToolCall, entityId: Optional = null ): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "executeToolCall", + file: this.fileName, + params: { tool, entityId }, + }); return JSON.stringify( await this.executeAction({ action: tool.function.name, @@ -87,6 +102,11 @@ export class OpenAIToolSet extends BaseComposioToolSet { chatCompletion: OpenAI.ChatCompletion, entityId: Optional = null ): Promise> { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "handleToolCall", + file: this.fileName, + params: { chatCompletion, entityId }, + }); const outputs = []; for (const message of chatCompletion.choices) { if (message.message.tool_calls) { @@ -104,6 +124,11 @@ export class OpenAIToolSet extends BaseComposioToolSet { ): Promise< Array > { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "handleAssistantMessage", + file: this.fileName, + params: { run, entityId }, + }); const tool_calls = run.required_action?.submit_tool_outputs?.tool_calls || []; const tool_outputs: Array = @@ -134,6 +159,12 @@ export class OpenAIToolSet extends BaseComposioToolSet { thread: OpenAI.Beta.Threads.Thread, entityId: string | null = null ): AsyncGenerator { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "waitAndHandleAssistantStreamToolCalls", + file: this.fileName, + params: { client, runStream, thread, entityId }, + }); + let runId = null; // Start processing the runStream events @@ -213,6 +244,12 @@ export class OpenAIToolSet extends BaseComposioToolSet { thread: OpenAI.Beta.Threads.Thread, entityId: Optional = null ): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "waitAndHandleAssistantToolCalls", + file: this.fileName, + params: { client, run, thread, entityId }, + }); + while (["queued", "in_progress", "requires_action"].includes(run.status)) { logger.debug(`Current run status: ${run.status}`); const tool_outputs = await this.handleAssistantMessage( diff --git a/js/src/frameworks/vercel.ts b/js/src/frameworks/vercel.ts index 1d2c8b3b290..de6f14a9c0a 100644 --- a/js/src/frameworks/vercel.ts +++ b/js/src/frameworks/vercel.ts @@ -4,6 +4,8 @@ import { jsonSchemaToModel } from "../utils/shared"; import { z } from "zod"; import { CEG } from "../sdk/utils/error"; import { SDK_ERROR_CODES } from "../sdk/utils/errors/src/constants"; +import { TELEMETRY_LOGGER } from "../sdk/utils/telemetry"; +import { TELEMETRY_EVENTS } from "../sdk/utils/telemetry/events"; type Optional = T | null; const zExecuteToolCallParams = z.object({ @@ -20,6 +22,7 @@ const zExecuteToolCallParams = z.object({ }); export class VercelAIToolSet extends BaseComposioToolSet { + fileName: string = "js/src/frameworks/vercel.ts"; constructor( config: { apiKey?: Optional; @@ -61,6 +64,12 @@ export class VercelAIToolSet extends BaseComposioToolSet { usecaseLimit?: Optional; filterByAvailableApps?: Optional; }): Promise<{ [key: string]: any }> { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getTools", + file: this.fileName, + params: filters, + }); + const { apps, tags, @@ -92,6 +101,12 @@ export class VercelAIToolSet extends BaseComposioToolSet { tool: { name: string; arguments: unknown }, entityId: Optional = null ): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "executeToolCall", + file: this.fileName, + params: { tool, entityId }, + }); + return JSON.stringify( await this.executeAction({ action: tool.name, diff --git a/js/src/sdk/index.ts b/js/src/sdk/index.ts index 7340d0ad964..70a6993aa67 100644 --- a/js/src/sdk/index.ts +++ b/js/src/sdk/index.ts @@ -32,6 +32,8 @@ export class Composio { integrations: Integrations; activeTriggers: ActiveTriggers; + fileName: string = "js/src/sdk/index.ts"; + /** * Initializes a new instance of the Composio class. * @@ -45,7 +47,6 @@ export class Composio { baseUrl, apiKey ); - const loggingLevel = getLogLevel(); ComposioSDKContext.apiKey = apiKeyParsed; ComposioSDKContext.baseURL = baseURLParsed; @@ -121,6 +122,11 @@ export class Composio { * @returns {Entity} An instance of the Entity class. */ getEntity(id: string = "default"): Entity { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getEntity", + file: this.fileName, + params: { id }, + }); return new Entity(this.backendClient, id); } @@ -148,6 +154,11 @@ export class Composio { | "BEARER_TOKEN" | "BASIC_WITH_JWT"; }> { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getExpectedParamsForUser", + file: this.fileName, + params: params, + }); const { app } = params; let { integrationId } = params; if (integrationId === null && app === null) { diff --git a/js/src/sdk/models/Entity.ts b/js/src/sdk/models/Entity.ts index f79e1aa9b11..1f7333fec06 100644 --- a/js/src/sdk/models/Entity.ts +++ b/js/src/sdk/models/Entity.ts @@ -10,6 +10,8 @@ import { CEG } from "../utils/error"; import logger from "../../utils/logger"; import { SDK_ERROR_CODES } from "../utils/errors/src/constants"; import { z } from "zod"; +import { TELEMETRY_LOGGER } from "../utils/telemetry"; +import { TELEMETRY_EVENTS } from "../utils/telemetry/events"; const LABELS = { PRIMARY: "primary", @@ -50,6 +52,8 @@ export class Entity { integrations: Integrations; activeTriggers: ActiveTriggers; + fileName: string = "js/src/sdk/models/Entity.ts"; + constructor(backendClient: BackendClient, id: string = "default") { this.backendClient = backendClient; this.id = id; @@ -67,6 +71,11 @@ export class Entity { text, connectedAccountId, }: TExecuteActionParams) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "execute", + file: this.fileName, + params: { actionName, params, text, connectedAccountId }, + }); try { ZExecuteActionParams.parse({ actionName, @@ -128,6 +137,11 @@ export class Entity { app?: string; connectedAccountId?: string; }): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getConnection", + file: this.fileName, + params: { app, connectedAccountId }, + }); try { if (connectedAccountId) { return await this.connectedAccounts.get({ @@ -187,6 +201,11 @@ export class Entity { triggerName: string, config: { [key: string]: any } ) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "setupTrigger", + file: this.fileName, + params: { app, triggerName, config }, + }); try { const connectedAccount = await this.getConnection({ app }); if (!connectedAccount) { @@ -209,6 +228,11 @@ export class Entity { } async disableTrigger(triggerId: string) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "disableTrigger", + file: this.fileName, + params: { triggerId }, + }); try { await this.activeTriggers.disable({ triggerId: triggerId }); return { status: "success" }; @@ -221,6 +245,11 @@ export class Entity { /** * Get all connections for an entity. */ + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getConnections", + file: this.fileName, + params: {}, + }); try { const connectedAccounts = await this.connectedAccounts.list({ // @ts-ignore @@ -236,6 +265,11 @@ export class Entity { /** * Get all active triggers for an entity. */ + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getActiveTriggers", + file: this.fileName, + params: {}, + }); try { const connectedAccounts = await this.getConnections(); const activeTriggers = await this.activeTriggers.list({ @@ -253,6 +287,11 @@ export class Entity { async initiateConnection( data: TInitiateConnectionParams ): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "initiateConnection", + file: this.fileName, + params: { data }, + }); try { const { appName, authMode, authConfig, integrationId, connectionData } = ZInitiateConnectionParams.parse(data); diff --git a/js/src/sdk/models/actions.ts b/js/src/sdk/models/actions.ts index fd07fd93f8f..190ffb11450 100644 --- a/js/src/sdk/models/actions.ts +++ b/js/src/sdk/models/actions.ts @@ -5,6 +5,8 @@ import { } from "../client"; import apiClient from "../client/client"; import { CEG } from "../utils/error"; +import { TELEMETRY_LOGGER } from "../utils/telemetry"; +import { TELEMETRY_EVENTS } from "../utils/telemetry/events"; import { BackendClient } from "./backendClient"; /** @@ -149,6 +151,7 @@ export type ExecuteActionResponse = { }; export class Actions { backendClient: BackendClient; + fileName: string = "js/src/sdk/models/actions.ts"; constructor(backendClient: BackendClient) { this.backendClient = backendClient; @@ -164,6 +167,11 @@ export class Actions { * @throws {ApiError} If the request fails. */ async get(data: { actionName: string }) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "get", + file: this.fileName, + params: { data }, + }); try { const actions = await apiClient.actionsV2.getActionV2({ path: { @@ -187,6 +195,11 @@ export class Actions { * @throws {ApiError} If the request fails. */ async list(data: GetListActionsData = {}): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "list", + file: this.fileName, + params: { data }, + }); try { let apps = data.apps; @@ -231,6 +244,11 @@ export class Actions { * @throws {ApiError} If the request fails. */ async execute(data: ExecuteActionData) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "execute", + file: this.fileName, + params: { data }, + }); try { const { data: res } = await apiClient.actionsV2.executeActionV2({ body: data.requestBody as unknown as ActionExecutionReqDTO, @@ -249,6 +267,11 @@ export class Actions { useCase: string; limit?: number; }): Promise> { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "findActionEnumsByUseCase", + file: this.fileName, + params: { data }, + }); try { const { data: res } = await apiClient.actionsV2.advancedUseCaseSearch({ query: { @@ -274,6 +297,11 @@ export class Actions { */ async executeRequest(data: ActionProxyRequestConfigDTO) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "executeRequest", + file: this.fileName, + params: { data }, + }); try { const { data: res } = await apiClient.actionsV2.executeActionProxyV2({ body: data as unknown as ActionProxyRequestConfigDTO, diff --git a/js/src/sdk/models/activeTriggers.ts b/js/src/sdk/models/activeTriggers.ts index cde2c76a476..40ea95310dd 100644 --- a/js/src/sdk/models/activeTriggers.ts +++ b/js/src/sdk/models/activeTriggers.ts @@ -2,6 +2,8 @@ import { GetActiveTriggersData } from "../client/types.gen"; import apiClient from "../client/client"; import { BackendClient } from "./backendClient"; import { CEG } from "../utils/error"; +import { TELEMETRY_LOGGER } from "../utils/telemetry"; +import { TELEMETRY_EVENTS } from "../utils/telemetry/events"; type TActiveTrigger = { id: string; @@ -18,7 +20,7 @@ type TActiveTrigger = { export class ActiveTriggers { backendClient: BackendClient; - + fileName: string = "js/src/sdk/models/activeTriggers.ts"; constructor(backendClient: BackendClient) { this.backendClient = backendClient; } @@ -32,6 +34,11 @@ export class ActiveTriggers { * @throws {ApiError} If the request fails. */ async get({ triggerId }: { triggerId: string }) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "get", + file: this.fileName, + params: { triggerId }, + }); try { const { data } = await apiClient.triggers.getActiveTriggers({ query: { @@ -54,6 +61,11 @@ export class ActiveTriggers { * @throws {ApiError} If the request fails. */ async list(data: GetActiveTriggersData = {}) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "list", + file: this.fileName, + params: { data }, + }); try { const { data: response } = await apiClient.triggers.getActiveTriggers({ query: data, @@ -74,6 +86,11 @@ export class ActiveTriggers { * @throws {ApiError} If the request fails. */ async enable(data: { triggerId: string }): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "enable", + file: this.fileName, + params: { data }, + }); try { await apiClient.triggers.switchTriggerInstanceStatus({ path: data, @@ -88,6 +105,11 @@ export class ActiveTriggers { } async disable(data: { triggerId: string }) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "disable", + file: this.fileName, + params: { data }, + }); try { await apiClient.triggers.switchTriggerInstanceStatus({ path: data, diff --git a/js/src/sdk/models/apps.ts b/js/src/sdk/models/apps.ts index d95f33a249f..41df61779cb 100644 --- a/js/src/sdk/models/apps.ts +++ b/js/src/sdk/models/apps.ts @@ -1,6 +1,8 @@ import { AppListResDTO, SingleAppInfoResDTO } from "../client"; import apiClient from "../client/client"; import { CEG } from "../utils/error"; +import { TELEMETRY_LOGGER } from "../utils/telemetry"; +import { TELEMETRY_EVENTS } from "../utils/telemetry/events"; import { BackendClient } from "./backendClient"; @@ -25,6 +27,7 @@ export type RequiredParamsFullResponse = { export class Apps { backendClient: BackendClient; + fileName: string = "js/src/sdk/models/apps.ts"; constructor(backendClient: BackendClient) { this.backendClient = backendClient; } @@ -38,6 +41,11 @@ export class Apps { * @throws {ApiError} If the request fails. */ async list() { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "list", + file: this.fileName, + params: {}, + }); try { const { data } = await apiClient.apps.getApps(); return data?.items || []; @@ -56,6 +64,11 @@ export class Apps { * @throws {ApiError} If the request fails. */ async get(data: GetAppData) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "get", + file: this.fileName, + params: { data }, + }); try { const { data: response } = await apiClient.apps.getApp({ path: { @@ -70,6 +83,11 @@ export class Apps { } async getRequiredParams(appId: string): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getRequiredParams", + file: this.fileName, + params: { appId }, + }); try { const appData = await this.get({ appKey: appId }); if (!appData) throw new Error("App not found"); @@ -128,6 +146,11 @@ export class Apps { appId: string; authScheme: string; }): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getRequiredParamsForAuthScheme", + file: this.fileName, + params: { appId, authScheme }, + }); try { const params = await this.getRequiredParams(appId); return params.authSchemes[authScheme]; diff --git a/js/src/sdk/models/connectedAccounts.ts b/js/src/sdk/models/connectedAccounts.ts index 3384d8ccd68..e3c102254b2 100644 --- a/js/src/sdk/models/connectedAccounts.ts +++ b/js/src/sdk/models/connectedAccounts.ts @@ -13,6 +13,8 @@ import { Integrations } from "./integrations"; import { Apps } from "./apps"; import { CEG } from "../utils/error"; import { SDK_ERROR_CODES } from "../utils/errors/src/constants"; +import { TELEMETRY_LOGGER } from "../utils/telemetry"; +import { TELEMETRY_EVENTS } from "../utils/telemetry/events"; type ConnectedAccountsListData = GetConnectionsData["query"] & { appNames?: string; @@ -33,6 +35,7 @@ export class ConnectedAccounts { backendClient: BackendClient; integrations: Integrations; apps: Apps; + fileName: string = "js/src/sdk/models/connectedAccounts.ts"; constructor(backendClient: BackendClient) { this.backendClient = backendClient; @@ -43,6 +46,11 @@ export class ConnectedAccounts { async list( data: ConnectedAccountsListData ): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "list", + file: this.fileName, + params: { data }, + }); try { const res = await apiClient.connections.getConnections({ query: data }); return res.data!; @@ -52,6 +60,11 @@ export class ConnectedAccounts { } async create(data: InitiateConnectionPayloadDto) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "create", + file: this.fileName, + params: { data }, + }); try { const { data: res } = (await apiClient.connections.initiateConnection({ body: data, @@ -68,6 +81,11 @@ export class ConnectedAccounts { } async get(data: { connectedAccountId: string }) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "get", + file: this.fileName, + params: { data }, + }); try { const res = await apiClient.connections.getConnection({ path: data }); return res.data; @@ -77,6 +95,11 @@ export class ConnectedAccounts { } async delete(data: { connectedAccountId: string }) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "delete", + file: this.fileName, + params: { data }, + }); try { const res = await apiClient.connections.deleteConnection({ path: data }); return res.data; @@ -86,6 +109,11 @@ export class ConnectedAccounts { } async getAuthParams(data: { connectedAccountId: string }) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getAuthParams", + file: this.fileName, + params: { data }, + }); try { const res = await apiClient.connections.getConnection({ path: { connectedAccountId: data.connectedAccountId }, @@ -99,6 +127,11 @@ export class ConnectedAccounts { async initiate( payload: InitiateConnectionDataReq ): Promise { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "initiate", + file: this.fileName, + params: { payload }, + }); try { let { integrationId, diff --git a/js/src/sdk/models/integrations.ts b/js/src/sdk/models/integrations.ts index f731c684533..34fd4b430f1 100644 --- a/js/src/sdk/models/integrations.ts +++ b/js/src/sdk/models/integrations.ts @@ -7,6 +7,8 @@ import { import apiClient from "../client/client"; import { BackendClient } from "./backendClient"; import { CEG } from "../utils/error"; +import { TELEMETRY_LOGGER } from "../utils/telemetry"; +import { TELEMETRY_EVENTS } from "../utils/telemetry/events"; export type ListAllIntegrationsData = { /** @@ -89,6 +91,7 @@ export type CreateIntegrationData = { export class Integrations { backendClient: BackendClient; + fileName: string = "js/src/sdk/models/integrations.ts"; constructor(backendClient: BackendClient) { this.backendClient = backendClient; @@ -103,6 +106,11 @@ export class Integrations { * @throws {ApiError} If the request fails. */ async list(data: ListAllIntegrationsData = {}) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "list", + file: this.fileName, + params: { data }, + }); try { const response = await apiClient.appConnector.listAllConnectors({ query: data, @@ -124,6 +132,11 @@ export class Integrations { * @throws {ApiError} If the request fails. */ async get(data: GetIntegrationData) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "get", + file: this.fileName, + params: { data }, + }); try { const response = await apiClient.appConnector.getConnectorInfo({ path: data, @@ -135,6 +148,11 @@ export class Integrations { } async getRequiredParams(integrationId: string) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "getRequiredParams", + file: this.fileName, + params: { integrationId }, + }); try { const response = await apiClient.appConnector.getConnectorInfo({ path: { @@ -158,6 +176,11 @@ export class Integrations { * @throws {ApiError} If the request fails. */ async create(data: CreateIntegrationData["requestBody"]) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "create", + file: this.fileName, + params: { data }, + }); try { if (!data?.authConfig) { data!.authConfig = {}; @@ -181,6 +204,11 @@ export class Integrations { } async delete(data: DeleteConnectorData) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "delete", + file: this.fileName, + params: { data }, + }); try { const response = await apiClient.appConnector.deleteConnector(data); return response.data; diff --git a/js/src/sdk/models/triggers.ts b/js/src/sdk/models/triggers.ts index 25599b36f50..cf3ee61cd27 100644 --- a/js/src/sdk/models/triggers.ts +++ b/js/src/sdk/models/triggers.ts @@ -6,6 +6,8 @@ import apiClient from "../client/client"; import { CEG } from "../utils/error"; import { ListTriggersData } from "../client"; +import { TELEMETRY_LOGGER } from "../utils/telemetry"; +import { TELEMETRY_EVENTS } from "../utils/telemetry/events"; type RequiredQuery = ListTriggersData["query"]; @@ -13,6 +15,7 @@ export class Triggers { trigger_to_client_event = "trigger_to_client"; backendClient: BackendClient; + fileName: string = "js/src/sdk/models/triggers.ts"; constructor(backendClient: BackendClient) { this.backendClient = backendClient; } @@ -27,6 +30,11 @@ export class Triggers { * @throws {ApiError} If the request fails. */ async list(data: RequiredQuery = {}) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "list", + file: this.fileName, + params: { data }, + }); try { const { data: response } = await apiClient.triggers.listTriggers({ query: { @@ -55,6 +63,11 @@ export class Triggers { triggerName: string; config: Record; }): Promise<{ status: string; triggerId: string }> { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "setup", + file: this.fileName, + params: { connectedAccountId, triggerName, config }, + }); try { const response = await apiClient.triggers.enableTrigger({ path: { @@ -72,6 +85,11 @@ export class Triggers { } async enable(data: { triggerId: string }) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "enable", + file: this.fileName, + params: { data }, + }); try { const response = await apiClient.triggers.switchTriggerInstanceStatus({ path: data, @@ -88,6 +106,11 @@ export class Triggers { } async disable(data: { triggerId: string }) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "disable", + file: this.fileName, + params: { data }, + }); try { const response = await apiClient.triggers.switchTriggerInstanceStatus({ path: data, @@ -104,6 +127,11 @@ export class Triggers { } async delete(data: { triggerInstanceId: string }) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "delete", + file: this.fileName, + params: { data }, + }); try { const response = await apiClient.triggers.deleteTrigger({ path: data, @@ -128,6 +156,11 @@ export class Triggers { entityId?: string; } = {} ) { + TELEMETRY_LOGGER.manualTelemetry(TELEMETRY_EVENTS.SDK_METHOD_INVOKED, { + method: "subscribe", + file: this.fileName, + params: { filters }, + }); if (!fn) throw new Error("Function is required for trigger subscription"); //@ts-ignore const clientId = await this.backendClient.getClientId(); diff --git a/js/src/sdk/utils/common.ts b/js/src/sdk/utils/common.ts index 06c1b4d883a..e727420bb2d 100644 --- a/js/src/sdk/utils/common.ts +++ b/js/src/sdk/utils/common.ts @@ -1,6 +1,13 @@ // Helper function to stringify objects if needed export const serializeValue = ( - obj: Record | string | number | boolean | null | undefined + obj: + | Record + | Array> + | string + | number + | boolean + | null + | undefined ) => { return typeof obj === "object" ? JSON.stringify(obj) : obj; }; diff --git a/js/src/sdk/utils/errors/index.ts b/js/src/sdk/utils/errors/index.ts index 7427b55b00f..664d99f4bb2 100644 --- a/js/src/sdk/utils/errors/index.ts +++ b/js/src/sdk/utils/errors/index.ts @@ -15,9 +15,9 @@ type ErrorPayload = { }; export async function logError(payload: ErrorPayload) { - const isTelementryDisabled = + const isTelemetryDisabled = getEnvVariable("TELEMETRY_DISABLED", "false") === "true"; - if (isTelementryDisabled) { + if (isTelemetryDisabled) { return; } try { diff --git a/js/src/sdk/utils/telemetry/index.ts b/js/src/sdk/utils/telemetry/index.ts index 57671423a28..54be3020d49 100644 --- a/js/src/sdk/utils/telemetry/index.ts +++ b/js/src/sdk/utils/telemetry/index.ts @@ -30,14 +30,17 @@ export class TELEMETRY_LOGGER { } private static async sendTelemetry(payload: Record[]) { - const isTelementryDisabled = + const isTelemetryDisabled = getEnvVariable("TELEMETRY_DISABLED", "false") === "true"; - if (isTelementryDisabled) { + + if (isTelemetryDisabled) { return; } + const url = `${TELEMETRY_URL}/api/sdk_metrics/telemetry`; + const reqPayload = { - data: { events: payload }, + data: payload, url, method: "POST", headers: { "Content-Type": "application/json" }, @@ -51,15 +54,6 @@ export class TELEMETRY_LOGGER { } } - static wrapClassMethodsForTelemetry(classInstance: any, methods: string[]) { - methods.forEach((method) => { - classInstance[method] = TELEMETRY_LOGGER.createTelemetryWrapper( - classInstance[method], - classInstance.constructor.name - ); - }); - } - static manualTelemetry(eventName: string, data: Record) { const payload = { eventName, diff --git a/js/src/utils/external.ts b/js/src/utils/external.ts index c4783ff09ff..6720f0c14be 100644 --- a/js/src/utils/external.ts +++ b/js/src/utils/external.ts @@ -3,6 +3,14 @@ import { IS_DEVELOPMENT_OR_CI, TELEMETRY_URL } from "../sdk/utils/constants"; import { serializeValue } from "../sdk/utils/common"; import logger from "./logger"; +type AcceptableJSONValue = + | Record + | Array> + | string + | number + | boolean + | null + | undefined; /** * Sends a reporting payload to the telemetry server using a child process. * This function is intended for use in Node.js environments. @@ -13,7 +21,7 @@ export function sendProcessReq(info: { url: string; method: string; headers: Record; - data: Record; + data: AcceptableJSONValue; }) { if (IS_DEVELOPMENT_OR_CI) { console.log( @@ -80,7 +88,7 @@ export function sendBrowserReq(info: { url: string; method: string; headers: Record; - data: Record; + data: AcceptableJSONValue; }) { if (IS_DEVELOPMENT_OR_CI) { logger.debug(