@depup/elastic-apm-node 4.15.0-depup.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +26 -0
- package/NOTICE.md +442 -0
- package/README.md +48 -0
- package/changes.json +78 -0
- package/index.d.ts +398 -0
- package/index.js +11 -0
- package/lib/InflightEventSet.js +53 -0
- package/lib/activation-method.js +119 -0
- package/lib/agent.js +941 -0
- package/lib/apm-client/apm-client.js +313 -0
- package/lib/apm-client/http-apm-client/CHANGELOG.md +271 -0
- package/lib/apm-client/http-apm-client/README.md +485 -0
- package/lib/apm-client/http-apm-client/central-config.js +41 -0
- package/lib/apm-client/http-apm-client/container-info.js +111 -0
- package/lib/apm-client/http-apm-client/detect-hostname.js +96 -0
- package/lib/apm-client/http-apm-client/index.js +1975 -0
- package/lib/apm-client/http-apm-client/logging.js +31 -0
- package/lib/apm-client/http-apm-client/ndjson.js +20 -0
- package/lib/apm-client/http-apm-client/truncate.js +434 -0
- package/lib/apm-client/noop-apm-client.js +73 -0
- package/lib/async-hooks-polyfill.js +58 -0
- package/lib/cloud-metadata/aws.js +175 -0
- package/lib/cloud-metadata/azure.js +123 -0
- package/lib/cloud-metadata/callback-coordination.js +159 -0
- package/lib/cloud-metadata/gcp.js +133 -0
- package/lib/cloud-metadata/index.js +175 -0
- package/lib/config/config.js +458 -0
- package/lib/config/normalizers.js +701 -0
- package/lib/config/schema.js +1007 -0
- package/lib/constants.js +35 -0
- package/lib/errors.js +303 -0
- package/lib/filters/sanitize-field-names.js +69 -0
- package/lib/http-request.js +249 -0
- package/lib/instrumentation/azure-functions.js +519 -0
- package/lib/instrumentation/context.js +56 -0
- package/lib/instrumentation/dropped-spans-stats.js +112 -0
- package/lib/instrumentation/elasticsearch-shared.js +63 -0
- package/lib/instrumentation/express-utils.js +91 -0
- package/lib/instrumentation/generic-span.js +322 -0
- package/lib/instrumentation/http-shared.js +424 -0
- package/lib/instrumentation/ids.js +39 -0
- package/lib/instrumentation/index.js +1127 -0
- package/lib/instrumentation/modules/@apollo/server.js +30 -0
- package/lib/instrumentation/modules/@aws-sdk/client-dynamodb.js +143 -0
- package/lib/instrumentation/modules/@aws-sdk/client-s3.js +230 -0
- package/lib/instrumentation/modules/@aws-sdk/client-sns.js +197 -0
- package/lib/instrumentation/modules/@aws-sdk/client-sqs.js +336 -0
- package/lib/instrumentation/modules/@elastic/elasticsearch.js +343 -0
- package/lib/instrumentation/modules/@hapi/hapi.js +221 -0
- package/lib/instrumentation/modules/@opentelemetry/api.js +86 -0
- package/lib/instrumentation/modules/@opentelemetry/sdk-metrics.js +79 -0
- package/lib/instrumentation/modules/@redis/client/dist/lib/client/commands-queue.js +178 -0
- package/lib/instrumentation/modules/@redis/client/dist/lib/client/index.js +49 -0
- package/lib/instrumentation/modules/@smithy/smithy-client.js +198 -0
- package/lib/instrumentation/modules/_lambda-handler.js +40 -0
- package/lib/instrumentation/modules/apollo-server-core.js +49 -0
- package/lib/instrumentation/modules/aws-sdk/dynamodb.js +155 -0
- package/lib/instrumentation/modules/aws-sdk/s3.js +184 -0
- package/lib/instrumentation/modules/aws-sdk/sns.js +232 -0
- package/lib/instrumentation/modules/aws-sdk/sqs.js +361 -0
- package/lib/instrumentation/modules/aws-sdk.js +76 -0
- package/lib/instrumentation/modules/bluebird.js +93 -0
- package/lib/instrumentation/modules/cassandra-driver.js +280 -0
- package/lib/instrumentation/modules/elasticsearch.js +191 -0
- package/lib/instrumentation/modules/express-graphql.js +66 -0
- package/lib/instrumentation/modules/express-queue.js +28 -0
- package/lib/instrumentation/modules/express.js +162 -0
- package/lib/instrumentation/modules/fastify.js +172 -0
- package/lib/instrumentation/modules/finalhandler.js +41 -0
- package/lib/instrumentation/modules/generic-pool.js +85 -0
- package/lib/instrumentation/modules/graphql.js +256 -0
- package/lib/instrumentation/modules/handlebars.js +22 -0
- package/lib/instrumentation/modules/http.js +112 -0
- package/lib/instrumentation/modules/http2.js +320 -0
- package/lib/instrumentation/modules/https.js +68 -0
- package/lib/instrumentation/modules/ioredis.js +94 -0
- package/lib/instrumentation/modules/jade.js +18 -0
- package/lib/instrumentation/modules/kafkajs.js +476 -0
- package/lib/instrumentation/modules/knex.js +91 -0
- package/lib/instrumentation/modules/koa-router.js +74 -0
- package/lib/instrumentation/modules/koa.js +15 -0
- package/lib/instrumentation/modules/memcached.js +99 -0
- package/lib/instrumentation/modules/mimic-response.js +45 -0
- package/lib/instrumentation/modules/mongodb/lib/cmap/connection_pool.js +40 -0
- package/lib/instrumentation/modules/mongodb-core.js +206 -0
- package/lib/instrumentation/modules/mongodb.js +259 -0
- package/lib/instrumentation/modules/mysql.js +200 -0
- package/lib/instrumentation/modules/mysql2.js +140 -0
- package/lib/instrumentation/modules/pg.js +148 -0
- package/lib/instrumentation/modules/pug.js +18 -0
- package/lib/instrumentation/modules/redis.js +176 -0
- package/lib/instrumentation/modules/restify.js +52 -0
- package/lib/instrumentation/modules/tedious.js +159 -0
- package/lib/instrumentation/modules/undici.js +270 -0
- package/lib/instrumentation/modules/ws.js +59 -0
- package/lib/instrumentation/noop-transaction.js +81 -0
- package/lib/instrumentation/run-context/AbstractRunContextManager.js +215 -0
- package/lib/instrumentation/run-context/AsyncHooksRunContextManager.js +106 -0
- package/lib/instrumentation/run-context/AsyncLocalStorageRunContextManager.js +73 -0
- package/lib/instrumentation/run-context/BasicRunContextManager.js +82 -0
- package/lib/instrumentation/run-context/RunContext.js +151 -0
- package/lib/instrumentation/run-context/index.js +23 -0
- package/lib/instrumentation/shimmer.js +123 -0
- package/lib/instrumentation/span-compression.js +239 -0
- package/lib/instrumentation/span.js +621 -0
- package/lib/instrumentation/template-shared.js +43 -0
- package/lib/instrumentation/timer.js +84 -0
- package/lib/instrumentation/transaction.js +571 -0
- package/lib/lambda.js +992 -0
- package/lib/load-source-map.js +100 -0
- package/lib/logging.js +212 -0
- package/lib/metrics/index.js +92 -0
- package/lib/metrics/platforms/generic/index.js +40 -0
- package/lib/metrics/platforms/generic/process-cpu.js +22 -0
- package/lib/metrics/platforms/generic/process-top.js +157 -0
- package/lib/metrics/platforms/generic/stats.js +34 -0
- package/lib/metrics/platforms/generic/system-cpu.js +51 -0
- package/lib/metrics/platforms/linux/index.js +19 -0
- package/lib/metrics/platforms/linux/stats.js +213 -0
- package/lib/metrics/queue.js +90 -0
- package/lib/metrics/registry.js +52 -0
- package/lib/metrics/reporter.js +119 -0
- package/lib/metrics/runtime.js +77 -0
- package/lib/middleware/connect.js +16 -0
- package/lib/opentelemetry-bridge/OTelBridgeNonRecordingSpan.js +150 -0
- package/lib/opentelemetry-bridge/OTelBridgeRunContext.js +124 -0
- package/lib/opentelemetry-bridge/OTelContextManager.js +82 -0
- package/lib/opentelemetry-bridge/OTelSpan.js +344 -0
- package/lib/opentelemetry-bridge/OTelTracer.js +201 -0
- package/lib/opentelemetry-bridge/OTelTracerProvider.js +25 -0
- package/lib/opentelemetry-bridge/README.md +244 -0
- package/lib/opentelemetry-bridge/index.js +15 -0
- package/lib/opentelemetry-bridge/oblog.js +23 -0
- package/lib/opentelemetry-bridge/opentelemetry-core-mini/README.md +3 -0
- package/lib/opentelemetry-bridge/opentelemetry-core-mini/internal/validators.js +52 -0
- package/lib/opentelemetry-bridge/opentelemetry-core-mini/trace/TraceState.js +109 -0
- package/lib/opentelemetry-bridge/otelutils.js +99 -0
- package/lib/opentelemetry-bridge/setup.js +76 -0
- package/lib/opentelemetry-metrics/ElasticApmMetricExporter.js +285 -0
- package/lib/opentelemetry-metrics/index.js +50 -0
- package/lib/parsers.js +225 -0
- package/lib/propwrap.js +147 -0
- package/lib/stacktraces.js +537 -0
- package/lib/symbols.js +15 -0
- package/lib/tracecontext/index.js +118 -0
- package/lib/tracecontext/traceparent.js +185 -0
- package/lib/tracecontext/tracestate.js +388 -0
- package/lib/wildcard-matcher.js +52 -0
- package/loader.mjs +7 -0
- package/package.json +299 -0
- package/start.d.ts +8 -0
- package/start.js +29 -0
- package/types/aws-lambda.d.ts +98 -0
- package/types/connect.d.ts +23 -0
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright Elasticsearch B.V. and other contributors where applicable.
|
|
3
|
+
* Licensed under the BSD 2-Clause License; you may not use this file except in
|
|
4
|
+
* compliance with the BSD 2-Clause License.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
'use strict';
|
|
8
|
+
|
|
9
|
+
const { URL } = require('url');
|
|
10
|
+
|
|
11
|
+
const { WildcardMatcher } = require('../wildcard-matcher');
|
|
12
|
+
const {
|
|
13
|
+
TRACE_CONTINUATION_STRATEGY_CONTINUE,
|
|
14
|
+
TRACE_CONTINUATION_STRATEGY_RESTART,
|
|
15
|
+
TRACE_CONTINUATION_STRATEGY_RESTART_EXTERNAL,
|
|
16
|
+
CONTEXT_MANAGER_ASYNCHOOKS,
|
|
17
|
+
CONTEXT_MANAGER_ASYNCLOCALSTORAGE,
|
|
18
|
+
} = require('../constants');
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Normalizes the key/value pairs properties of the config options object
|
|
22
|
+
* KeyValuePairs config vars are either an object or a comma-separated string
|
|
23
|
+
* of key=value pairs (whitespace around the "key=value" strings is trimmed):
|
|
24
|
+
* {'foo': 'bar', 'eggs': 'spam'} => [['foo', 'bar'], ['eggs', 'spam']]
|
|
25
|
+
* foo=bar, eggs=spam => [['foo', 'bar'], ['eggs', 'spam']]
|
|
26
|
+
*
|
|
27
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
28
|
+
* @param {String[]} fields the list of fields to normalize as key/value pair
|
|
29
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
30
|
+
* @param {import('../logging.js').Logger} logger
|
|
31
|
+
*/
|
|
32
|
+
function normalizeKeyValuePairs(opts, fields, defaults, logger) {
|
|
33
|
+
for (const key of fields) {
|
|
34
|
+
if (key in opts) {
|
|
35
|
+
if (typeof opts[key] === 'object' && !Array.isArray(opts[key])) {
|
|
36
|
+
opts[key] = Object.entries(opts[key]);
|
|
37
|
+
continue;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!Array.isArray(opts[key]) && typeof opts[key] === 'string') {
|
|
41
|
+
opts[key] = opts[key].split(',').map((v) => v.trim());
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if (Array.isArray(opts[key])) {
|
|
45
|
+
// Note: Currently this assumes no '=' in the value. Also this does not
|
|
46
|
+
// trim whitespace.
|
|
47
|
+
opts[key] = opts[key].map((value) =>
|
|
48
|
+
typeof value === 'string' ? value.split('=') : value,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Normalizes the number properties of the config options object
|
|
57
|
+
*
|
|
58
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
59
|
+
* @param {String[]} fields the list of fields to normalize as number
|
|
60
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
61
|
+
* @param {import('../logging.js').Logger} logger
|
|
62
|
+
*/
|
|
63
|
+
function normalizeNumbers(opts, fields, defaults, logger) {
|
|
64
|
+
for (const key of fields) {
|
|
65
|
+
if (key in opts) opts[key] = Number(opts[key]);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Normalizes the number properties of the config options object
|
|
71
|
+
*
|
|
72
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
73
|
+
* @param {String[]} fields the list of fields to normalize as number
|
|
74
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
75
|
+
* @param {import('../logging.js').Logger} logger
|
|
76
|
+
*/
|
|
77
|
+
function normalizeInfinity(opts, fields, defaults, logger) {
|
|
78
|
+
for (const key of fields) {
|
|
79
|
+
if (opts[key] === -1) opts[key] = Infinity;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Translates a string byte size, e.g. '10kb', into an integer number of bytes.
|
|
85
|
+
*
|
|
86
|
+
* @param {String} input
|
|
87
|
+
* @param {string} key - the config option key
|
|
88
|
+
* @param {import('../logging.js').Logger} logger
|
|
89
|
+
* @returns {Number|undefined}
|
|
90
|
+
*/
|
|
91
|
+
function bytes(input, key, logger) {
|
|
92
|
+
const matches = input.match(/^(\d+)(b|kb|mb|gb)$/i);
|
|
93
|
+
if (!matches) {
|
|
94
|
+
logger.warn(
|
|
95
|
+
'units missing in size value "%s" for "%s" config option. Use one of b|kb|mb|gb',
|
|
96
|
+
input,
|
|
97
|
+
key,
|
|
98
|
+
);
|
|
99
|
+
return Number(input);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
const suffix = matches[2].toLowerCase();
|
|
103
|
+
let value = Number(matches[1]);
|
|
104
|
+
|
|
105
|
+
if (!suffix || suffix === 'b') {
|
|
106
|
+
return value;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
value *= 1024;
|
|
110
|
+
if (suffix === 'kb') {
|
|
111
|
+
return value;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
value *= 1024;
|
|
115
|
+
if (suffix === 'mb') {
|
|
116
|
+
return value;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
value *= 1024;
|
|
120
|
+
if (suffix === 'gb') {
|
|
121
|
+
return value;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Normalizes the byte properties of the config options object
|
|
127
|
+
*
|
|
128
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
129
|
+
* @param {String[]} fields the list of fields to normalize as bytes
|
|
130
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
131
|
+
* @param {import('../logging.js').Logger} logger
|
|
132
|
+
*/
|
|
133
|
+
function normalizeBytes(opts, fields, defaults, logger) {
|
|
134
|
+
for (const key of fields) {
|
|
135
|
+
if (key in opts) {
|
|
136
|
+
opts[key] = bytes(String(opts[key]), key, logger);
|
|
137
|
+
if (key === 'errorMessageMaxLength') {
|
|
138
|
+
logger.warn(
|
|
139
|
+
'config option "errorMessageMaxLength" is deprecated. Use "longFieldMaxLength"',
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Convert a given duration config option into a number of seconds.
|
|
148
|
+
* If the given duration is invalid, this returns `null`.
|
|
149
|
+
* Units are *case-sensitive*.
|
|
150
|
+
*
|
|
151
|
+
* Examples:
|
|
152
|
+
* secondsFromDuration('30s', 's', ['ms', 's', 'm'], false) // => 30
|
|
153
|
+
* secondsFromDuration('-1s', 's', ['ms', 's', 'm'], false) // => null
|
|
154
|
+
* secondsFromDuration('-1ms', 's', ['ms', 's', 'm'], true) // => -0.001
|
|
155
|
+
* secondsFromDuration(500, 'ms', ['us', 'ms', 's', 'm'], false) // => 0.5
|
|
156
|
+
*
|
|
157
|
+
* @param {String|Number} duration - Typically a string of the form `<num><unit>`,
|
|
158
|
+
* for example `30s`, `-1ms`, `2m`. The `defaultUnit` is used if a unit is
|
|
159
|
+
* not part of the string, or if duration is a number. If given as a string,
|
|
160
|
+
* decimal ('1.5s') and exponential-notation ('1e-3s') values are not allowed.
|
|
161
|
+
* @param {String} defaultUnit
|
|
162
|
+
* @param {Array<String>} allowedUnits - An array of the allowed unit strings. This
|
|
163
|
+
* array may include any number of `us`, `ms`, `s`, and `m`.
|
|
164
|
+
* @param {Boolean} allowNegative - Whether a negative number is allowed.
|
|
165
|
+
* @param {string} key - the config option key
|
|
166
|
+
* @param {Logger} logger
|
|
167
|
+
* @returns {number|null}
|
|
168
|
+
*/
|
|
169
|
+
function secondsFromDuration(
|
|
170
|
+
duration,
|
|
171
|
+
defaultUnit,
|
|
172
|
+
allowedUnits,
|
|
173
|
+
allowNegative,
|
|
174
|
+
key,
|
|
175
|
+
logger,
|
|
176
|
+
) {
|
|
177
|
+
let val;
|
|
178
|
+
let unit;
|
|
179
|
+
if (typeof duration === 'string') {
|
|
180
|
+
let match;
|
|
181
|
+
if (allowNegative) {
|
|
182
|
+
match = /^(-?\d+)(\w+)?$/.exec(duration);
|
|
183
|
+
} else {
|
|
184
|
+
match = /^(\d+)(\w+)?$/.exec(duration);
|
|
185
|
+
}
|
|
186
|
+
if (!match) {
|
|
187
|
+
return null;
|
|
188
|
+
}
|
|
189
|
+
val = Number(match[1]);
|
|
190
|
+
if (isNaN(val) || !Number.isFinite(val)) {
|
|
191
|
+
return null;
|
|
192
|
+
}
|
|
193
|
+
unit = match[2];
|
|
194
|
+
if (!unit) {
|
|
195
|
+
logger.warn(
|
|
196
|
+
'units missing in duration value "%s" for "%s" config option: using default units "%s"',
|
|
197
|
+
duration,
|
|
198
|
+
key,
|
|
199
|
+
defaultUnit,
|
|
200
|
+
);
|
|
201
|
+
unit = defaultUnit;
|
|
202
|
+
}
|
|
203
|
+
if (!allowedUnits.includes(unit)) {
|
|
204
|
+
return null;
|
|
205
|
+
}
|
|
206
|
+
} else if (typeof duration === 'number') {
|
|
207
|
+
if (isNaN(duration)) {
|
|
208
|
+
return null;
|
|
209
|
+
} else if (duration < 0 && !allowNegative) {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
val = duration;
|
|
213
|
+
unit = defaultUnit;
|
|
214
|
+
} else {
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
// Scale to seconds.
|
|
219
|
+
switch (unit) {
|
|
220
|
+
case 'us':
|
|
221
|
+
val /= 1e6;
|
|
222
|
+
break;
|
|
223
|
+
case 'ms':
|
|
224
|
+
val /= 1e3;
|
|
225
|
+
break;
|
|
226
|
+
case 's':
|
|
227
|
+
break;
|
|
228
|
+
case 'm':
|
|
229
|
+
val *= 60;
|
|
230
|
+
break;
|
|
231
|
+
default:
|
|
232
|
+
throw new Error(`unknown unit "${unit}" from "${duration}"`);
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
return val;
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
/**
|
|
239
|
+
* Normalizes the duration properties of the config options object
|
|
240
|
+
*
|
|
241
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
242
|
+
* @param {Array<Object>} fields the list of fields to normalize as duration (with name, defaultUnit, allowedUnits, allowNegative)
|
|
243
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
244
|
+
* @param {import('../logging.js').Logger} logger
|
|
245
|
+
*/
|
|
246
|
+
function normalizeDurationOptions(opts, fields, defaults, logger) {
|
|
247
|
+
for (const optSpec of fields) {
|
|
248
|
+
const key = optSpec.name;
|
|
249
|
+
if (key in opts) {
|
|
250
|
+
const val = secondsFromDuration(
|
|
251
|
+
opts[key],
|
|
252
|
+
optSpec.defaultUnit,
|
|
253
|
+
optSpec.allowedUnits,
|
|
254
|
+
optSpec.allowNegative,
|
|
255
|
+
key,
|
|
256
|
+
logger,
|
|
257
|
+
);
|
|
258
|
+
if (val === null) {
|
|
259
|
+
if (key in defaults) {
|
|
260
|
+
const def = defaults[key];
|
|
261
|
+
logger.warn(
|
|
262
|
+
'invalid duration value "%s" for "%s" config option: using default "%s"',
|
|
263
|
+
opts[key],
|
|
264
|
+
key,
|
|
265
|
+
def,
|
|
266
|
+
);
|
|
267
|
+
opts[key] = secondsFromDuration(
|
|
268
|
+
def,
|
|
269
|
+
optSpec.defaultUnit,
|
|
270
|
+
optSpec.allowedUnits,
|
|
271
|
+
optSpec.allowNegative,
|
|
272
|
+
key,
|
|
273
|
+
logger,
|
|
274
|
+
);
|
|
275
|
+
} else {
|
|
276
|
+
logger.warn(
|
|
277
|
+
'invalid duration value "%s" for "%s" config option: ignoring this option',
|
|
278
|
+
opts[key],
|
|
279
|
+
key,
|
|
280
|
+
);
|
|
281
|
+
delete opts[key];
|
|
282
|
+
}
|
|
283
|
+
} else {
|
|
284
|
+
opts[key] = val;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
/**
|
|
291
|
+
* Normalizes the array properties of the config options object
|
|
292
|
+
* Array config vars are either already an array of strings, or a
|
|
293
|
+
* comma-separated string (whitespace is trimmed):
|
|
294
|
+
* 'foo, bar' => ['foo', 'bar']
|
|
295
|
+
*
|
|
296
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
297
|
+
* @param {String[]} fields the list of fields to normalize as arrays
|
|
298
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
299
|
+
* @param {import('../logging.js').Logger} logger
|
|
300
|
+
*/
|
|
301
|
+
function normalizeArrays(opts, fields, defaults, logger) {
|
|
302
|
+
for (const key of fields) {
|
|
303
|
+
if (key in opts && typeof opts[key] === 'string') {
|
|
304
|
+
opts[key] = opts[key].split(',').map((v) => v.trim());
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Parses "true"|"false" to boolean if not a boolean already and returns it. Returns undefined otherwise
|
|
311
|
+
*
|
|
312
|
+
* @param {import('../logging.js').Logger} logger
|
|
313
|
+
* @param {String} key
|
|
314
|
+
* @param {any} value
|
|
315
|
+
* @returns {Boolean|undefined}
|
|
316
|
+
*/
|
|
317
|
+
function strictBool(logger, key, value) {
|
|
318
|
+
if (typeof value === 'boolean') {
|
|
319
|
+
return value;
|
|
320
|
+
}
|
|
321
|
+
// This will return undefined for unknown inputs, resulting in them being skipped.
|
|
322
|
+
switch (value) {
|
|
323
|
+
case 'false':
|
|
324
|
+
return false;
|
|
325
|
+
case 'true':
|
|
326
|
+
return true;
|
|
327
|
+
default: {
|
|
328
|
+
logger.warn('unrecognized boolean value "%s" for "%s"', value, key);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* Normalizes the boolean properties of the config options object
|
|
335
|
+
* Boolean config vars are either already a boolean, or a string
|
|
336
|
+
* representation of the boolean value: `true` or `false`
|
|
337
|
+
*
|
|
338
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
339
|
+
* @param {String[]} fields the list of fields to normalize as boolean
|
|
340
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
341
|
+
* @param {import('../logging.js').Logger} logger
|
|
342
|
+
*/
|
|
343
|
+
function normalizeBools(opts, fields, defaults, logger) {
|
|
344
|
+
for (const key of fields) {
|
|
345
|
+
if (key in opts) opts[key] = strictBool(logger, key, opts[key]);
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
/**
|
|
350
|
+
* Checks validity of the URL properties of the config options object.
|
|
351
|
+
*
|
|
352
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
353
|
+
* @param {String[]} fields the list of fields to normalize as boolean
|
|
354
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
355
|
+
* @param {import('../logging.js').Logger} logger
|
|
356
|
+
*/
|
|
357
|
+
function normalizeUrls(opts, fields, defaults, logger) {
|
|
358
|
+
for (const key of fields) {
|
|
359
|
+
if (key in opts) {
|
|
360
|
+
try {
|
|
361
|
+
// eslint-disable-next-line no-unused-vars
|
|
362
|
+
const url = new URL(opts[key]);
|
|
363
|
+
// TODO: consider making the port explicit in the URL
|
|
364
|
+
// sourceValue http://foo.com => normalized http://foo.com:80
|
|
365
|
+
// sourceValue https://foo.com => normalized https://foo.com:443
|
|
366
|
+
} catch (err) {
|
|
367
|
+
logger.warn('Invalid "%s" config value, it must be a valid URL', key);
|
|
368
|
+
opts[key] = null;
|
|
369
|
+
}
|
|
370
|
+
}
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
/**
|
|
375
|
+
* Normalizes the ignore options and places them in specific properties for string and RegExp values
|
|
376
|
+
*
|
|
377
|
+
* Ignore config vars are either an array of wildcard expressions or an array of strings and RegExps:
|
|
378
|
+
* of key=value pairs (whitespace around the "key=value" strings is trimmed):
|
|
379
|
+
* ['*foo', 'bar*'] => [ /^.*foo/, /^bar.*$/ ] (result goes to another property)
|
|
380
|
+
* ['foo', /url/pathname$/] => ['foo'] (strings are placed into a specific config option)
|
|
381
|
+
* => [/url/pathname$/] (RegExps are placed into a specific config option)
|
|
382
|
+
*
|
|
383
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
384
|
+
* @param {String[]} fields the list of fields to normalize as boolean
|
|
385
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
386
|
+
* @param {import('../logging.js').Logger} logger
|
|
387
|
+
*/
|
|
388
|
+
function normalizeIgnoreOptions(opts, fields, defaults, logger) {
|
|
389
|
+
// Params are meant to be used in upcoming changes
|
|
390
|
+
if (opts.transactionIgnoreUrls) {
|
|
391
|
+
opts.transactionIgnoreUrlRegExp = [];
|
|
392
|
+
const wildcard = new WildcardMatcher();
|
|
393
|
+
for (const ptn of opts.transactionIgnoreUrls) {
|
|
394
|
+
const re = wildcard.compile(ptn);
|
|
395
|
+
opts.transactionIgnoreUrlRegExp.push(re);
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
if (opts.ignoreUrls) {
|
|
400
|
+
opts.ignoreUrlStr = [];
|
|
401
|
+
opts.ignoreUrlRegExp = [];
|
|
402
|
+
for (const ptn of opts.ignoreUrls) {
|
|
403
|
+
if (typeof ptn === 'string') {
|
|
404
|
+
opts.ignoreUrlStr.push(ptn);
|
|
405
|
+
} else {
|
|
406
|
+
opts.ignoreUrlRegExp.push(ptn);
|
|
407
|
+
}
|
|
408
|
+
}
|
|
409
|
+
delete opts.ignoreUrls;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
if (opts.ignoreUserAgents) {
|
|
413
|
+
opts.ignoreUserAgentStr = [];
|
|
414
|
+
opts.ignoreUserAgentRegExp = [];
|
|
415
|
+
for (const ptn of opts.ignoreUserAgents) {
|
|
416
|
+
if (typeof ptn === 'string') {
|
|
417
|
+
opts.ignoreUserAgentStr.push(ptn);
|
|
418
|
+
} else {
|
|
419
|
+
opts.ignoreUserAgentRegExp.push(ptn);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
delete opts.ignoreUserAgents;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (opts.ignoreMessageQueues) {
|
|
426
|
+
opts.ignoreMessageQueuesRegExp = [];
|
|
427
|
+
const wildcard = new WildcardMatcher();
|
|
428
|
+
for (const ptn of opts.ignoreMessageQueues) {
|
|
429
|
+
const re = wildcard.compile(ptn);
|
|
430
|
+
opts.ignoreMessageQueuesRegExp.push(re);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Normalizes the wildcard matchers of sanitizeFieldNames and thansforms the into RegExps
|
|
437
|
+
*
|
|
438
|
+
* TODO: we are doing the same to some ignoreOptions
|
|
439
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
440
|
+
*/
|
|
441
|
+
function normalizeSanitizeFieldNames(opts) {
|
|
442
|
+
if (opts.sanitizeFieldNames) {
|
|
443
|
+
opts.sanitizeFieldNamesRegExp = [];
|
|
444
|
+
const wildcard = new WildcardMatcher();
|
|
445
|
+
for (const ptn of opts.sanitizeFieldNames) {
|
|
446
|
+
const re = wildcard.compile(ptn);
|
|
447
|
+
opts.sanitizeFieldNamesRegExp.push(re);
|
|
448
|
+
}
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// TODO: this is the same as normalizeSanitizeFieldNames
|
|
453
|
+
// maybe create a normalizeWildcardOptions???
|
|
454
|
+
function normalizeDisableMetrics(opts) {
|
|
455
|
+
if (opts.disableMetrics) {
|
|
456
|
+
opts.disableMetricsRegExp = []; // This line was not in the original code but raised an exception in the tests
|
|
457
|
+
const wildcard = new WildcardMatcher();
|
|
458
|
+
for (const ptn of opts.disableMetrics) {
|
|
459
|
+
const re = wildcard.compile(ptn);
|
|
460
|
+
opts.disableMetricsRegExp.push(re);
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
// TODO: same as above
|
|
466
|
+
function normalizeElasticsearchCaptureBodyUrls(opts) {
|
|
467
|
+
if (opts.elasticsearchCaptureBodyUrls) {
|
|
468
|
+
opts.elasticsearchCaptureBodyUrlsRegExp = [];
|
|
469
|
+
const wildcard = new WildcardMatcher();
|
|
470
|
+
for (const ptn of opts.elasticsearchCaptureBodyUrls) {
|
|
471
|
+
const re = wildcard.compile(ptn);
|
|
472
|
+
opts.elasticsearchCaptureBodyUrlsRegExp.push(re);
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* Makes sure the cloudProvider options is valid othherwise it set the default value.
|
|
479
|
+
*
|
|
480
|
+
* @param {Record<String, unknown>} opts the configuration options to normalize
|
|
481
|
+
* @param {String[]} fields the list of fields to normalize as duration
|
|
482
|
+
* @param {Record<String, unknown>} defaults the configuration defaults
|
|
483
|
+
* @param {import('../logging.js').Logger} logger
|
|
484
|
+
*/
|
|
485
|
+
function normalizeCloudProvider(opts, fields, defaults, logger) {
|
|
486
|
+
if ('cloudProvider' in opts) {
|
|
487
|
+
const allowedValues = ['auto', 'gcp', 'azure', 'aws', 'none'];
|
|
488
|
+
if (allowedValues.indexOf(opts.cloudProvider) === -1) {
|
|
489
|
+
logger.warn(
|
|
490
|
+
'Invalid "cloudProvider" config value %s, falling back to default %s',
|
|
491
|
+
opts.cloudProvider,
|
|
492
|
+
defaults.cloudProvider,
|
|
493
|
+
);
|
|
494
|
+
opts.cloudProvider = defaults.cloudProvider;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
// `customMetricsHistogramBoundaries` must be a sorted array of numbers,
|
|
500
|
+
// without duplicates.
|
|
501
|
+
function normalizeCustomMetricsHistogramBoundaries(
|
|
502
|
+
opts,
|
|
503
|
+
fields,
|
|
504
|
+
defaults,
|
|
505
|
+
logger,
|
|
506
|
+
) {
|
|
507
|
+
if (!('customMetricsHistogramBoundaries' in opts)) {
|
|
508
|
+
return;
|
|
509
|
+
}
|
|
510
|
+
let val = opts.customMetricsHistogramBoundaries;
|
|
511
|
+
if (typeof val === 'string') {
|
|
512
|
+
val = val.split(',').map((v) => Number(v.trim()));
|
|
513
|
+
}
|
|
514
|
+
let errReason = null;
|
|
515
|
+
if (!Array.isArray(val)) {
|
|
516
|
+
errReason = 'value is not an array';
|
|
517
|
+
} else if (val.some((el) => typeof el !== 'number' || isNaN(el))) {
|
|
518
|
+
errReason = 'array includes non-numbers';
|
|
519
|
+
} else {
|
|
520
|
+
for (let i = 0; i < val.length - 1; i++) {
|
|
521
|
+
if (val[i] === val[i + 1]) {
|
|
522
|
+
errReason = 'array has duplicate values';
|
|
523
|
+
break;
|
|
524
|
+
} else if (val[i] > val[i + 1]) {
|
|
525
|
+
errReason = 'array is not sorted';
|
|
526
|
+
break;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
if (errReason) {
|
|
531
|
+
logger.warn(
|
|
532
|
+
'Invalid "customMetricsHistogramBoundaries" config value %j, %s; falling back to default',
|
|
533
|
+
opts.customMetricsHistogramBoundaries,
|
|
534
|
+
errReason,
|
|
535
|
+
);
|
|
536
|
+
opts.customMetricsHistogramBoundaries =
|
|
537
|
+
defaults.customMetricsHistogramBoundaries;
|
|
538
|
+
} else {
|
|
539
|
+
opts.customMetricsHistogramBoundaries = val;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
// transactionSampleRate is specified to be:
|
|
544
|
+
// - in the range [0,1]
|
|
545
|
+
// - rounded to 4 decimal places of precision (e.g. 0.0001, 0.5678, 0.9999)
|
|
546
|
+
// - with the special case that a value in the range (0, 0.0001] should be
|
|
547
|
+
// rounded to 0.0001 -- to avoid a small value being rounded to zero.
|
|
548
|
+
//
|
|
549
|
+
// https://github.com/elastic/apm/blob/main/specs/agents/tracing-sampling.md
|
|
550
|
+
function normalizeTransactionSampleRate(opts, fields, defaults, logger) {
|
|
551
|
+
if ('transactionSampleRate' in opts) {
|
|
552
|
+
// The value was already run through `Number(...)` in `normalizeNumbers`.
|
|
553
|
+
const rate = opts.transactionSampleRate;
|
|
554
|
+
if (isNaN(rate) || rate < 0 || rate > 1) {
|
|
555
|
+
opts.transactionSampleRate = defaults.transactionSampleRate;
|
|
556
|
+
logger.warn(
|
|
557
|
+
'Invalid "transactionSampleRate" config value %s, falling back to default %s',
|
|
558
|
+
rate,
|
|
559
|
+
opts.transactionSampleRate,
|
|
560
|
+
);
|
|
561
|
+
} else if (rate > 0 && rate < 0.0001) {
|
|
562
|
+
opts.transactionSampleRate = 0.0001;
|
|
563
|
+
} else {
|
|
564
|
+
opts.transactionSampleRate = Math.round(rate * 10000) / 10000;
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
const ALLOWED_TRACE_CONTINUATION_STRATEGY = {
|
|
570
|
+
[TRACE_CONTINUATION_STRATEGY_CONTINUE]: true,
|
|
571
|
+
[TRACE_CONTINUATION_STRATEGY_RESTART]: true,
|
|
572
|
+
[TRACE_CONTINUATION_STRATEGY_RESTART_EXTERNAL]: true,
|
|
573
|
+
};
|
|
574
|
+
function normalizeTraceContinuationStrategy(opts, fields, defaults, logger) {
|
|
575
|
+
if (
|
|
576
|
+
'traceContinuationStrategy' in opts &&
|
|
577
|
+
!(opts.traceContinuationStrategy in ALLOWED_TRACE_CONTINUATION_STRATEGY)
|
|
578
|
+
) {
|
|
579
|
+
logger.warn(
|
|
580
|
+
'Invalid "traceContinuationStrategy" config value %j, falling back to default %j',
|
|
581
|
+
opts.traceContinuationStrategy,
|
|
582
|
+
defaults.traceContinuationStrategy,
|
|
583
|
+
);
|
|
584
|
+
opts.traceContinuationStrategy = defaults.traceContinuationStrategy;
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
const ALLOWED_CONTEXT_MANAGER = {
|
|
589
|
+
[CONTEXT_MANAGER_ASYNCHOOKS]: true,
|
|
590
|
+
[CONTEXT_MANAGER_ASYNCLOCALSTORAGE]: true,
|
|
591
|
+
};
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* Normalize and validate the given values for `contextManager`, and the
|
|
595
|
+
* deprecated `asyncHooks` that it replaces.
|
|
596
|
+
*
|
|
597
|
+
* - `contextManager=asynchooks` means use the "async_hooks.createHook()"
|
|
598
|
+
* technique. This works in all supported versions of node, but can have
|
|
599
|
+
* significant performance overhead for Promise-heavy apps.
|
|
600
|
+
* - `contextManager=asynclocalstorage` means use the "AsyncLocalStorage"
|
|
601
|
+
* technique *if supported in the version of node* (>=14.5 || ^12.19.0).
|
|
602
|
+
* Otherwise, this will warn and fallback to "asynchooks".
|
|
603
|
+
* - No specified option means use the best async technique.
|
|
604
|
+
*/
|
|
605
|
+
function normalizeContextManager(opts, fields, defaults, logger) {
|
|
606
|
+
// Treat the empty string, e.g. `ELASTIC_APM_CONTEXT_MANAGER=`, as if it had
|
|
607
|
+
// not been specified.
|
|
608
|
+
if (opts.contextManager === '') {
|
|
609
|
+
delete opts.contextManager;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
if (
|
|
613
|
+
'contextManager' in opts &&
|
|
614
|
+
!(opts.contextManager in ALLOWED_CONTEXT_MANAGER)
|
|
615
|
+
) {
|
|
616
|
+
logger.warn(
|
|
617
|
+
'Invalid "contextManager" config value %j, falling back to default behavior',
|
|
618
|
+
opts.contextManager,
|
|
619
|
+
);
|
|
620
|
+
delete opts.contextManager;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
// Normalize provided values for `spanFramesMinDuration` (deprecated),
|
|
625
|
+
// `captureSpanStackTraces` (deprecated) and `spanStackTraceMinDuration` into
|
|
626
|
+
// a final value for `spanStackTraceMinDuration` that is used by the agent.
|
|
627
|
+
//
|
|
628
|
+
// This function expects `normalizeDurationOptions()` and `normalizeBools()`
|
|
629
|
+
// to have already been called.
|
|
630
|
+
//
|
|
631
|
+
// | spanStackTraceMinDuration | captureSpanStackTraces | spanFramesMinDuration | resultant spanStackTraceMinDuration |
|
|
632
|
+
// | ------------------------- | ---------------------- | ----------------------- | ----------------------------------- |
|
|
633
|
+
// | - | - | - | `-1ms` (no span stacktraces) |
|
|
634
|
+
// | `-1ms` (negative value) | (any value is ignored) | (any value is ignored) | `-1ms` (no span stacktraces) |
|
|
635
|
+
// | `0ms` (zero value) | (any value is ignored) | (any value is ignored) | `0ms` (stacktraces for all spans) |
|
|
636
|
+
// | `5ms` (positive value) | (any value is ignored) | (any value is ignored) | `5ms` |
|
|
637
|
+
// | - | `false` | (any value) | `-1ms` (no span stacktraces) |
|
|
638
|
+
// | - | `true` | - | `10ms` (backwards compatible value) |
|
|
639
|
+
// | - | `true` or unspecified | `0ms` (zero value) | `-1ms` (no span stacktraces) |
|
|
640
|
+
// | - | `true` or unspecified | `-1ms` (negative value) | `0ms` (stacktraces for all spans) |
|
|
641
|
+
// | - | `true` or unspecified | `5ms` (positive value) | `5ms` |
|
|
642
|
+
function normalizeSpanStackTraceMinDuration(opts, fields, defaults, logger) {
|
|
643
|
+
const before = {};
|
|
644
|
+
if (opts.captureSpanStackTraces !== undefined)
|
|
645
|
+
before.captureSpanStackTraces = opts.captureSpanStackTraces;
|
|
646
|
+
if (opts.spanFramesMinDuration !== undefined)
|
|
647
|
+
before.spanFramesMinDuration = opts.spanFramesMinDuration;
|
|
648
|
+
if (opts.spanStackTraceMinDuration !== undefined)
|
|
649
|
+
before.spanStackTraceMinDuration = opts.spanStackTraceMinDuration;
|
|
650
|
+
|
|
651
|
+
if ('spanStackTraceMinDuration' in opts) {
|
|
652
|
+
// If the new option was specified, then use it and ignore the old two.
|
|
653
|
+
} else if (opts.captureSpanStackTraces === false) {
|
|
654
|
+
opts.spanStackTraceMinDuration = -1; // Turn off span stacktraces.
|
|
655
|
+
} else if ('spanFramesMinDuration' in opts) {
|
|
656
|
+
if (opts.spanFramesMinDuration === 0) {
|
|
657
|
+
opts.spanStackTraceMinDuration = -1; // Turn off span stacktraces.
|
|
658
|
+
} else if (opts.spanFramesMinDuration < 0) {
|
|
659
|
+
opts.spanStackTraceMinDuration = 0; // Stacktraces for all spans.
|
|
660
|
+
} else {
|
|
661
|
+
opts.spanStackTraceMinDuration = opts.spanFramesMinDuration;
|
|
662
|
+
}
|
|
663
|
+
} else if (opts.captureSpanStackTraces === true) {
|
|
664
|
+
// For backwards compat, use the default `spanFramesMinDuration` value
|
|
665
|
+
// from before `spanStackTraceMinDuration` was introduced.
|
|
666
|
+
opts.spanStackTraceMinDuration = 10 / 1e3; // 10ms
|
|
667
|
+
} else {
|
|
668
|
+
// None of the three options was specified.
|
|
669
|
+
opts.spanStackTraceMinDuration = -1; // Turn off span stacktraces.
|
|
670
|
+
}
|
|
671
|
+
delete opts.captureSpanStackTraces;
|
|
672
|
+
delete opts.spanFramesMinDuration;
|
|
673
|
+
|
|
674
|
+
// Log if something potentially interesting happened here.
|
|
675
|
+
if (Object.keys(before).length > 0) {
|
|
676
|
+
const after = { spanStackTraceMinDuration: opts.spanStackTraceMinDuration };
|
|
677
|
+
logger.trace({ before, after }, 'normalizeSpanStackTraceMinDuration');
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
|
|
681
|
+
module.exports = {
|
|
682
|
+
normalizeArrays,
|
|
683
|
+
normalizeBools,
|
|
684
|
+
normalizeBytes,
|
|
685
|
+
normalizeCloudProvider,
|
|
686
|
+
normalizeCustomMetricsHistogramBoundaries,
|
|
687
|
+
normalizeDisableMetrics,
|
|
688
|
+
normalizeDurationOptions,
|
|
689
|
+
normalizeElasticsearchCaptureBodyUrls,
|
|
690
|
+
normalizeIgnoreOptions,
|
|
691
|
+
normalizeInfinity,
|
|
692
|
+
normalizeKeyValuePairs,
|
|
693
|
+
normalizeNumbers,
|
|
694
|
+
normalizeSanitizeFieldNames,
|
|
695
|
+
normalizeTransactionSampleRate,
|
|
696
|
+
secondsFromDuration,
|
|
697
|
+
normalizeTraceContinuationStrategy,
|
|
698
|
+
normalizeContextManager,
|
|
699
|
+
normalizeSpanStackTraceMinDuration,
|
|
700
|
+
normalizeUrls,
|
|
701
|
+
};
|