@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,63 @@
|
|
|
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
|
+
// Shared functionality between the instrumentations of:
|
|
10
|
+
// - elasticsearch - the legacy Elasticsearch JS client
|
|
11
|
+
// - @elastic/elasticsearch - the new Elasticsearch JS client
|
|
12
|
+
|
|
13
|
+
// Only capture the ES request body if the request path matches the
|
|
14
|
+
// `elasticsearchCaptureBodyUrls` config.
|
|
15
|
+
function shouldCaptureBody(path, elasticsearchCaptureBodyUrlsRegExp) {
|
|
16
|
+
if (!path) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
for (var i = 0; i < elasticsearchCaptureBodyUrlsRegExp.length; i++) {
|
|
20
|
+
const re = elasticsearchCaptureBodyUrlsRegExp[i];
|
|
21
|
+
if (re.test(path)) {
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Get an appropriate `span.context.db.statement` for this ES client request, if any.
|
|
30
|
+
* https://github.com/elastic/apm/blob/main/specs/agents/tracing-instrumentation-db.md#elasticsearch_capture_body_urls-configuration
|
|
31
|
+
*
|
|
32
|
+
* @param {string | null} path
|
|
33
|
+
* @param {string | null} body
|
|
34
|
+
* @param {RegExp[]} elasticsearchCaptureBodyUrlsRegExp
|
|
35
|
+
* @return {string | undefined}
|
|
36
|
+
*/
|
|
37
|
+
function getElasticsearchDbStatement(
|
|
38
|
+
path,
|
|
39
|
+
body,
|
|
40
|
+
elasticsearchCaptureBodyUrlsRegExp,
|
|
41
|
+
) {
|
|
42
|
+
if (body && shouldCaptureBody(path, elasticsearchCaptureBodyUrlsRegExp)) {
|
|
43
|
+
if (typeof body === 'string') {
|
|
44
|
+
return body;
|
|
45
|
+
} else if (Buffer.isBuffer(body) || typeof body.pipe === 'function') {
|
|
46
|
+
// Never serialize a Buffer or a Readable. These guards mirror
|
|
47
|
+
// `shouldSerialize()` in the ES client, e.g.:
|
|
48
|
+
// https://github.com/elastic/elastic-transport-js/blob/069172506d1fcd544b23747d8c2d497bab053038/src/Transport.ts#L614-L618
|
|
49
|
+
} else if (Array.isArray(body)) {
|
|
50
|
+
try {
|
|
51
|
+
return body.map(JSON.stringify).join('\n') + '\n'; // ndjson
|
|
52
|
+
} catch (_ignoredErr) {}
|
|
53
|
+
} else if (typeof body === 'object') {
|
|
54
|
+
try {
|
|
55
|
+
return JSON.stringify(body);
|
|
56
|
+
} catch (_ignoredErr) {}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
module.exports = {
|
|
62
|
+
getElasticsearchDbStatement,
|
|
63
|
+
};
|
|
@@ -0,0 +1,91 @@
|
|
|
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
|
+
var symbols = require('../symbols');
|
|
12
|
+
|
|
13
|
+
function normalizeSlash(value) {
|
|
14
|
+
return value[0] === '/' ? value : '/' + value;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function excludeRoot(value) {
|
|
18
|
+
return value !== '/';
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
function join(parts) {
|
|
22
|
+
if (!parts) return;
|
|
23
|
+
return parts.filter(excludeRoot).map(normalizeSlash).join('') || '/';
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// This works for both express AND restify
|
|
27
|
+
function routePath(route) {
|
|
28
|
+
if (!route) return;
|
|
29
|
+
return route.path || (route.regexp && route.regexp.source);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function getStackPath(req) {
|
|
33
|
+
var stack = req[symbols.expressMountStack];
|
|
34
|
+
return join(stack);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// This function is also able to extract the path from a Restify request as
|
|
38
|
+
// it's storing the route name on req.route.path as well
|
|
39
|
+
function getPathFromRequest(req, useBase, usePathAsTransactionName) {
|
|
40
|
+
if (req[symbols.staticFile]) {
|
|
41
|
+
return 'static file';
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
var path = getStackPath(req);
|
|
45
|
+
var route = routePath(req.route);
|
|
46
|
+
|
|
47
|
+
if (route) {
|
|
48
|
+
return path ? join([path, route]) : route;
|
|
49
|
+
} else if (path && (path !== '/' || useBase)) {
|
|
50
|
+
return path;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
if (usePathAsTransactionName) {
|
|
54
|
+
// `req.url` is the "request-target" from the HTTP request line
|
|
55
|
+
// (https://www.rfc-editor.org/rfc/rfc7230#section-3.1.1). The special-case
|
|
56
|
+
// handling for leading '/' is because this:
|
|
57
|
+
// GET //foo/bar HTTP/1.1
|
|
58
|
+
// Host: example.com
|
|
59
|
+
// should result in:
|
|
60
|
+
// { host: 'example.com', pathname: '//foo/bar' }
|
|
61
|
+
// and *not*:
|
|
62
|
+
// { host: 'foo', pathname: '/bar' }
|
|
63
|
+
//
|
|
64
|
+
// Assuming 'http://' for the `base` URL is fine, because we don't use the
|
|
65
|
+
// protocol.
|
|
66
|
+
let base;
|
|
67
|
+
try {
|
|
68
|
+
// Host header may contain invalid characters therefore the URL
|
|
69
|
+
// parsing will fail and break the app. This try block is to avoid it
|
|
70
|
+
// Ref: https://github.com/elastic/apm-agent-nodejs/issues/3874
|
|
71
|
+
const url = new url.URL('http://' + (req.headers && req.headers.host));
|
|
72
|
+
base = 'http://' + url.hostname;
|
|
73
|
+
} catch (err) {
|
|
74
|
+
base = 'http://undefined';
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// We may receive invalid chars in the path also but the URL
|
|
78
|
+
// constructor escapes them without throwing.
|
|
79
|
+
const parsed = req.url.startsWith('/')
|
|
80
|
+
? new url.URL(base + req.url)
|
|
81
|
+
: new url.URL(req.url, base);
|
|
82
|
+
|
|
83
|
+
return parsed && parsed.pathname;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
module.exports = {
|
|
88
|
+
getPathFromRequest,
|
|
89
|
+
getStackPath,
|
|
90
|
+
routePath,
|
|
91
|
+
};
|
|
@@ -0,0 +1,322 @@
|
|
|
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 truncate = require('unicode-byte-truncate');
|
|
10
|
+
|
|
11
|
+
const { INTAKE_STRING_MAX_SIZE } = require('../constants');
|
|
12
|
+
const constants = require('../constants');
|
|
13
|
+
const { SpanCompression } = require('./span-compression');
|
|
14
|
+
const Timer = require('./timer');
|
|
15
|
+
const TraceContext = require('../tracecontext');
|
|
16
|
+
const { TraceParent } = require('../tracecontext/traceparent');
|
|
17
|
+
|
|
18
|
+
module.exports = GenericSpan;
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* GenericSpan is an internal base class for Span and Transaction.
|
|
22
|
+
*
|
|
23
|
+
* @param {Agent} agent
|
|
24
|
+
* @param {Object} opts
|
|
25
|
+
* TODO: document supported opts
|
|
26
|
+
*/
|
|
27
|
+
function GenericSpan(agent, opts) {
|
|
28
|
+
this._timer = new Timer(opts.timer, opts.startTime);
|
|
29
|
+
|
|
30
|
+
this._context = TraceContext.startOrResume(
|
|
31
|
+
opts.childOf,
|
|
32
|
+
agent._conf,
|
|
33
|
+
opts.tracestate,
|
|
34
|
+
);
|
|
35
|
+
this._hasPropagatedTraceContext = false;
|
|
36
|
+
|
|
37
|
+
this._parentSpan = null;
|
|
38
|
+
if (opts.childOf instanceof GenericSpan) {
|
|
39
|
+
this.setParentSpan(opts.childOf);
|
|
40
|
+
}
|
|
41
|
+
this._compression = new SpanCompression(agent);
|
|
42
|
+
this._compression.setBufferedSpan(null);
|
|
43
|
+
|
|
44
|
+
this._agent = agent;
|
|
45
|
+
this._labels = null;
|
|
46
|
+
this._ids = null; // Populated by sub-types of GenericSpan
|
|
47
|
+
this._otelKind = null;
|
|
48
|
+
this._otelAttributes = null;
|
|
49
|
+
|
|
50
|
+
this._links = [];
|
|
51
|
+
if (opts.links) {
|
|
52
|
+
for (let i = 0; i < opts.links.length; i++) {
|
|
53
|
+
const link = linkFromLinkArg(opts.links[i]);
|
|
54
|
+
if (link) {
|
|
55
|
+
this._links.push(link);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
this.timestamp = this._timer.start;
|
|
61
|
+
this.ended = false;
|
|
62
|
+
this._duration = null; // Duration in milliseconds. Set on `.end()`.
|
|
63
|
+
this._endTimestamp = null;
|
|
64
|
+
|
|
65
|
+
this.outcome = constants.OUTCOME_UNKNOWN;
|
|
66
|
+
|
|
67
|
+
// Freezing the outcome allows us to prefer a value set from
|
|
68
|
+
// from the API and allows a span to keep its unknown status
|
|
69
|
+
// even if it succesfully ends.
|
|
70
|
+
this._isOutcomeFrozen = false;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
Object.defineProperty(GenericSpan.prototype, 'id', {
|
|
74
|
+
enumerable: true,
|
|
75
|
+
get() {
|
|
76
|
+
return this._context.traceparent.id;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
Object.defineProperty(GenericSpan.prototype, 'traceId', {
|
|
81
|
+
enumerable: true,
|
|
82
|
+
get() {
|
|
83
|
+
return this._context.traceparent.traceId;
|
|
84
|
+
},
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
Object.defineProperty(GenericSpan.prototype, 'parentId', {
|
|
88
|
+
enumerable: true,
|
|
89
|
+
get() {
|
|
90
|
+
return this._context.traceparent.parentId;
|
|
91
|
+
},
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
Object.defineProperty(GenericSpan.prototype, 'sampled', {
|
|
95
|
+
enumerable: true,
|
|
96
|
+
get() {
|
|
97
|
+
return this._context.traceparent.recorded;
|
|
98
|
+
},
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
Object.defineProperty(GenericSpan.prototype, 'sampleRate', {
|
|
102
|
+
enumerable: true,
|
|
103
|
+
get() {
|
|
104
|
+
const rate = parseFloat(this._context.tracestate.getValue('s'));
|
|
105
|
+
if (rate >= 0 && rate <= 1) {
|
|
106
|
+
return rate;
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
},
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
Object.defineProperty(GenericSpan.prototype, 'traceparent', {
|
|
113
|
+
enumerable: true,
|
|
114
|
+
get() {
|
|
115
|
+
return this._context.toString();
|
|
116
|
+
},
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// The duration of the span, in milliseconds.
|
|
120
|
+
GenericSpan.prototype.duration = function () {
|
|
121
|
+
if (!this.ended) {
|
|
122
|
+
this._agent.logger.debug(
|
|
123
|
+
'tried to call duration() on un-ended transaction/span %o',
|
|
124
|
+
{
|
|
125
|
+
id: this.id,
|
|
126
|
+
parent: this.parentId,
|
|
127
|
+
trace: this.traceId,
|
|
128
|
+
name: this.name,
|
|
129
|
+
type: this.type,
|
|
130
|
+
},
|
|
131
|
+
);
|
|
132
|
+
return null;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
return this._duration;
|
|
136
|
+
};
|
|
137
|
+
|
|
138
|
+
// The 'stringify' option is for backward compatibility and will likely be
|
|
139
|
+
// removed in the next major version.
|
|
140
|
+
GenericSpan.prototype.setLabel = function (key, value, stringify = true) {
|
|
141
|
+
const makeLabelValue = () => {
|
|
142
|
+
if (
|
|
143
|
+
!stringify &&
|
|
144
|
+
(typeof value === 'boolean' || typeof value === 'number')
|
|
145
|
+
) {
|
|
146
|
+
return value;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
return truncate(String(value), INTAKE_STRING_MAX_SIZE);
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
if (!key) return false;
|
|
153
|
+
if (!this._labels) this._labels = {};
|
|
154
|
+
var skey = key.replace(/[.*"]/g, '_');
|
|
155
|
+
if (key !== skey) {
|
|
156
|
+
this._agent.logger.warn('Illegal characters used in tag key: %s', key);
|
|
157
|
+
}
|
|
158
|
+
this._labels[skey] = makeLabelValue();
|
|
159
|
+
return true;
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
GenericSpan.prototype.addLabels = function (labels, stringify) {
|
|
163
|
+
if (!labels) return false;
|
|
164
|
+
var keys = Object.keys(labels);
|
|
165
|
+
for (const key of keys) {
|
|
166
|
+
if (!this.setLabel(key, labels[key], stringify)) {
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return true;
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
// Add span links.
|
|
174
|
+
//
|
|
175
|
+
// @param {Array} links - An array of objects with a `context` property that is
|
|
176
|
+
// a Transaction, Span, or TraceParent instance; an OTel SpanContext object;
|
|
177
|
+
// or a W3C trace-context 'traceparent' string.
|
|
178
|
+
GenericSpan.prototype.addLinks = function (links) {
|
|
179
|
+
if (links) {
|
|
180
|
+
for (let i = 0; i < links.length; i++) {
|
|
181
|
+
this.addLink(links[i]);
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
// Add a span link.
|
|
187
|
+
//
|
|
188
|
+
// @param {Link} link - An object with a `context` property that is
|
|
189
|
+
// a Transaction, Span, or TraceParent instance; an OTel SpanContext object;
|
|
190
|
+
// or a W3C trace-context 'traceparent' string.
|
|
191
|
+
GenericSpan.prototype.addLink = function (linkArg) {
|
|
192
|
+
const link = linkFromLinkArg(linkArg);
|
|
193
|
+
if (link) {
|
|
194
|
+
this._links.push(link);
|
|
195
|
+
}
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
GenericSpan.prototype._freezeOutcome = function () {
|
|
199
|
+
this._isOutcomeFrozen = true;
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
GenericSpan.prototype._isValidOutcome = function (outcome) {
|
|
203
|
+
return (
|
|
204
|
+
outcome === constants.OUTCOME_FAILURE ||
|
|
205
|
+
outcome === constants.OUTCOME_SUCCESS ||
|
|
206
|
+
outcome === constants.OUTCOME_UNKNOWN
|
|
207
|
+
);
|
|
208
|
+
};
|
|
209
|
+
|
|
210
|
+
GenericSpan.prototype.propagateTraceContextHeaders = function (
|
|
211
|
+
carrier,
|
|
212
|
+
setter,
|
|
213
|
+
) {
|
|
214
|
+
this._hasPropagatedTraceContext = true;
|
|
215
|
+
return this._context.propagateTraceContextHeaders(carrier, setter);
|
|
216
|
+
};
|
|
217
|
+
GenericSpan.prototype.setParentSpan = function (span) {
|
|
218
|
+
this._parentSpan = span;
|
|
219
|
+
};
|
|
220
|
+
|
|
221
|
+
GenericSpan.prototype.getParentSpan = function (span) {
|
|
222
|
+
return this._parentSpan;
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
GenericSpan.prototype.getBufferedSpan = function () {
|
|
226
|
+
return this._compression.getBufferedSpan();
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
GenericSpan.prototype.setBufferedSpan = function (span) {
|
|
230
|
+
return this._compression.setBufferedSpan(span);
|
|
231
|
+
};
|
|
232
|
+
|
|
233
|
+
GenericSpan.prototype.isCompositeSameKind = function () {
|
|
234
|
+
return this._compression.isCompositeSameKind();
|
|
235
|
+
};
|
|
236
|
+
|
|
237
|
+
GenericSpan.prototype.isComposite = function () {
|
|
238
|
+
return this._compression.isComposite();
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
GenericSpan.prototype.getCompositeSum = function () {
|
|
242
|
+
return this._compression.composite.sum;
|
|
243
|
+
};
|
|
244
|
+
|
|
245
|
+
// https://github.com/elastic/apm/blob/main/specs/agents/tracing-api-otel.md#span-kind
|
|
246
|
+
// @param {String} kind
|
|
247
|
+
GenericSpan.prototype._setOTelKind = function (kind) {
|
|
248
|
+
this._otelKind = kind;
|
|
249
|
+
};
|
|
250
|
+
|
|
251
|
+
// This returns the internal OTel attributes object so it can be mutated.
|
|
252
|
+
GenericSpan.prototype._getOTelAttributes = function () {
|
|
253
|
+
if (!this._otelAttributes) {
|
|
254
|
+
this._otelAttributes = {};
|
|
255
|
+
}
|
|
256
|
+
return this._otelAttributes;
|
|
257
|
+
};
|
|
258
|
+
|
|
259
|
+
// Serialize OTel-related fields into the given payload, if any.
|
|
260
|
+
GenericSpan.prototype._serializeOTel = function (payload) {
|
|
261
|
+
if (this._otelKind) {
|
|
262
|
+
payload.otel = {
|
|
263
|
+
span_kind: this._otelKind,
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
|
|
267
|
+
if (this._otelAttributes) {
|
|
268
|
+
// Though the spec allows it ("MAY"), we are opting *not* to report OTel
|
|
269
|
+
// span attributes as labels for older (<7.16) versions of APM server.
|
|
270
|
+
// This is to avoid the added complexity of guarding allowed attribute
|
|
271
|
+
// value types to those supported by the APM server intake API.
|
|
272
|
+
if (!payload.otel) {
|
|
273
|
+
payload.otel = {};
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
payload.otel.attributes = this._otelAttributes;
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
|
|
280
|
+
// Translate a `opts.links` entry (see the `Link` type in "index.d.ts") to a
|
|
281
|
+
// span link as it will be serialized and sent to APM server. If the linkArg is
|
|
282
|
+
// invalid, this will return null.
|
|
283
|
+
//
|
|
284
|
+
// @param {Object} linkArg - An object with a `context` property that is
|
|
285
|
+
// a Transaction, Span, or TraceParent instance; an OTel SpanContext object;
|
|
286
|
+
// or a W3C trace-context 'traceparent' string.
|
|
287
|
+
function linkFromLinkArg(linkArg) {
|
|
288
|
+
if (!linkArg || !linkArg.context) {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
const ctx = linkArg.context;
|
|
293
|
+
let traceId;
|
|
294
|
+
let spanId;
|
|
295
|
+
|
|
296
|
+
if (ctx.traceId && ctx.spanId) {
|
|
297
|
+
// Duck-typing for an OTel SpanContext. APM intake v2 only supports the
|
|
298
|
+
// trace id and span id fields for span links, so we only need care about
|
|
299
|
+
// those attributes.
|
|
300
|
+
traceId = ctx.traceId;
|
|
301
|
+
spanId = ctx.spanId;
|
|
302
|
+
} else if (ctx._context instanceof TraceContext) {
|
|
303
|
+
// Transaction or Span
|
|
304
|
+
traceId = ctx._context.traceparent.traceId;
|
|
305
|
+
spanId = ctx._context.traceparent.id;
|
|
306
|
+
} else if (ctx instanceof TraceParent) {
|
|
307
|
+
traceId = ctx.traceId;
|
|
308
|
+
spanId = ctx.id;
|
|
309
|
+
} else if (typeof ctx === 'string') {
|
|
310
|
+
// Note: Unfortunately TraceParent.fromString doesn't validate the string.
|
|
311
|
+
const traceparent = TraceParent.fromString(ctx);
|
|
312
|
+
traceId = traceparent.traceId;
|
|
313
|
+
spanId = traceparent.id;
|
|
314
|
+
} else {
|
|
315
|
+
return null;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
return {
|
|
319
|
+
trace_id: traceId,
|
|
320
|
+
span_id: spanId,
|
|
321
|
+
};
|
|
322
|
+
}
|