chore: Distributed tracing for client (#37101)

This commit is contained in:
Nidhi 2024-10-29 11:25:43 +05:30 committed by GitHub
parent 64f1342a40
commit 27bdeb92b6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 197 additions and 76 deletions

View File

@ -99,6 +99,10 @@ module.exports = {
"__APPSMITH_NEW_RELIC_OTEL_EXPORTER_OTLP_ENDPOINT__",
),
},
observability: {
deploymentName: "jest-run",
serviceInstanceId: "appsmith-0",
},
fusioncharts: {
licenseKey: parseConfig("__APPSMITH_FUSIONCHARTS_LICENSE_KEY__"),
},

View File

@ -72,6 +72,7 @@
"@mantine/hooks": "^5.10.1",
"@newrelic/browser-agent": "^1.255.0",
"@opentelemetry/api": "^1.9.0",
"@opentelemetry/auto-instrumentations-web": "^0.41.0",
"@opentelemetry/context-zone": "1.25.1",
"@opentelemetry/core": "^1.26.0",
"@opentelemetry/exporter-metrics-otlp-http": "0.52.1",
@ -81,7 +82,7 @@
"@opentelemetry/sdk-metrics": "1.25.1",
"@opentelemetry/sdk-trace-base": "1.25.1",
"@opentelemetry/sdk-trace-web": "1.25.1",
"@opentelemetry/semantic-conventions": "1.25.1",
"@opentelemetry/semantic-conventions": "^1.27.0",
"@react-spring/web": "^9.7.4",
"@react-types/shared": "^3.23.0",
"@redux-saga/core": "1.1.3",

View File

