Skip to content

Commit 2b343f7

Browse files
committed
Increase otel attribute limits and make them configurable
1 parent 704aceb commit 2b343f7

File tree

6 files changed

+183
-23
lines changed

6 files changed

+183
-23
lines changed

apps/webapp/app/env.server.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { z } from "zod";
22
import { isValidDatabaseUrl } from "./utils/db";
33
import { isValidRegex } from "./utils/regex";
44
import { BoolEnv } from "./utils/boolEnv";
5+
import { OTEL_ATTRIBUTE_PER_LINK_COUNT_LIMIT, OTEL_LINK_COUNT_LIMIT } from "@trigger.dev/core/v3";
56

67
const EnvironmentSchema = z.object({
78
NODE_ENV: z.union([z.literal("development"), z.literal("production"), z.literal("test")]),
@@ -276,6 +277,15 @@ const EnvironmentSchema = z.object({
276277
PROD_OTEL_LOG_EXPORT_TIMEOUT_MILLIS: z.string().default("30000"),
277278
PROD_OTEL_LOG_MAX_QUEUE_SIZE: z.string().default("512"),
278279

280+
TRIGGER_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT: z.string().default("256"),
281+
TRIGGER_OTEL_LOG_ATTRIBUTE_COUNT_LIMIT: z.string().default("256"),
282+
TRIGGER_OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT: z.string().default("131072"),
283+
TRIGGER_OTEL_LOG_ATTRIBUTE_VALUE_LENGTH_LIMIT: z.string().default("131072"),
284+
TRIGGER_OTEL_SPAN_EVENT_COUNT_LIMIT: z.string().default("10"),
285+
TRIGGER_OTEL_LINK_COUNT_LIMIT: z.string().default("2"),
286+
TRIGGER_OTEL_ATTRIBUTE_PER_LINK_COUNT_LIMIT: z.string().default("10"),
287+
TRIGGER_OTEL_ATTRIBUTE_PER_EVENT_COUNT_LIMIT: z.string().default("10"),
288+
279289
CHECKPOINT_THRESHOLD_IN_MS: z.coerce.number().int().default(30000),
280290

281291
// Internal OTEL environment variables

apps/webapp/app/v3/environmentVariables/environmentVariablesRepository.server.ts

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -810,6 +810,7 @@ export const RuntimeEnvironmentForEnvRepoPayload = {
810810
apiKey: true,
811811
organizationId: true,
812812
branchName: true,
813+
builtInEnvironmentVariableOverrides: true,
813814
},
814815
} as const;
815816

@@ -1025,5 +1026,93 @@ async function resolveBuiltInProdVariables(
10251026
async function resolveCommonBuiltInVariables(
10261027
runtimeEnvironment: RuntimeEnvironmentForEnvRepo
10271028
): Promise<Array<EnvironmentVariable>> {
1028-
return [];
1029+
return [
1030+
{
1031+
key: "TRIGGER_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT",
1032+
value: resolveBuiltInEnvironmentVariableOverrides(
1033+
"TRIGGER_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT",
1034+
runtimeEnvironment,
1035+
String(env.TRIGGER_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT)
1036+
),
1037+
},
1038+
{
1039+
key: "TRIGGER_OTEL_LOG_ATTRIBUTE_COUNT_LIMIT",
1040+
value: resolveBuiltInEnvironmentVariableOverrides(
1041+
"TRIGGER_OTEL_LOG_ATTRIBUTE_COUNT_LIMIT",
1042+
runtimeEnvironment,
1043+
String(env.TRIGGER_OTEL_LOG_ATTRIBUTE_COUNT_LIMIT)
1044+
),
1045+
},
1046+
{
1047+
key: "TRIGGER_OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT",
1048+
value: resolveBuiltInEnvironmentVariableOverrides(
1049+
"TRIGGER_OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT",
1050+
runtimeEnvironment,
1051+
String(env.TRIGGER_OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT)
1052+
),
1053+
},
1054+
{
1055+
key: "TRIGGER_OTEL_LOG_ATTRIBUTE_VALUE_LENGTH_LIMIT",
1056+
value: resolveBuiltInEnvironmentVariableOverrides(
1057+
"TRIGGER_OTEL_LOG_ATTRIBUTE_VALUE_LENGTH_LIMIT",
1058+
runtimeEnvironment,
1059+
String(env.TRIGGER_OTEL_LOG_ATTRIBUTE_VALUE_LENGTH_LIMIT)
1060+
),
1061+
},
1062+
{
1063+
key: "TRIGGER_OTEL_SPAN_EVENT_COUNT_LIMIT",
1064+
value: resolveBuiltInEnvironmentVariableOverrides(
1065+
"TRIGGER_OTEL_SPAN_EVENT_COUNT_LIMIT",
1066+
runtimeEnvironment,
1067+
String(env.TRIGGER_OTEL_SPAN_EVENT_COUNT_LIMIT)
1068+
),
1069+
},
1070+
{
1071+
key: "TRIGGER_OTEL_LINK_COUNT_LIMIT",
1072+
value: resolveBuiltInEnvironmentVariableOverrides(
1073+
"TRIGGER_OTEL_LINK_COUNT_LIMIT",
1074+
runtimeEnvironment,
1075+
String(env.TRIGGER_OTEL_LINK_COUNT_LIMIT)
1076+
),
1077+
},
1078+
{
1079+
key: "TRIGGER_OTEL_ATTRIBUTE_PER_LINK_COUNT_LIMIT",
1080+
value: resolveBuiltInEnvironmentVariableOverrides(
1081+
"TRIGGER_OTEL_ATTRIBUTE_PER_LINK_COUNT_LIMIT",
1082+
runtimeEnvironment,
1083+
String(env.TRIGGER_OTEL_ATTRIBUTE_PER_LINK_COUNT_LIMIT)
1084+
),
1085+
},
1086+
{
1087+
key: "TRIGGER_OTEL_ATTRIBUTE_PER_EVENT_COUNT_LIMIT",
1088+
value: resolveBuiltInEnvironmentVariableOverrides(
1089+
"TRIGGER_OTEL_ATTRIBUTE_PER_EVENT_COUNT_LIMIT",
1090+
runtimeEnvironment,
1091+
String(env.TRIGGER_OTEL_ATTRIBUTE_PER_EVENT_COUNT_LIMIT)
1092+
),
1093+
},
1094+
];
1095+
}
1096+
1097+
function resolveBuiltInEnvironmentVariableOverrides(
1098+
key: string,
1099+
runtimeEnvironment: RuntimeEnvironmentForEnvRepo,
1100+
defaultValue: string
1101+
) {
1102+
const overrides = runtimeEnvironment.builtInEnvironmentVariableOverrides;
1103+
1104+
if (!overrides) {
1105+
return defaultValue;
1106+
}
1107+
1108+
if (
1109+
!Array.isArray(overrides) &&
1110+
typeof overrides === "object" &&
1111+
key in overrides &&
1112+
typeof overrides[key] === "string"
1113+
) {
1114+
return overrides[key];
1115+
}
1116+
1117+
return defaultValue;
10291118
}

apps/webapp/app/v3/otlpExporter.server.ts

Lines changed: 37 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ class OTLPExporter {
3939

4040
constructor(
4141
private readonly _eventRepository: EventRepository,
42-
private readonly _verbose: boolean
42+
private readonly _verbose: boolean,
43+
private readonly _spanAttributeValueLengthLimit: number
4344
) {
4445
this._tracer = trace.getTracer("otlp-exporter");
4546
}
@@ -52,7 +53,7 @@ class OTLPExporter {
5253
this.#logExportTracesVerbose(request);
5354

5455
const events = this.#filterResourceSpans(request.resourceSpans).flatMap((resourceSpan) => {
55-
return convertSpansToCreateableEvents(resourceSpan);
56+
return convertSpansToCreateableEvents(resourceSpan, this._spanAttributeValueLengthLimit);
5657
});
5758

5859
const enrichedEvents = enrichCreatableEvents(events);
@@ -79,7 +80,7 @@ class OTLPExporter {
7980
this.#logExportLogsVerbose(request);
8081

8182
const events = this.#filterResourceLogs(request.resourceLogs).flatMap((resourceLog) => {
82-
return convertLogsToCreateableEvents(resourceLog);
83+
return convertLogsToCreateableEvents(resourceLog, this._spanAttributeValueLengthLimit);
8384
});
8485

8586
const enrichedEvents = enrichCreatableEvents(events);
@@ -180,7 +181,10 @@ class OTLPExporter {
180181
}
181182
}
182183

183-
function convertLogsToCreateableEvents(resourceLog: ResourceLogs): Array<CreatableEvent> {
184+
function convertLogsToCreateableEvents(
185+
resourceLog: ResourceLogs,
186+
spanAttributeValueLengthLimit: number
187+
): Array<CreatableEvent> {
184188
const resourceAttributes = resourceLog.resource?.attributes ?? [];
185189

186190
const resourceProperties = extractEventProperties(resourceAttributes);
@@ -213,10 +217,10 @@ function convertLogsToCreateableEvents(resourceLog: ResourceLogs): Array<Creatab
213217
status: logLevelToEventStatus(log.severityNumber),
214218
startTime: log.timeUnixNano,
215219
properties: {
216-
...convertKeyValueItemsToMap(log.attributes ?? [], [
217-
SemanticInternalAttributes.SPAN_ID,
218-
SemanticInternalAttributes.SPAN_PARTIAL,
219-
]),
220+
...convertKeyValueItemsToMap(
221+
truncateAttributes(log.attributes ?? [], spanAttributeValueLengthLimit),
222+
[SemanticInternalAttributes.SPAN_ID, SemanticInternalAttributes.SPAN_PARTIAL]
223+
),
220224
},
221225
style: convertKeyValueItemsToMap(
222226
pickAttributes(log.attributes ?? [], SemanticInternalAttributes.STYLE),
@@ -283,7 +287,10 @@ function convertLogsToCreateableEvents(resourceLog: ResourceLogs): Array<Creatab
283287
});
284288
}
285289

286-
function convertSpansToCreateableEvents(resourceSpan: ResourceSpans): Array<CreatableEvent> {
290+
function convertSpansToCreateableEvents(
291+
resourceSpan: ResourceSpans,
292+
spanAttributeValueLengthLimit: number
293+
): Array<CreatableEvent> {
287294
const resourceAttributes = resourceSpan.resource?.attributes ?? [];
288295

289296
const resourceProperties = extractEventProperties(resourceAttributes);
@@ -323,10 +330,10 @@ function convertSpansToCreateableEvents(resourceSpan: ResourceSpans): Array<Crea
323330
events: spanEventsToEventEvents(span.events ?? []),
324331
duration: span.endTimeUnixNano - span.startTimeUnixNano,
325332
properties: {
326-
...convertKeyValueItemsToMap(span.attributes ?? [], [
327-
SemanticInternalAttributes.SPAN_ID,
328-
SemanticInternalAttributes.SPAN_PARTIAL,
329-
]),
333+
...convertKeyValueItemsToMap(
334+
truncateAttributes(span.attributes ?? [], spanAttributeValueLengthLimit),
335+
[SemanticInternalAttributes.SPAN_ID, SemanticInternalAttributes.SPAN_PARTIAL]
336+
),
330337
},
331338
style: convertKeyValueItemsToMap(
332339
pickAttributes(span.attributes ?? [], SemanticInternalAttributes.STYLE),
@@ -852,7 +859,23 @@ function binaryToHex(buffer: Buffer | string | undefined): string | undefined {
852859
return Buffer.from(Array.from(buffer)).toString("hex");
853860
}
854861

862+
function truncateAttributes(attributes: KeyValue[], maximumLength: number = 1024): KeyValue[] {
863+
return attributes.map((attribute) => {
864+
return isStringValue(attribute.value)
865+
? {
866+
key: attribute.key,
867+
value: {
868+
stringValue: attribute.value.stringValue.slice(0, maximumLength),
869+
},
870+
}
871+
: attribute;
872+
});
873+
}
874+
855875
export const otlpExporter = new OTLPExporter(
856876
eventRepository,
857-
process.env.OTLP_EXPORTER_VERBOSE === "1"
877+
process.env.OTLP_EXPORTER_VERBOSE === "1",
878+
process.env.SERVER_OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT
879+
? parseInt(process.env.SERVER_OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT, 10)
880+
: 8192
858881
);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
-- AlterTable
2+
ALTER TABLE "RuntimeEnvironment" ADD COLUMN "builtInEnvironmentVariableOverrides" JSONB;

internal-packages/database/prisma/schema.prisma

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -241,6 +241,9 @@ model RuntimeEnvironment {
241241
createdAt DateTime @default(now())
242242
updatedAt DateTime @updatedAt
243243
244+
/// Allows us to customize the built-in environment variables for a specific environment, like TRIGGER_OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT
245+
builtInEnvironmentVariableOverrides Json?
246+
244247
tunnelId String?
245248
246249
backgroundWorkers BackgroundWorker[]

packages/core/src/v3/limits.ts

Lines changed: 41 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,46 @@
11
import { AttributeValue, Attributes } from "@opentelemetry/api";
2+
import { getEnvVar } from "./utils/getEnv.js";
3+
4+
function getOtelEnvVarLimit(key: string, defaultValue: number) {
5+
const value = getEnvVar(key);
6+
7+
if (!value) {
8+
return defaultValue;
9+
}
10+
11+
return parseInt(value, 10);
12+
}
13+
14+
export const OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = getOtelEnvVarLimit(
15+
"TRIGGER_OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT",
16+
256
17+
);
18+
export const OTEL_LOG_ATTRIBUTE_COUNT_LIMIT = getOtelEnvVarLimit(
19+
"TRIGGER_OTEL_LOG_ATTRIBUTE_COUNT_LIMIT",
20+
256
21+
);
22+
export const OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = getOtelEnvVarLimit(
23+
"TRIGGER_OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT",
24+
131072
25+
);
26+
export const OTEL_LOG_ATTRIBUTE_VALUE_LENGTH_LIMIT = getOtelEnvVarLimit(
27+
"TRIGGER_OTEL_LOG_ATTRIBUTE_VALUE_LENGTH_LIMIT",
28+
131072
29+
);
30+
export const OTEL_SPAN_EVENT_COUNT_LIMIT = getOtelEnvVarLimit(
31+
"TRIGGER_OTEL_SPAN_EVENT_COUNT_LIMIT",
32+
10
33+
);
34+
export const OTEL_LINK_COUNT_LIMIT = getOtelEnvVarLimit("TRIGGER_OTEL_LINK_COUNT_LIMIT", 2);
35+
export const OTEL_ATTRIBUTE_PER_LINK_COUNT_LIMIT = getOtelEnvVarLimit(
36+
"TRIGGER_OTEL_ATTRIBUTE_PER_LINK_COUNT_LIMIT",
37+
10
38+
);
39+
export const OTEL_ATTRIBUTE_PER_EVENT_COUNT_LIMIT = getOtelEnvVarLimit(
40+
"TRIGGER_OTEL_ATTRIBUTE_PER_EVENT_COUNT_LIMIT",
41+
10
42+
);
243

3-
export const OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT = 256;
4-
export const OTEL_LOG_ATTRIBUTE_COUNT_LIMIT = 256;
5-
export const OTEL_SPAN_ATTRIBUTE_VALUE_LENGTH_LIMIT = 1028;
6-
export const OTEL_LOG_ATTRIBUTE_VALUE_LENGTH_LIMIT = 1028;
7-
export const OTEL_SPAN_EVENT_COUNT_LIMIT = 10;
8-
export const OTEL_LINK_COUNT_LIMIT = 2;
9-
export const OTEL_ATTRIBUTE_PER_LINK_COUNT_LIMIT = 10;
10-
export const OTEL_ATTRIBUTE_PER_EVENT_COUNT_LIMIT = 10;
1144
export const OFFLOAD_IO_PACKET_LENGTH_LIMIT = 128 * 1024;
1245

1346
export function imposeAttributeLimits(attributes: Attributes): Attributes {

0 commit comments

Comments
 (0)