Skip to content

Commit 9f730fe

Browse files
committed
fix(aws-lambda): reduced lambda runtimes for large number of spans
refs https://jsw.ibm.com/browse/INSTA-13498
1 parent a85026e commit 9f730fe

File tree

6 files changed

+68
-25
lines changed

6 files changed

+68
-25
lines changed

packages/aws-lambda/src/identity_provider.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ exports.init = function init(arnInfo) {
1111
qualifiedArn = arnInfo.arn;
1212
};
1313

14+
exports.getName = function getName() {
15+
return 'aws-lambda';
16+
};
17+
1418
exports.getHostHeader = function getHostHeader() {
1519
return qualifiedArn;
1620
};

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

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ describe('multiple data lambda handler', function () {
9494
});
9595
});
9696

97-
describe('[batching disabled] with 100 iterations', function () {
97+
describe('with 100 iterations and high transmission config values', function () {
9898
this.timeout(config.getTestTimeout() * 2);
9999
let control;
100100

@@ -106,7 +106,9 @@ describe('multiple data lambda handler', function () {
106106
env: {
107107
INSTANA_AGENT_KEY: instanaAgentKey,
108108
WITH_CONFIG: 'true',
109-
INSTANA_NUMBER_OF_ITERATIONS: 100
109+
INSTANA_NUMBER_OF_ITERATIONS: 100,
110+
INSTANA_FORCE_TRANSMISSION_STARTING_AT: 500,
111+
INSTANA_TRACING_INITIAL_TRANSMISSION_DELAY: 1000
110112
}
111113
});
112114

@@ -160,7 +162,9 @@ describe('multiple data lambda handler', function () {
160162
});
161163
});
162164

163-
describe('[batching enabled] with 100 iterations', function () {
165+
// TODO: This test does not use any batchable spans.
166+
// We could also extend the test to enable batching.
167+
describe('with 100 iterations and default behavior', function () {
164168
this.timeout(config.getTestTimeout() * 2);
165169
let control;
166170

@@ -172,10 +176,7 @@ describe('multiple data lambda handler', function () {
172176
env: {
173177
INSTANA_AGENT_KEY: instanaAgentKey,
174178
WITH_CONFIG: 'true',
175-
INSTANA_NUMBER_OF_ITERATIONS: 100,
176-
INSTANA_SPANBATCHING_ENABLED: 'true',
177-
INSTANA_FORCE_TRANSMISSION_STARTING_AT: 10,
178-
INSTANA_DEV_MIN_DELAY_BEFORE_SENDING_SPANS: 100
179+
INSTANA_NUMBER_OF_ITERATIONS: 100
179180
}
180181
});
181182

packages/collector/src/pidStore/index.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ Object.defineProperty(exports, 'pid', {
3636
}
3737
});
3838

39+
exports.getName = function getName() {
40+
return 'default-identity';
41+
};
42+
3943
exports.getEntityId = function getEntityId() {
4044
return internalPidStore.pid;
4145
};

packages/core/src/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ function preInit() {
6868
function init(config, downstreamConnection, processIdentityProvider) {
6969
log.init(/** @type {log.LoggerConfig} */ (config));
7070
util.hasThePackageBeenInitializedTooLate();
71-
config = normalizeConfig(config);
71+
config = normalizeConfig(config, processIdentityProvider);
7272
secrets.init(/** @type {secrets.SecretOption} */ (config));
7373
util.requireHook.init(config);
7474
tracing.init(config, downstreamConnection, processIdentityProvider);

packages/core/src/tracing/spanBuffer.js

Lines changed: 22 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,16 +22,8 @@ let isActive = false;
2222
/** @type {number} */
2323
let activatedAt = null;
2424

25-
let minDelayBeforeSendingSpans = 1000;
26-
if (process.env.INSTANA_DEV_MIN_DELAY_BEFORE_SENDING_SPANS != null) {
27-
minDelayBeforeSendingSpans = parseInt(process.env.INSTANA_DEV_MIN_DELAY_BEFORE_SENDING_SPANS, 10);
28-
if (isNaN(minDelayBeforeSendingSpans)) {
29-
minDelayBeforeSendingSpans = 1000;
30-
}
31-
}
32-
3325
/** @type {number} */
34-
let initialDelayBeforeSendingSpans;
26+
let initialTransmissionDelay;
3527
/** @type {number} */
3628
let transmissionDelay;
3729
/** @type {number} */
@@ -98,7 +90,19 @@ exports.init = function init(config, _downstreamConnection) {
9890
forceTransmissionStartingAt = config.tracing.forceTransmissionStartingAt;
9991
transmissionDelay = config.tracing.transmissionDelay;
10092
batchingEnabled = config.tracing.spanBatchingEnabled;
101-
initialDelayBeforeSendingSpans = Math.max(transmissionDelay, minDelayBeforeSendingSpans);
93+
initialTransmissionDelay = config.tracing.initialTransmissionDelay;
94+
95+
// TODO: drop undocumented env variable in v4 major release
96+
if (process.env.INSTANA_DEV_MIN_DELAY_BEFORE_SENDING_SPANS != null) {
97+
initialTransmissionDelay = parseInt(process.env.INSTANA_DEV_MIN_DELAY_BEFORE_SENDING_SPANS, 10);
98+
if (isNaN(initialTransmissionDelay)) {
99+
initialTransmissionDelay = config.tracing.initialTransmissionDelay;
100+
}
101+
}
102+
103+
// TODO: remove in v4 and make initialTransmissionDelay configurable instead
104+
initialTransmissionDelay = Math.max(transmissionDelay, initialTransmissionDelay);
105+
102106
isFaaS = false;
103107
transmitImmediate = false;
104108

@@ -146,7 +150,7 @@ exports.activate = function activate(extraConfig) {
146150
// On AWS Lambda we wait till the handler finishes and then transmit all collected spans via
147151
// `sendBundle`. Any detected span will be sent directly to the BE.
148152
if (!isFaaS) {
149-
transmissionTimeoutHandle = setTimeout(transmitSpans, initialDelayBeforeSendingSpans);
153+
transmissionTimeoutHandle = setTimeout(transmitSpans, initialTransmissionDelay);
150154
transmissionTimeoutHandle.unref();
151155
}
152156

@@ -201,8 +205,8 @@ exports.addSpan = function (span) {
201205
addToBucket(span);
202206
}
203207

204-
// NOTE: we send out spans directly if the number of spans reaches > 500 [default] and if the min delay is reached.
205-
if (spans.length >= forceTransmissionStartingAt && Date.now() - minDelayBeforeSendingSpans > activatedAt) {
208+
// NOTE: we send out spans directly if the number of spans reaches > X [default] and if the min delay is reached.
209+
if (spans.length >= forceTransmissionStartingAt && Date.now() - initialTransmissionDelay > activatedAt) {
206210
transmitSpans();
207211
}
208212
}
@@ -402,6 +406,11 @@ function batchingBucketKey(span) {
402406
}
403407

404408
/**
409+
* IMPORTANT: Only some instrumentations are enabled to be batchable.
410+
* e.g. mysql, pg, redis, elasticsearch, etc.
411+
* Batching spans means to collect multiple spans of the same type
412+
* and merge them into one span.
413+
*
405414
* @param {import('./cls').InstanaBaseSpan} span
406415
* @returns {boolean}
407416
*/

packages/core/src/util/normalizeConfig.js

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
'use strict';
99

1010
const supportedTracingVersion = require('../tracing/supportedVersion');
11-
11+
const deepMerge = require('../util/deepMerge');
1212
const constants = require('../tracing/constants');
1313

1414
/**
@@ -18,6 +18,7 @@ const constants = require('../tracing/constants');
1818
* @property {boolean} [automaticTracingEnabled]
1919
* @property {boolean} [activateImmediately]
2020
* @property {number} [forceTransmissionStartingAt]
21+
* @property {number} [initialTransmissionDelay]
2122
* @property {number} [maxBufferedSpans]
2223
* @property {number} [transmissionDelay]
2324
* @property {number} [stackTraceLength]
@@ -91,7 +92,7 @@ logger = require('../logger').getLogger('configuration', newLogger => {
9192
});
9293

9394
/** @type {InstanaConfig} */
94-
const defaults = {
95+
const defaultsBase = {
9596
serviceName: null,
9697
packageJsonPath: null,
9798

@@ -108,6 +109,7 @@ const defaults = {
108109
forceTransmissionStartingAt: 500,
109110
maxBufferedSpans: 1000,
110111
transmissionDelay: 1000,
112+
initialTransmissionDelay: 1000,
111113
http: {
112114
extraHttpHeadersToCapture: []
113115
},
@@ -126,8 +128,17 @@ const defaults = {
126128
}
127129
};
128130

129-
const validKafkaHeaderFormats = ['binary', 'string', 'both'];
131+
/** @type {Record<string, InstanaConfig>} */
132+
const identityProviderDefaults = {
133+
'aws-lambda': {
134+
tracing: { forceTransmissionStartingAt: 10, transmissionDelay: 100, initialTransmissionDelay: 100 }
135+
}
136+
};
137+
138+
/** @type InstanaConfig */
139+
let defaults = {};
130140

141+
const validKafkaHeaderFormats = ['binary', 'string', 'both'];
131142
const validSecretsMatcherModes = ['equals-ignore-case', 'equals', 'contains-ignore-case', 'contains', 'regex', 'none'];
132143

133144
/**
@@ -136,13 +147,20 @@ const validSecretsMatcherModes = ['equals-ignore-case', 'equals', 'contains-igno
136147

137148
/**
138149
* @param {InstanaConfig} [config]
150+
* @param {import('../../../collector/src/pidStore')} [identityProvider]
139151
* @returns {InstanaConfig}
140152
*/
141-
module.exports = function normalizeConfig(config) {
153+
module.exports = function normalizeConfig(config, identityProvider) {
142154
if (config == null) {
143155
config = {};
144156
}
145157

158+
if (identityProvider && identityProvider.getName && identityProviderDefaults[identityProvider.getName()]) {
159+
defaults = deepMerge(defaultsBase, identityProviderDefaults[identityProvider.getName()]);
160+
} else {
161+
defaults = defaultsBase;
162+
}
163+
146164
normalizeServiceName(config);
147165
normalizePackageJsonPath(config);
148166
normalizeMetricsConfig(config);
@@ -338,6 +356,13 @@ function normalizeTracingTransmission(config) {
338356
'config.tracing.forceTransmissionStartingAt',
339357
'INSTANA_FORCE_TRANSMISSION_STARTING_AT'
340358
);
359+
360+
config.tracing.initialTransmissionDelay = normalizeSingleValue(
361+
config.tracing.initialTransmissionDelay,
362+
defaults.tracing.initialTransmissionDelay,
363+
'config.tracing.initialTransmissionDelay',
364+
'INSTANA_TRACING_INITIAL_TRANSMISSION_DELAY'
365+
);
341366
}
342367

343368
/**

0 commit comments

Comments
 (0)