@ -228,6 +228,10 @@
apiKey: parseConfig('{{env "APPSMITH_SEGMENT_KEY"}}'),
ceKey: parseConfig('{{env "APPSMITH_SEGMENT_CE_KEY"}}'),
},
observability: {
deploymentName: parseConfig('{{env "APPSMITH_DEPLOYMENT_NAME"}}') || "self-hosted",
serviceInstanceId: parseConfig('{{env "HOSTNAME"}}') || "appsmith-0",
},
newRelic:{
enableNewRelic: parseConfig('{{env "APPSMITH_NEW_RELIC_ACCOUNT_ENABLE"}}'),
accountId: parseConfig('{{env "APPSMITH_NEW_RELIC_ACCOUNT_ID"}}'),

View File

@ -4,12 +4,11 @@ import { ZoneContextManager } from "@opentelemetry/context-zone";
import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
import { Resource } from "@opentelemetry/resources";
import {
SEMRESATTRS_SERVICE_NAME,
SEMRESATTRS_SERVICE_VERSION,
SEMRESATTRS_SERVICE_INSTANCE_ID,
} from "@opentelemetry/semantic-conventions";
ATTR_DEPLOYMENT_NAME,
ATTR_SERVICE_INSTANCE_ID,
} from "@opentelemetry/semantic-conventions/incubating";
import { ATTR_SERVICE_NAME } from "@opentelemetry/semantic-conventions";
import { getAppsmithConfigs } from "ee/configs";
import { W3CTraceContextPropagator } from "@opentelemetry/core";
import {
MeterProvider,
PeriodicExportingMetricReader,
@ -18,23 +17,19 @@ import {
OTLPMetricExporter,
AggregationTemporalityPreference,
} from "@opentelemetry/exporter-metrics-otlp-http";
import type { Context, TextMapSetter } from "@opentelemetry/api";
import { metrics } from "@opentelemetry/api";
import { registerInstrumentations } from "@opentelemetry/instrumentation";
import { PageLoadInstrumentation } from "./PageLoadInstrumentation";
import { getWebAutoInstrumentations } from "@opentelemetry/auto-instrumentations-web";
enum CompressionAlgorithm {
NONE = "none",
GZIP = "gzip",
}
const { newRelic } = getAppsmithConfigs();
const {
applicationId,
browserAgentEndpoint,
otlpEndpoint,
otlpLicenseKey,
otlpServiceName,
} = newRelic;
const { newRelic, observability } = getAppsmithConfigs();
const { browserAgentEndpoint, otlpEndpoint, otlpLicenseKey } = newRelic;
const { deploymentName, serviceInstanceId, serviceName } = observability;
// This base domain is used to filter out the Smartlook requests from the browser agent
// There are some requests made to subdomains of smartlook.cloud which will also be filtered out
@ -42,9 +37,9 @@ const smartlookBaseDomain = "smartlook.cloud";
const tracerProvider = new WebTracerProvider({
resource: new Resource({
[SEMRESATTRS_SERVICE_NAME]: otlpServiceName,
[SEMRESATTRS_SERVICE_INSTANCE_ID]: applicationId,
[SEMRESATTRS_SERVICE_VERSION]: "1.0.0",
[ATTR_DEPLOYMENT_NAME]: deploymentName,
[ATTR_SERVICE_INSTANCE_ID]: serviceInstanceId,
[ATTR_SERVICE_NAME]: serviceName,
}),
});
@ -71,32 +66,9 @@ const processor = new BatchSpanProcessor(
},
);
const W3C_OTLP_TRACE_HEADER = "traceparent";
const CUSTOM_OTLP_TRACE_HEADER = "traceparent-otlp";
//We are overriding the default header "traceparent" used for trace context because the browser
// agent shares the same header's distributed tracing
class CustomW3CTraceContextPropagator extends W3CTraceContextPropagator {
inject(
context: Context,
carrier: Record<string, unknown>,
setter: TextMapSetter,
) {
// Call the original inject method to get the default traceparent header
super.inject(context, carrier, setter);
// Modify the carrier to use a different header
if (carrier[W3C_OTLP_TRACE_HEADER]) {
carrier[CUSTOM_OTLP_TRACE_HEADER] = carrier[W3C_OTLP_TRACE_HEADER];
delete carrier[W3C_OTLP_TRACE_HEADER]; // Remove the original traceparent header
}
}
}
tracerProvider.addSpanProcessor(processor);
tracerProvider.register({
contextManager: new ZoneContextManager(),
propagator: new CustomW3CTraceContextPropagator(),
});
const nrMetricsExporter = new OTLPMetricExporter({
@ -110,9 +82,9 @@ const nrMetricsExporter = new OTLPMetricExporter({
const meterProvider = new MeterProvider({
resource: new Resource({
[SEMRESATTRS_SERVICE_NAME]: otlpServiceName,
[SEMRESATTRS_SERVICE_INSTANCE_ID]: applicationId,
[SEMRESATTRS_SERVICE_VERSION]: "1.0.0",
[ATTR_DEPLOYMENT_NAME]: deploymentName,
[ATTR_SERVICE_INSTANCE_ID]: serviceInstanceId,
[ATTR_SERVICE_NAME]: serviceName,
}),
readers: [
new PeriodicExportingMetricReader({
@ -136,5 +108,10 @@ registerInstrumentations({
smartlookBaseDomain,
],
}),
getWebAutoInstrumentations({
"@opentelemetry/instrumentation-xml-http-request": {
enabled: true,
},
}),
],
});

View File

@ -122,14 +122,6 @@ export const startAndEndSpanForFn = <T>(
return res;
};
// TODO: Fix this the next time the file is edited
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function wrapFnWithParentTraceContext(parentSpan: Span, fn: () => any) {
const parentContext = trace.setSpan(context.active(), parentSpan);
return context.with(parentContext, fn);
}
export function startAndEndSpan(
spanName: string,
startTime: number,

View File

@ -8,8 +8,6 @@ import axios from "axios";
import type { Action, ActionViewMode } from "entities/Action";
import type { APIRequest } from "constants/AppsmithActionConstants/ActionConstants";
import type { WidgetType } from "constants/WidgetConstants";
import type { OtlpSpan } from "UITelemetry/generateTraces";
import { wrapFnWithParentTraceContext } from "UITelemetry/generateTraces";
import type { ActionParentEntityTypeInterface } from "ee/entities/Engine/actionHelpers";
export interface Property {
@ -233,17 +231,10 @@ class ActionAPI extends API {
static async executeAction(
executeAction: FormData,
timeout?: number,
parentSpan?: OtlpSpan,
): Promise<AxiosPromise<ActionExecutionResponse>> {
ActionAPI.abortActionExecutionTokenSource = axios.CancelToken.source();
if (!parentSpan) {
return this.executeApiCall(executeAction, timeout);
}
return wrapFnWithParentTraceContext(parentSpan, async () => {
return await this.executeApiCall(executeAction, timeout);
});
return await this.executeApiCall(executeAction, timeout);
}
static async moveAction(moveRequest: MoveActionRequest) {

View File

@ -13,6 +13,10 @@ export interface INJECTED_CONFIGS {
apiKey: string;
ceKey: string;
};
observability: {
deploymentName: string;
serviceInstanceId: string;
};
newRelic: {
enableNewRelic: boolean;
accountId: string;
@ -20,7 +24,6 @@ export interface INJECTED_CONFIGS {
browserAgentlicenseKey: string;
browserAgentEndpoint: string;
otlpLicenseKey: string;
otlpServiceName: string;
otlpEndpoint: string;
};
fusioncharts: {
@ -92,6 +95,10 @@ export const getConfigsFromEnvVars = (): INJECTED_CONFIGS => {
indexName: process.env.REACT_APP_ALGOLIA_SEARCH_INDEX_NAME || "",
snippetIndex: process.env.REACT_APP_ALGOLIA_SNIPPET_INDEX_NAME || "",
},
observability: {
deploymentName: process.env.APPSMITH_DEPLOYMENT_NAME || "self-hosted",
serviceInstanceId: process.env.HOSTNAME || "appsmith-0",
},
newRelic: {
enableNewRelic: !!process.env.APPSMITH_NEW_RELIC_ACCOUNT_ENABLE,
accountId: process.env.APPSMITH_NEW_RELIC_ACCOUNT_ID || "",
@ -102,8 +109,6 @@ export const getConfigsFromEnvVars = (): INJECTED_CONFIGS => {
process.env.APPSMITH_NEW_RELIC_BROWSER_AGENT_ENDPOINT || "",
otlpLicenseKey: process.env.APPSMITH_NEW_RELIC_OTLP_LICENSE_KEY || "",
otlpEndpoint: process.env.APPSMITH_NEW_RELIC_OTEL_SERVICE_NAME || "",
otlpServiceName:
process.env.APPSMITH_NEW_RELIC_OTEL_EXPORTER_OTLP_ENDPOINT || "",
},
logLevel:
(process.env.REACT_APP_CLIENT_LOG_LEVEL as
@ -171,6 +176,14 @@ export const getAppsmithConfigs = (): AppsmithUIConfigs => {
ENV_CONFIG.mixpanel.apiKey,
APPSMITH_FEATURE_CONFIGS?.mixpanel.apiKey,
);
const observabilityDeploymentName = getConfig(
ENV_CONFIG.observability.deploymentName,
APPSMITH_FEATURE_CONFIGS?.observability.deploymentName,
);
const observabilityServiceInstanceId = getConfig(
ENV_CONFIG.observability.serviceInstanceId,
APPSMITH_FEATURE_CONFIGS?.observability.serviceInstanceId,
);
const newRelicAccountId = getConfig(
ENV_CONFIG.newRelic.accountId,
APPSMITH_FEATURE_CONFIGS?.newRelic.accountId,
@ -191,11 +204,6 @@ export const getAppsmithConfigs = (): AppsmithUIConfigs => {
ENV_CONFIG.newRelic.otlpLicenseKey,
APPSMITH_FEATURE_CONFIGS?.newRelic.otlpLicenseKey,
);
const newRelicOtlpServiceName = getConfig(
ENV_CONFIG.newRelic.otlpServiceName,
APPSMITH_FEATURE_CONFIGS?.newRelic.otlpServiceName,
);
const newRelicOtlpEndpoint = getConfig(
ENV_CONFIG.newRelic.otlpEndpoint,
APPSMITH_FEATURE_CONFIGS?.newRelic.otlpEndpoint,
@ -271,7 +279,11 @@ export const getAppsmithConfigs = (): AppsmithUIConfigs => {
browserAgentEndpoint: newRelicBrowserAgentEndpoint.value,
otlpLicenseKey: newRelicOtlpLicenseKey.value,
otlpEndpoint: newRelicOtlpEndpoint.value,
otlpServiceName: newRelicOtlpServiceName.value,
},
observability: {
deploymentName: observabilityDeploymentName.value,
serviceInstanceId: observabilityServiceInstanceId.value,
serviceName: "frontend",
},
fusioncharts: {
enabled: fusioncharts.enabled,

View File

@ -20,6 +20,11 @@ export interface AppsmithUIConfigs {
enabled: boolean;
id: string;
};
observability: {
deploymentName: string;
serviceInstanceId: string;
serviceName: string;
};
newRelic: {
enableNewRelic: boolean;
accountId: string;
@ -27,7 +32,6 @@ export interface AppsmithUIConfigs {
browserAgentlicenseKey: string;
browserAgentEndpoint: string;
otlpLicenseKey: string;
otlpServiceName: string;
otlpEndpoint: string;
};
segment: {

View File

@ -1436,7 +1436,7 @@ function* executePluginActionSaga(
let response: ActionExecutionResponse;
try {
response = yield ActionAPI.executeAction(formData, timeout, parentSpan);
response = yield ActionAPI.executeAction(formData, timeout);
const isError = isErrorResponse(response);

View File

@ -4786,6 +4786,22 @@ __metadata:
languageName: node
linkType: hard
"@opentelemetry/auto-instrumentations-web@npm:^0.41.0":
version: 0.41.0
resolution: "@opentelemetry/auto-instrumentations-web@npm:0.41.0"
dependencies:
"@opentelemetry/instrumentation": ^0.53.0
"@opentelemetry/instrumentation-document-load": ^0.40.0
"@opentelemetry/instrumentation-fetch": ^0.53.0
"@opentelemetry/instrumentation-user-interaction": ^0.40.0
"@opentelemetry/instrumentation-xml-http-request": ^0.53.0
peerDependencies:
"@opentelemetry/api": ^1.3.0
zone.js: ^0.11.4 || ^0.13.0 || ^0.14.0
checksum: 9e73bc3654bfe325154a2e26d713033a3a6c1e4341a5f3803af75b5c945d1844e2f83b129b42c69b660ca9caf5f16b666c12143ac51744c8d12ea550d29935d5
languageName: node
linkType: hard
"@opentelemetry/context-async-hooks@npm:1.26.0":
version: 1.26.0
resolution: "@opentelemetry/context-async-hooks@npm:1.26.0"
@ -4826,7 +4842,7 @@ __metadata:
languageName: node
linkType: hard
"@opentelemetry/core@npm:1.26.0, @opentelemetry/core@npm:^1.26.0":
"@opentelemetry/core@npm:1.26.0":
version: 1.26.0
resolution: "@opentelemetry/core@npm:1.26.0"
dependencies:
@ -4837,6 +4853,17 @@ __metadata:
languageName: node
linkType: hard
"@opentelemetry/core@npm:1.27.0, @opentelemetry/core@npm:^1.26.0, @opentelemetry/core@npm:^1.8.0":
version: 1.27.0
resolution: "@opentelemetry/core@npm:1.27.0"
dependencies:
"@opentelemetry/semantic-conventions": 1.27.0
peerDependencies:
"@opentelemetry/api": ">=1.0.0 <1.10.0"
checksum: 33ff551f89f0bb95830c9f9464c43b11adf88882ec1d3a03a5b9afcc89d2aafab33c36cb5047f18667d7929d6ab40ed0121649c42d0105f1cb33ffdca48f8b13
languageName: node
linkType: hard
"@opentelemetry/exporter-metrics-otlp-http@npm:0.52.1":
version: 0.52.1
resolution: "@opentelemetry/exporter-metrics-otlp-http@npm:0.52.1"
@ -4867,6 +4894,35 @@ __metadata:
languageName: node
linkType: hard
"@opentelemetry/instrumentation-document-load@npm:^0.40.0":
version: 0.40.0
resolution: "@opentelemetry/instrumentation-document-load@npm:0.40.0"
dependencies:
"@opentelemetry/core": ^1.8.0
"@opentelemetry/instrumentation": ^0.53.0
"@opentelemetry/sdk-trace-base": ^1.0.0
"@opentelemetry/sdk-trace-web": ^1.15.0
"@opentelemetry/semantic-conventions": ^1.27.0
peerDependencies:
"@opentelemetry/api": ^1.3.0
checksum: 5a06eeb5b68623c655fa728cc2bb036cdd0270488abfa1fca5e733891f3ce5b22067b014c4f3317e957be3c89acab5c70f199eb82c409dd01605960908c34048
languageName: node
linkType: hard
"@opentelemetry/instrumentation-fetch@npm:^0.53.0":
version: 0.53.0
resolution: "@opentelemetry/instrumentation-fetch@npm:0.53.0"
dependencies:
"@opentelemetry/core": 1.26.0
"@opentelemetry/instrumentation": 0.53.0
"@opentelemetry/sdk-trace-web": 1.26.0
"@opentelemetry/semantic-conventions": 1.27.0
peerDependencies:
"@opentelemetry/api": ^1.0.0
checksum: 2c92c9ccccfa424adb3773424df42d64156b67bdbcc1a21fbe5f620370d68bbd64701279897a0807e0b259b4e7a9fdcfdc21fa064343793c592bd0d08c5483cf
languageName: node
linkType: hard
"@opentelemetry/instrumentation-http@npm:^0.53.0":
version: 0.53.0
resolution: "@opentelemetry/instrumentation-http@npm:0.53.0"
@ -4881,6 +4937,34 @@ __metadata:
languageName: node
linkType: hard
"@opentelemetry/instrumentation-user-interaction@npm:^0.40.0":
version: 0.40.0
resolution: "@opentelemetry/instrumentation-user-interaction@npm:0.40.0"
dependencies:
"@opentelemetry/core": ^1.8.0
"@opentelemetry/instrumentation": ^0.53.0
"@opentelemetry/sdk-trace-web": ^1.8.0
peerDependencies:
"@opentelemetry/api": ^1.3.0
zone.js: ^0.11.4 || ^0.13.0 || ^0.14.0
checksum: 24ae06b6a6ab2df39dc1074e7edf8ddaa2009e0376bf5e2bcb5d355bdf96bb4aeb09dc861a110150702a251d30e9984ee2a0bd7ba57e820e0859977f5807f369
languageName: node
linkType: hard
"@opentelemetry/instrumentation-xml-http-request@npm:^0.53.0":
version: 0.53.0
resolution: "@opentelemetry/instrumentation-xml-http-request@npm:0.53.0"
dependencies:
"@opentelemetry/core": 1.26.0
"@opentelemetry/instrumentation": 0.53.0
"@opentelemetry/sdk-trace-web": 1.26.0
"@opentelemetry/semantic-conventions": 1.27.0
peerDependencies:
"@opentelemetry/api": ^1.0.0
checksum: 61dd00e30fbf4de611a7d1fa63aa8b004a0624c566d043dc9970dcaaef8eeb1f67e39a224bffd0d05c437e0d08371ee569f1d273429c05eb155e8c854e3fa818
languageName: node
linkType: hard
"@opentelemetry/instrumentation@npm:0.52.1":
version: 0.52.1
resolution: "@opentelemetry/instrumentation@npm:0.52.1"
@ -4897,7 +4981,7 @@ __metadata:
languageName: node
linkType: hard
"@opentelemetry/instrumentation@npm:0.53.0":
"@opentelemetry/instrumentation@npm:0.53.0, @opentelemetry/instrumentation@npm:^0.53.0":
version: 0.53.0
resolution: "@opentelemetry/instrumentation@npm:0.53.0"
dependencies:
@ -4988,6 +5072,18 @@ __metadata:
languageName: node
linkType: hard
"@opentelemetry/resources@npm:1.27.0":
version: 1.27.0
resolution: "@opentelemetry/resources@npm:1.27.0"
dependencies:
"@opentelemetry/core": 1.27.0
"@opentelemetry/semantic-conventions": 1.27.0
peerDependencies:
"@opentelemetry/api": ">=1.0.0 <1.10.0"
checksum: 43d298afea7daf7524e6b98c1441bcce9fa73b76aecf17e36cabb1a4cfaae6818acf9759d3e42706b1fd91243644076d2291e78c3ed81641d3b351fcff6cb9a9
languageName: node
linkType: hard
"@opentelemetry/sdk-logs@npm:0.52.1":
version: 0.52.1
resolution: "@opentelemetry/sdk-logs@npm:0.52.1"
@ -5040,6 +5136,19 @@ __metadata:
languageName: node
linkType: hard
"@opentelemetry/sdk-trace-base@npm:1.27.0, @opentelemetry/sdk-trace-base@npm:^1.0.0":
version: 1.27.0
resolution: "@opentelemetry/sdk-trace-base@npm:1.27.0"
dependencies:
"@opentelemetry/core": 1.27.0
"@opentelemetry/resources": 1.27.0
"@opentelemetry/semantic-conventions": 1.27.0
peerDependencies:
"@opentelemetry/api": ">=1.0.0 <1.10.0"
checksum: d28c36724aeaf4884f7957e2ab138d9a0ca715a68b2ad23e2935ff0e39cd438c57fd0c8cc85fd5e280464857ede1ae8f9c8e40a37088a1e34d2e625e77276fee
languageName: node
linkType: hard
"@opentelemetry/sdk-trace-node@npm:^1.26.0":
version: 1.26.0
resolution: "@opentelemetry/sdk-trace-node@npm:1.26.0"
@ -5069,6 +5178,32 @@ __metadata:
languageName: node
linkType: hard
"@opentelemetry/sdk-trace-web@npm:1.26.0":
version: 1.26.0
resolution: "@opentelemetry/sdk-trace-web@npm:1.26.0"
dependencies:
"@opentelemetry/core": 1.26.0
"@opentelemetry/sdk-trace-base": 1.26.0
"@opentelemetry/semantic-conventions": 1.27.0
peerDependencies:
"@opentelemetry/api": ">=1.0.0 <1.10.0"
checksum: d8e0ae8f9088723fc250874290923dc81933b279958f04beb79ca7e312bf66a79b823d92dd06be4e707d6919030c2998f8a18167a47ee7281e573b3ef3cc9e10
languageName: node
linkType: hard
"@opentelemetry/sdk-trace-web@npm:^1.15.0, @opentelemetry/sdk-trace-web@npm:^1.8.0":
version: 1.27.0
resolution: "@opentelemetry/sdk-trace-web@npm:1.27.0"
dependencies:
"@opentelemetry/core": 1.27.0
"@opentelemetry/sdk-trace-base": 1.27.0
"@opentelemetry/semantic-conventions": 1.27.0
peerDependencies:
"@opentelemetry/api": ">=1.0.0 <1.10.0"
checksum: 7c5c354fc9400adef70e6f169edd61a11ebcd36ca15993b366e8f6cfb296f248786be41d327ca971ad4f24b6623a5b8af2fb88fd760af6419c6313a7288ed6f9
languageName: node
linkType: hard
"@opentelemetry/semantic-conventions@npm:1.25.1":
version: 1.25.1
resolution: "@opentelemetry/semantic-conventions@npm:1.25.1"
@ -12743,6 +12878,7 @@ __metadata:
"@newrelic/browser-agent": ^1.255.0
"@octokit/rest": ^20.0.1
"@opentelemetry/api": ^1.9.0
"@opentelemetry/auto-instrumentations-web": ^0.41.0
"@opentelemetry/context-zone": 1.25.1
"@opentelemetry/core": ^1.26.0
"@opentelemetry/exporter-metrics-otlp-http": 0.52.1
@ -12752,7 +12888,7 @@ __metadata:
"@opentelemetry/sdk-metrics": 1.25.1
"@opentelemetry/sdk-trace-base": 1.25.1
"@opentelemetry/sdk-trace-web": 1.25.1
"@opentelemetry/semantic-conventions": 1.25.1
"@opentelemetry/semantic-conventions": ^1.27.0
"@peculiar/webcrypto": ^1.4.3
"@react-spring/web": ^9.7.4
"@react-types/shared": ^3.23.0