Skip to content

Commit b1d0013

Browse files
committed
chore: fixes
1 parent 636d6dd commit b1d0013

File tree

3 files changed

+82
-16
lines changed

3 files changed

+82
-16
lines changed

packages/aws-lambda/load-test/test.js

Lines changed: 56 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ const {
1919

2020
const region = process.env.REGION || 'us-east-1';
2121
const released = process.env.RELEASED ? Boolean(process.env.RELEASED) : false;
22+
const filterTimedOuts = process.env.FILTER_TIMED_OUTS ? Boolean(process.env.FILTER_TIMED_OUTS) : false;
2223
const functionName = released ? 'teamnodejstracer-released-many-spans' : 'teamnodejstracer-many-spans';
2324
const cloudWatchLogsClient = new CloudWatchLogsClient({ region });
2425

@@ -28,7 +29,7 @@ async function getFunctionUrl() {
2829
return functionUrl;
2930
}
3031

31-
const requests = 2;
32+
const requests = process.env.REQUESTS ? parseInt(process.env.REQUESTS, 10) : 10;
3233
let logStreamsResponse;
3334

3435
async function getBilledDurationByRequestId(logGroupName, requestId) {
@@ -49,9 +50,13 @@ async function getBilledDurationByRequestId(logGroupName, requestId) {
4950
}
5051

5152
let billedDuration;
53+
let timeoutErrorFound = false;
54+
let requestIdStart = false;
55+
let requestIdEnd = false;
56+
5257
for (const obj of logStreamsResponse.logStreams) {
5358
const logStreamName = obj.logStreamName;
54-
console.log(`Log Stream Name: ${logStreamName}`);
59+
// console.log(`Log Stream Name: ${logStreamName}`);
5560

5661
const getLogEventsCommand = new GetLogEventsCommand({
5762
logGroupName,
@@ -62,15 +67,34 @@ async function getBilledDurationByRequestId(logGroupName, requestId) {
6267
const logEventsResponse = await cloudWatchLogsClient.send(getLogEventsCommand);
6368

6469
for (const event of logEventsResponse.events) {
70+
if (filterTimedOuts) {
71+
if (requestIdStart && !requestIdEnd) {
72+
if (event.message.includes('request failed')) {
73+
timeoutErrorFound = true;
74+
}
75+
}
76+
}
77+
6578
if (event.message.includes(requestId)) {
79+
requestIdStart = true;
6680
const match = event.message.match(/Billed Duration: (\d+) ms/);
6781
if (match) {
6882
billedDuration = parseInt(match[1], 10);
6983
}
84+
} else if (requestIdStart) {
85+
requestIdEnd = true;
7086
}
7187
}
7288
}
7389

90+
if (filterTimedOuts) {
91+
if (timeoutErrorFound) {
92+
return billedDuration;
93+
}
94+
95+
return null;
96+
}
97+
7498
if (billedDuration) {
7599
return billedDuration;
76100
}
@@ -81,12 +105,16 @@ async function getBilledDurationByRequestId(logGroupName, requestId) {
81105
async function loadTest() {
82106
const functionUrl = await getFunctionUrl();
83107
const logGroupName = `/aws/lambda/${functionName}`;
84-
const requestIds = [];
85-
const responseTimes = [];
108+
const requestIds = {};
86109

87110
console.log(`Function Name: ${functionName}`);
88111
console.log(`Function URL: ${functionUrl}`);
89-
console.log('Starting...');
112+
113+
if (filterTimedOuts) {
114+
console.log('Filtering requests by timed out.');
115+
}
116+
117+
console.log(`Executing ${requests}...`);
90118

91119
// Avoid cold start
92120
let response = await fetch(functionUrl);
@@ -97,36 +125,50 @@ async function loadTest() {
97125

98126
response = await fetch(functionUrl);
99127
const requestId = response.headers.get('x-amzn-requestid');
100-
requestIds.push(requestId);
101128

102129
const end = process.hrtime.bigint();
103-
104130
const durationMs = Number(end - start) / 1e6;
105-
console.log(`${requestId} http response: ${durationMs.toFixed(3)}ms`);
106131

107-
responseTimes.push(durationMs);
132+
requestIds[requestId] = { durationMs };
108133

109134
await new Promise(resolve => setTimeout(resolve, 1000));
110135
}
111136

112-
// log the average response time for all requests responseTimes
113-
const averageResponseTime = responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length;
114-
console.log(`Average Response Time: ${averageResponseTime.toFixed(3)}ms`);
137+
console.log(`Executed ${requests}...`);
115138

116-
console.log(`Fetching billed duration for ${requestIds.length} requests...`);
139+
console.log('Fetching billed duration...');
117140
await new Promise(resolve => setTimeout(resolve, 1000 * 120));
118141

119142
const billedDurations = [];
120-
for (const id of requestIds) {
143+
for (const id of Object.keys(requestIds)) {
121144
try {
122145
const billedDuration = await getBilledDurationByRequestId(logGroupName, id);
146+
147+
if (!billedDuration) {
148+
delete requestIds[id];
149+
continue;
150+
}
151+
152+
console.log(`${id} HTTP Response Time: ${requestIds[id].durationMs}ms`);
123153
console.log(`${id} Billed: ${billedDuration}ms`);
124154
billedDurations.push(billedDuration);
125155
} catch (error) {
126156
console.error(`Failed to get billed duration for Request ${id}:`, error.message);
127157
}
128158
}
129159

160+
if (Object.keys(requestIds).length === 0) {
161+
console.error('No results.');
162+
return;
163+
}
164+
165+
console.log(`Total Requests: ${Object.keys(requestIds).length}`);
166+
167+
// log the average response time for all requests responseTimes
168+
const averageResponseTime =
169+
Object.values(requestIds).reduce((a, b) => a + b.durationMs, 0) / Object.keys(requestIds).length;
170+
console.log(`Average Response Time: ${averageResponseTime.toFixed(3)}ms`);
171+
130172
// log the average billed duration for all requests billedDurations
131173
const averageBilledDuration = billedDurations.reduce((a, b) => a + b, 0) / billedDurations.length;
132174
console.log(`Average Billed Duration: ${averageBilledDuration.toFixed(3)}ms`);

packages/core/src/util/normalizeConfig.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -373,6 +373,7 @@ function normalizeTracingTransmission(config) {
373373
'INSTANA_TRACING_TRANSMISSION_DELAY'
374374
);
375375

376+
// TODO: make it possible to disable the feature - opt in ??
376377
config.tracing.forceTransmissionStartingAt = normalizeSingleValue(
377378
config.tracing.forceTransmissionStartingAt,
378379
defaults.tracing.forceTransmissionStartingAt,

packages/serverless/src/backend_connector.js

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,8 @@ let isLambdaRequest = false;
2222

2323
const timeoutEnvVar = 'INSTANA_TIMEOUT';
2424
let defaultTimeout = 500;
25+
const heartbeatTimeout = 200;
26+
2527
const layerExtensionTimeout = process.env.INSTANA_LAMBDA_EXTENSION_TIMEOUT_IN_MS
2628
? Number(process.env.INSTANA_LAMBDA_EXTENSION_TIMEOUT_IN_MS)
2729
: 2000;
@@ -160,7 +162,7 @@ function scheduleLambdaExtensionHeartbeatRequest() {
160162
method: 'POST',
161163
// This sets a timeout for establishing the socket connection, see setTimeout below for a timeout for an
162164
// idle connection after the socket has been opened.
163-
timeout: layerExtensionTimeout,
165+
timeout: heartbeatTimeout,
164166
headers: {
165167
Connection: 'keep-alive'
166168
}
@@ -206,14 +208,35 @@ function scheduleLambdaExtensionHeartbeatRequest() {
206208
);
207209
});
208210

211+
// CASE: socket is open but no data is sent (should not happen from we know but we need to handle it)
212+
req.setTimeout(heartbeatTimeout, () => {
213+
// req.destroyed indicates that we have run into a timeout and have already handled the timeout error.
214+
if (req.destroyed) {
215+
return;
216+
}
217+
218+
// Make sure we do not try to talk to the Lambda extension again.
219+
useLambdaExtension = false;
220+
clearInterval(heartbeatInterval);
221+
222+
// Destroy timed out request manually as mandated in https://nodejs.org/api/http.html#event-timeout.
223+
if (req && !req.destroyed) {
224+
try {
225+
destroyRequest(req);
226+
} catch (e) {
227+
// ignore
228+
}
229+
}
230+
});
231+
209232
req.end();
210233
};
211234

212235
// call immediately
213236
// timeout is bigger because of possible coldstart
214237
executeHeartbeat();
215238

216-
heartbeatInterval = setInterval(executeHeartbeat, 500);
239+
heartbeatInterval = setInterval(executeHeartbeat, 300);
217240
heartbeatInterval.unref();
218241
}
219242

0 commit comments

Comments
 (0)