@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.
Files changed (154) hide show
  1. package/LICENSE +26 -0
  2. package/NOTICE.md +442 -0
  3. package/README.md +48 -0
  4. package/changes.json +78 -0
  5. package/index.d.ts +398 -0
  6. package/index.js +11 -0
  7. package/lib/InflightEventSet.js +53 -0
  8. package/lib/activation-method.js +119 -0
  9. package/lib/agent.js +941 -0
  10. package/lib/apm-client/apm-client.js +313 -0
  11. package/lib/apm-client/http-apm-client/CHANGELOG.md +271 -0
  12. package/lib/apm-client/http-apm-client/README.md +485 -0
  13. package/lib/apm-client/http-apm-client/central-config.js +41 -0
  14. package/lib/apm-client/http-apm-client/container-info.js +111 -0
  15. package/lib/apm-client/http-apm-client/detect-hostname.js +96 -0
  16. package/lib/apm-client/http-apm-client/index.js +1975 -0
  17. package/lib/apm-client/http-apm-client/logging.js +31 -0
  18. package/lib/apm-client/http-apm-client/ndjson.js +20 -0
  19. package/lib/apm-client/http-apm-client/truncate.js +434 -0
  20. package/lib/apm-client/noop-apm-client.js +73 -0
  21. package/lib/async-hooks-polyfill.js +58 -0
  22. package/lib/cloud-metadata/aws.js +175 -0
  23. package/lib/cloud-metadata/azure.js +123 -0
  24. package/lib/cloud-metadata/callback-coordination.js +159 -0
  25. package/lib/cloud-metadata/gcp.js +133 -0
  26. package/lib/cloud-metadata/index.js +175 -0
  27. package/lib/config/config.js +458 -0
  28. package/lib/config/normalizers.js +701 -0
  29. package/lib/config/schema.js +1007 -0
  30. package/lib/constants.js +35 -0
  31. package/lib/errors.js +303 -0
  32. package/lib/filters/sanitize-field-names.js +69 -0
  33. package/lib/http-request.js +249 -0
  34. package/lib/instrumentation/azure-functions.js +519 -0
  35. package/lib/instrumentation/context.js +56 -0
  36. package/lib/instrumentation/dropped-spans-stats.js +112 -0
  37. package/lib/instrumentation/elasticsearch-shared.js +63 -0
  38. package/lib/instrumentation/express-utils.js +91 -0
  39. package/lib/instrumentation/generic-span.js +322 -0
  40. package/lib/instrumentation/http-shared.js +424 -0
  41. package/lib/instrumentation/ids.js +39 -0
  42. package/lib/instrumentation/index.js +1127 -0
  43. package/lib/instrumentation/modules/@apollo/server.js +30 -0
  44. package/lib/instrumentation/modules/@aws-sdk/client-dynamodb.js +143 -0
  45. package/lib/instrumentation/modules/@aws-sdk/client-s3.js +230 -0
  46. package/lib/instrumentation/modules/@aws-sdk/client-sns.js +197 -0
  47. package/lib/instrumentation/modules/@aws-sdk/client-sqs.js +336 -0
  48. package/lib/instrumentation/modules/@elastic/elasticsearch.js +343 -0
  49. package/lib/instrumentation/modules/@hapi/hapi.js +221 -0
  50. package/lib/instrumentation/modules/@opentelemetry/api.js +86 -0
  51. package/lib/instrumentation/modules/@opentelemetry/sdk-metrics.js +79 -0
  52. package/lib/instrumentation/modules/@redis/client/dist/lib/client/commands-queue.js +178 -0
  53. package/lib/instrumentation/modules/@redis/client/dist/lib/client/index.js +49 -0
  54. package/lib/instrumentation/modules/@smithy/smithy-client.js +198 -0
  55. package/lib/instrumentation/modules/_lambda-handler.js +40 -0
  56. package/lib/instrumentation/modules/apollo-server-core.js +49 -0
  57. package/lib/instrumentation/modules/aws-sdk/dynamodb.js +155 -0
  58. package/lib/instrumentation/modules/aws-sdk/s3.js +184 -0
  59. package/lib/instrumentation/modules/aws-sdk/sns.js +232 -0
  60. package/lib/instrumentation/modules/aws-sdk/sqs.js +361 -0
  61. package/lib/instrumentation/modules/aws-sdk.js +76 -0
  62. package/lib/instrumentation/modules/bluebird.js +93 -0
  63. package/lib/instrumentation/modules/cassandra-driver.js +280 -0
  64. package/lib/instrumentation/modules/elasticsearch.js +191 -0
  65. package/lib/instrumentation/modules/express-graphql.js +66 -0
  66. package/lib/instrumentation/modules/express-queue.js +28 -0
  67. package/lib/instrumentation/modules/express.js +162 -0
  68. package/lib/instrumentation/modules/fastify.js +172 -0
  69. package/lib/instrumentation/modules/finalhandler.js +41 -0
  70. package/lib/instrumentation/modules/generic-pool.js +85 -0
  71. package/lib/instrumentation/modules/graphql.js +256 -0
  72. package/lib/instrumentation/modules/handlebars.js +22 -0
  73. package/lib/instrumentation/modules/http.js +112 -0
  74. package/lib/instrumentation/modules/http2.js +320 -0
  75. package/lib/instrumentation/modules/https.js +68 -0
  76. package/lib/instrumentation/modules/ioredis.js +94 -0
  77. package/lib/instrumentation/modules/jade.js +18 -0
  78. package/lib/instrumentation/modules/kafkajs.js +476 -0
  79. package/lib/instrumentation/modules/knex.js +91 -0
  80. package/lib/instrumentation/modules/koa-router.js +74 -0
  81. package/lib/instrumentation/modules/koa.js +15 -0
  82. package/lib/instrumentation/modules/memcached.js +99 -0
  83. package/lib/instrumentation/modules/mimic-response.js +45 -0
  84. package/lib/instrumentation/modules/mongodb/lib/cmap/connection_pool.js +40 -0
  85. package/lib/instrumentation/modules/mongodb-core.js +206 -0
  86. package/lib/instrumentation/modules/mongodb.js +259 -0
  87. package/lib/instrumentation/modules/mysql.js +200 -0
  88. package/lib/instrumentation/modules/mysql2.js +140 -0
  89. package/lib/instrumentation/modules/pg.js +148 -0
  90. package/lib/instrumentation/modules/pug.js +18 -0
  91. package/lib/instrumentation/modules/redis.js +176 -0
  92. package/lib/instrumentation/modules/restify.js +52 -0
  93. package/lib/instrumentation/modules/tedious.js +159 -0
  94. package/lib/instrumentation/modules/undici.js +270 -0
  95. package/lib/instrumentation/modules/ws.js +59 -0
  96. package/lib/instrumentation/noop-transaction.js +81 -0
  97. package/lib/instrumentation/run-context/AbstractRunContextManager.js +215 -0
  98. package/lib/instrumentation/run-context/AsyncHooksRunContextManager.js +106 -0
  99. package/lib/instrumentation/run-context/AsyncLocalStorageRunContextManager.js +73 -0
  100. package/lib/instrumentation/run-context/BasicRunContextManager.js +82 -0
  101. package/lib/instrumentation/run-context/RunContext.js +151 -0
  102. package/lib/instrumentation/run-context/index.js +23 -0
  103. package/lib/instrumentation/shimmer.js +123 -0
  104. package/lib/instrumentation/span-compression.js +239 -0
  105. package/lib/instrumentation/span.js +621 -0
  106. package/lib/instrumentation/template-shared.js +43 -0
  107. package/lib/instrumentation/timer.js +84 -0
  108. package/lib/instrumentation/transaction.js +571 -0
  109. package/lib/lambda.js +992 -0
  110. package/lib/load-source-map.js +100 -0
  111. package/lib/logging.js +212 -0
  112. package/lib/metrics/index.js +92 -0
  113. package/lib/metrics/platforms/generic/index.js +40 -0
  114. package/lib/metrics/platforms/generic/process-cpu.js +22 -0
  115. package/lib/metrics/platforms/generic/process-top.js +157 -0
  116. package/lib/metrics/platforms/generic/stats.js +34 -0
  117. package/lib/metrics/platforms/generic/system-cpu.js +51 -0
  118. package/lib/metrics/platforms/linux/index.js +19 -0
  119. package/lib/metrics/platforms/linux/stats.js +213 -0
  120. package/lib/metrics/queue.js +90 -0
  121. package/lib/metrics/registry.js +52 -0
  122. package/lib/metrics/reporter.js +119 -0
  123. package/lib/metrics/runtime.js +77 -0
  124. package/lib/middleware/connect.js +16 -0
  125. package/lib/opentelemetry-bridge/OTelBridgeNonRecordingSpan.js +150 -0
  126. package/lib/opentelemetry-bridge/OTelBridgeRunContext.js +124 -0
  127. package/lib/opentelemetry-bridge/OTelContextManager.js +82 -0
  128. package/lib/opentelemetry-bridge/OTelSpan.js +344 -0
  129. package/lib/opentelemetry-bridge/OTelTracer.js +201 -0
  130. package/lib/opentelemetry-bridge/OTelTracerProvider.js +25 -0
  131. package/lib/opentelemetry-bridge/README.md +244 -0
  132. package/lib/opentelemetry-bridge/index.js +15 -0
  133. package/lib/opentelemetry-bridge/oblog.js +23 -0
  134. package/lib/opentelemetry-bridge/opentelemetry-core-mini/README.md +3 -0
  135. package/lib/opentelemetry-bridge/opentelemetry-core-mini/internal/validators.js +52 -0
  136. package/lib/opentelemetry-bridge/opentelemetry-core-mini/trace/TraceState.js +109 -0
  137. package/lib/opentelemetry-bridge/otelutils.js +99 -0
  138. package/lib/opentelemetry-bridge/setup.js +76 -0
  139. package/lib/opentelemetry-metrics/ElasticApmMetricExporter.js +285 -0
  140. package/lib/opentelemetry-metrics/index.js +50 -0
  141. package/lib/parsers.js +225 -0
  142. package/lib/propwrap.js +147 -0
  143. package/lib/stacktraces.js +537 -0
  144. package/lib/symbols.js +15 -0
  145. package/lib/tracecontext/index.js +118 -0
  146. package/lib/tracecontext/traceparent.js +185 -0
  147. package/lib/tracecontext/tracestate.js +388 -0
  148. package/lib/wildcard-matcher.js +52 -0
  149. package/loader.mjs +7 -0
  150. package/package.json +299 -0
  151. package/start.d.ts +8 -0
  152. package/start.js +29 -0
  153. package/types/aws-lambda.d.ts +98 -0
  154. package/types/connect.d.ts +23 -0
@@ -0,0 +1,106 @@
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 asyncHooks = require('async_hooks');
10
+
11
+ const { BasicRunContextManager } = require('./BasicRunContextManager');
12
+
13
+ // A run context manager that uses an async hook to automatically track
14
+ // run context across async tasks.
15
+ //
16
+ // (Adapted from https://github.com/open-telemetry/opentelemetry-js/blob/main/packages/opentelemetry-context-async-hooks/src/AsyncHooksContextManager.ts)
17
+ class AsyncHooksRunContextManager extends BasicRunContextManager {
18
+ constructor(log, runContextClass) {
19
+ super(log, runContextClass);
20
+ this._runContextFromAsyncId = new Map();
21
+ this._asyncHook = asyncHooks.createHook({
22
+ init: this._init.bind(this),
23
+ before: this._before.bind(this),
24
+ after: this._after.bind(this),
25
+ destroy: this._destroy.bind(this),
26
+ promiseResolve: this._destroy.bind(this),
27
+ });
28
+ }
29
+
30
+ enable() {
31
+ super.enable();
32
+ this._asyncHook.enable();
33
+ return this;
34
+ }
35
+
36
+ disable() {
37
+ super.disable();
38
+ this._asyncHook.disable();
39
+ this._runContextFromAsyncId.clear();
40
+ return this;
41
+ }
42
+
43
+ // Reset state for re-use of this context manager by tests in the same process.
44
+ testReset() {
45
+ // Absent a core node async_hooks bug, the easy way to implement this method
46
+ // would be: `this.disable(); this.enable()`.
47
+ // However there is a bug in Node.js v12.0.0 - v12.2.0 (inclusive) where
48
+ // disabling the async hook could result in it never getting re-enabled.
49
+ // https://github.com/nodejs/node/issues/27585
50
+ // https://github.com/nodejs/node/pull/27590 (included in node v12.3.0)
51
+ this._runContextFromAsyncId.clear();
52
+ this._stack = [];
53
+ }
54
+
55
+ /**
56
+ * Init hook will be called when userland create a async context, setting the
57
+ * context as the current one if it exist.
58
+ * @param asyncId id of the async context
59
+ * @param type the resource type
60
+ */
61
+ _init(asyncId, type, triggerAsyncId) {
62
+ // ignore TIMERWRAP as they combine timers with same timeout which can lead to
63
+ // false context propagation. TIMERWRAP has been removed in node 11
64
+ // every timer has it's own `Timeout` resource anyway which is used to propagete
65
+ // context.
66
+ if (type === 'TIMERWRAP') {
67
+ return;
68
+ }
69
+
70
+ const context = this._stack[this._stack.length - 1];
71
+ if (context !== undefined) {
72
+ this._runContextFromAsyncId.set(asyncId, context);
73
+ }
74
+ }
75
+
76
+ /**
77
+ * Destroy hook will be called when a given context is no longer used so we can
78
+ * remove its attached context.
79
+ * @param asyncId id of the async context
80
+ */
81
+ _destroy(asyncId) {
82
+ this._runContextFromAsyncId.delete(asyncId);
83
+ }
84
+
85
+ /**
86
+ * Before hook is called just before executing a async context.
87
+ * @param asyncId id of the async context
88
+ */
89
+ _before(asyncId) {
90
+ const context = this._runContextFromAsyncId.get(asyncId);
91
+ if (context !== undefined) {
92
+ this._enterRunContext(context);
93
+ }
94
+ }
95
+
96
+ /**
97
+ * After hook is called just after completing the execution of a async context.
98
+ */
99
+ _after() {
100
+ this._exitRunContext();
101
+ }
102
+ }
103
+
104
+ module.exports = {
105
+ AsyncHooksRunContextManager,
106
+ };
@@ -0,0 +1,73 @@
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 { AsyncLocalStorage } = require('async_hooks');
10
+
11
+ const { AbstractRunContextManager } = require('./AbstractRunContextManager');
12
+
13
+ /**
14
+ * A RunContextManager that uses core node `AsyncLocalStorage` as the mechanism
15
+ * for run-context tracking.
16
+ *
17
+ * (Adapted from https://github.com/open-telemetry/opentelemetry-js/blob/main/packages/opentelemetry-context-async-hooks/src/AsyncLocalStorageContextManager.ts)
18
+ */
19
+ class AsyncLocalStorageRunContextManager extends AbstractRunContextManager {
20
+ constructor(log, runContextClass) {
21
+ super(log, runContextClass);
22
+ this._asyncLocalStorage = new AsyncLocalStorage();
23
+ }
24
+
25
+ // A string representation useful for debug logging. For example,
26
+ // AsyncLocalStorageRunContextManager( RC(Trans(685ead, manual), [Span(9dd31c, GET httpstat.us, ended)]) )
27
+ toString() {
28
+ return `${this.constructor.name}( ${this.active().toString()} )`;
29
+ }
30
+
31
+ enable() {
32
+ return this;
33
+ }
34
+
35
+ disable() {
36
+ this._asyncLocalStorage.disable();
37
+ return this;
38
+ }
39
+
40
+ // Reset state for re-use of this context manager by tests in the same process.
41
+ testReset() {
42
+ this.disable();
43
+ this.enable();
44
+ }
45
+
46
+ active() {
47
+ const store = this._asyncLocalStorage.getStore();
48
+ if (store == null) {
49
+ return this.root();
50
+ } else {
51
+ return store;
52
+ }
53
+ }
54
+
55
+ with(runContext, fn, thisArg, ...args) {
56
+ const cb = thisArg == null ? fn : fn.bind(thisArg);
57
+ return this._asyncLocalStorage.run(runContext, cb, ...args);
58
+ }
59
+
60
+ // This public method is needed to support the semantics of
61
+ // apm.startTransaction() and apm.startSpan() that impact the current run
62
+ // context.
63
+ //
64
+ // Otherwise, all run context changes are via `.with()` -- scoped to a
65
+ // function call -- or via the "before" async hook -- scoped to an async task.
66
+ supersedeRunContext(runContext) {
67
+ this._asyncLocalStorage.enterWith(runContext);
68
+ }
69
+ }
70
+
71
+ module.exports = {
72
+ AsyncLocalStorageRunContextManager,
73
+ };
@@ -0,0 +1,82 @@
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 { AbstractRunContextManager } = require('./AbstractRunContextManager');
10
+
11
+ // A basic manager for run context. It handles a stack of run contexts, but does
12
+ // no automatic tracking (via async_hooks or otherwise). Use one of the
13
+ // subclasses.
14
+ //
15
+ // (Adapted from https://github.com/open-telemetry/opentelemetry-js/blob/main/packages/opentelemetry-context-async-hooks/src/AsyncHooksContextManager.ts)
16
+ class BasicRunContextManager extends AbstractRunContextManager {
17
+ constructor(log, runContextClass) {
18
+ super(log, runContextClass);
19
+ this._stack = []; // Top of stack is the current run context.
20
+ }
21
+
22
+ // A string representation useful for debug logging. For example,
23
+ // BasicRunContextManager(
24
+ // RC(Trans(685ead, manual), [Span(9dd31c, GET httpstat.us, ended)]),
25
+ // RC(Trans(685ead, manual)) )
26
+ toString() {
27
+ return `${this.constructor.name}( ${this._stack
28
+ .map((rc) => rc.toString())
29
+ .join(', ')} )`;
30
+ }
31
+
32
+ enable() {
33
+ return this;
34
+ }
35
+
36
+ disable() {
37
+ this._stack = [];
38
+ return this;
39
+ }
40
+
41
+ // Reset state for re-use of this context manager by tests in the same process.
42
+ testReset() {
43
+ this.disable();
44
+ this.enable();
45
+ }
46
+
47
+ active() {
48
+ return this._stack[this._stack.length - 1] || this.root();
49
+ }
50
+
51
+ with(runContext, fn, thisArg, ...args) {
52
+ this._enterRunContext(runContext);
53
+ try {
54
+ return fn.call(thisArg, ...args);
55
+ } finally {
56
+ this._exitRunContext();
57
+ }
58
+ }
59
+
60
+ // This public method is needed to support the semantics of
61
+ // apm.startTransaction() and apm.startSpan() that impact the current run
62
+ // context.
63
+ //
64
+ // Otherwise, all run context changes are via `.with()` -- scoped to a
65
+ // function call -- or via the "before" async hook -- scoped to an async task.
66
+ supersedeRunContext(runContext) {
67
+ this._exitRunContext();
68
+ this._enterRunContext(runContext);
69
+ }
70
+
71
+ _enterRunContext(runContext) {
72
+ this._stack.push(runContext);
73
+ }
74
+
75
+ _exitRunContext() {
76
+ this._stack.pop();
77
+ }
78
+ }
79
+
80
+ module.exports = {
81
+ BasicRunContextManager,
82
+ };
@@ -0,0 +1,151 @@
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
+ // A RunContext is the immutable structure that holds which transaction and span
10
+ // are currently active, if any, for the running JavaScript code.
11
+ //
12
+ // Module instrumentation code interacts with run contexts via a number of
13
+ // methods on the `Instrumentation` instance at `agent._instrumentation`.
14
+ //
15
+ // User code using the agent's API (the Agent API, Transaction API, and Span API)
16
+ // are not exposes to RunContext instances. However users of the OpenTelemetry
17
+ // API, provided by the OpenTelemetry Bridge, *are* exposed to OpenTelemetry
18
+ // `Context` instances -- which RunContext implements.
19
+ //
20
+ // A RunContext holds:
21
+ // - a current Transaction, which can be null; and
22
+ // - a *stack* of Spans, where the top-of-stack span is the "current" one.
23
+ // A stack is necessary to support the semantics of multiple started and ended
24
+ // spans in the same async task. E.g.:
25
+ // apm.startTransaction('t')
26
+ // var s1 = apm.startSpan('s1')
27
+ // var s2 = apm.startSpan('s2')
28
+ // s2.end()
29
+ // assert(apm.currentSpan === s1, 's1 is now the current span')
30
+ // - a mapping of "values". This is an arbitrary key-value mapping, but exists
31
+ // primarily to implement OpenTelemetry `interface Context`
32
+ // https://github.com/open-telemetry/opentelemetry-js-api/blob/v1.1.0/src/context/types.ts#L17-L41
33
+ //
34
+ // A RunContext is immutable. This means that `runContext.enterSpan(span)` and
35
+ // other similar methods return a new/separate RunContext instance. This is
36
+ // done so that a run-context change in the current code does not change
37
+ // anything for other code bound to the original RunContext (e.g. via
38
+ // `ins.bindFunction` or `ins.bindEmitter`).
39
+ //
40
+ // Warning: Agent code should never use the `RunContext` class directly
41
+ // because a subclass can be provided for the `Instrumentation` to use.
42
+ // Instead new instances should be built from an existing one, typically the
43
+ // active one (`_runCtxMgr.active()`) or the root one (`_runCtxMgr.root()`).
44
+ class RunContext {
45
+ constructor(trans, spans, parentValues) {
46
+ this._trans = trans || null;
47
+ this._spans = spans || [];
48
+ this._values = parentValues ? new Map(parentValues) : new Map();
49
+ }
50
+
51
+ currTransaction() {
52
+ return this._trans;
53
+ }
54
+
55
+ // Returns the currently active span, if any, otherwise null.
56
+ currSpan() {
57
+ if (this._spans.length > 0) {
58
+ return this._spans[this._spans.length - 1];
59
+ } else {
60
+ return null;
61
+ }
62
+ }
63
+
64
+ // Return a new RunContext for a newly active/current Transaction.
65
+ enterTrans(trans) {
66
+ return new this.constructor(trans, null, this._values);
67
+ }
68
+
69
+ // Return a new RunContext with the given span added to the top of the spans
70
+ // stack.
71
+ enterSpan(span) {
72
+ const newSpans = this._spans.slice();
73
+ newSpans.push(span);
74
+ return new this.constructor(this._trans, newSpans, this._values);
75
+ }
76
+
77
+ // Return a new RunContext with the given transaction (and hence all of its
78
+ // spans) removed.
79
+ leaveTrans() {
80
+ return new this.constructor(null, null, this._values);
81
+ }
82
+
83
+ // Return a new RunContext with the given span removed, or null if there is
84
+ // no change (the given span isn't part of the run context).
85
+ //
86
+ // Typically this span is the top of stack (i.e. it is the current span).
87
+ // However, it is possible to have out-of-order span.end() or even end a span
88
+ // that isn't part of the current run context stack at all. (See
89
+ // test/instrumentation/run-context/fixtures/end-non-current-spans.js for
90
+ // examples.)
91
+ leaveSpan(span) {
92
+ let newRc = null;
93
+ let newSpans;
94
+ const lastSpan = this._spans[this._spans.length - 1];
95
+ if (lastSpan && lastSpan.id === span.id) {
96
+ // Fast path for common case: `span` is top of stack.
97
+ newSpans = this._spans.slice(0, this._spans.length - 1);
98
+ newRc = new this.constructor(this._trans, newSpans, this._values);
99
+ } else {
100
+ const stackIdx = this._spans.findIndex((s) => s.id === span.id);
101
+ if (stackIdx !== -1) {
102
+ newSpans = this._spans
103
+ .slice(0, stackIdx)
104
+ .concat(this._spans.slice(stackIdx + 1));
105
+ newRc = new this.constructor(this._trans, newSpans, this._values);
106
+ }
107
+ }
108
+ return newRc;
109
+ }
110
+
111
+ // A string representation useful for debug logging.
112
+ // For example:
113
+ // RunContext(Transaction(abc123, 'trans name'), [Span(def456, 'span name', ended)])
114
+ // ^^^^^^^-- if the span has ended
115
+ // ^^^^^^ ^^^^^^-- id
116
+ // ^^^^^^^^^^-- the class name, typically "RunContext", but can be overriden
117
+ toString() {
118
+ const bits = [];
119
+ if (this._trans) {
120
+ bits.push(this._trans.toString());
121
+ }
122
+ if (this._spans.length > 0) {
123
+ const spanStrs = this._spans.map((s) => s.toString());
124
+ bits.push('[' + spanStrs + ']');
125
+ }
126
+ return `${this.constructor.name}(${bits.join(', ')})`;
127
+ }
128
+
129
+ // ---- The following implements the OTel Context interface.
130
+ // https://github.com/open-telemetry/opentelemetry-js-api/blob/v1.0.4/src/context/types.ts#L17
131
+
132
+ getValue(key) {
133
+ return this._values.get(key);
134
+ }
135
+
136
+ setValue(key, value) {
137
+ const rc = new this.constructor(this._trans, this._spans, this._values);
138
+ rc._values.set(key, value);
139
+ return rc;
140
+ }
141
+
142
+ deleteValue(key) {
143
+ const rc = new this.constructor(this._trans, this._spans, this._values);
144
+ rc._values.delete(key);
145
+ return rc;
146
+ }
147
+ }
148
+
149
+ module.exports = {
150
+ RunContext,
151
+ };
@@ -0,0 +1,23 @@
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 {
10
+ AsyncHooksRunContextManager,
11
+ } = require('./AsyncHooksRunContextManager');
12
+ const {
13
+ AsyncLocalStorageRunContextManager,
14
+ } = require('./AsyncLocalStorageRunContextManager');
15
+ const { BasicRunContextManager } = require('./BasicRunContextManager');
16
+ const { RunContext } = require('./RunContext');
17
+
18
+ module.exports = {
19
+ AsyncHooksRunContextManager,
20
+ AsyncLocalStorageRunContextManager,
21
+ BasicRunContextManager,
22
+ RunContext,
23
+ };
@@ -0,0 +1,123 @@
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
+ /**
10
+ * This file is extracted from the 'shimmer' project copyright by Forrest L
11
+ * Norvell. It have been modified slightly to be used in the current context.
12
+ *
13
+ * https://github.com/othiym23/shimmer
14
+ *
15
+ * Original file:
16
+ *
17
+ * https://github.com/othiym23/shimmer/blob/master/index.js
18
+ *
19
+ * License:
20
+ *
21
+ * BSD-2-Clause, http://opensource.org/licenses/BSD-2-Clause
22
+ */
23
+
24
+ var symbols = require('../symbols');
25
+
26
+ var isWrappedSym = Symbol('elasticAPMIsWrapped');
27
+
28
+ exports.wrap = wrap;
29
+ exports.massWrap = massWrap;
30
+ exports.unwrap = unwrap;
31
+
32
+ // Do not load agent until used to avoid circular dependency issues.
33
+ var _agent;
34
+ function logger() {
35
+ if (!_agent) _agent = require('../../');
36
+ return _agent.logger;
37
+ }
38
+
39
+ function isFunction(funktion) {
40
+ return typeof funktion === 'function';
41
+ }
42
+
43
+ function wrap(nodule, name, wrapper) {
44
+ if (!nodule || !nodule[name]) {
45
+ logger().debug('no original function %s to wrap', name);
46
+ return;
47
+ }
48
+
49
+ if (!wrapper) {
50
+ logger().debug({ stack: new Error().stack }, 'no wrapper function');
51
+ return;
52
+ }
53
+
54
+ if (!isFunction(nodule[name]) || !isFunction(wrapper)) {
55
+ logger().debug('original object and wrapper must be functions');
56
+ return;
57
+ }
58
+
59
+ if (nodule[name][isWrappedSym]) {
60
+ logger().debug('function %s already wrapped', name);
61
+ return;
62
+ }
63
+
64
+ var desc = Object.getOwnPropertyDescriptor(nodule, name);
65
+ if (desc && !desc.writable) {
66
+ logger().debug('function %s is not writable', name);
67
+ return;
68
+ }
69
+
70
+ var original = nodule[name];
71
+ var wrapped = wrapper(original, name);
72
+
73
+ wrapped[isWrappedSym] = true;
74
+ wrapped[symbols.unwrap] = function elasticAPMUnwrap() {
75
+ if (nodule[name] === wrapped) {
76
+ nodule[name] = original;
77
+ wrapped[isWrappedSym] = false;
78
+ }
79
+ };
80
+
81
+ nodule[name] = wrapped;
82
+
83
+ return wrapped;
84
+ }
85
+
86
+ function massWrap(nodules, names, wrapper) {
87
+ if (!nodules) {
88
+ logger().debug(
89
+ { stack: new Error().stack },
90
+ 'must provide one or more modules to patch',
91
+ );
92
+ return;
93
+ } else if (!Array.isArray(nodules)) {
94
+ nodules = [nodules];
95
+ }
96
+
97
+ if (!(names && Array.isArray(names))) {
98
+ logger().debug('must provide one or more functions to wrap on modules');
99
+ return;
100
+ }
101
+
102
+ for (const nodule of nodules) {
103
+ for (const name of names) {
104
+ wrap(nodule, name, wrapper);
105
+ }
106
+ }
107
+ }
108
+
109
+ function unwrap(nodule, name) {
110
+ if (!nodule || !nodule[name]) {
111
+ logger().debug({ stack: new Error().stack }, 'no function to unwrap');
112
+ return;
113
+ }
114
+
115
+ if (!nodule[name][symbols.unwrap]) {
116
+ logger().debug(
117
+ 'no original to unwrap to -- has %s already been unwrapped?',
118
+ name,
119
+ );
120
+ } else {
121
+ return nodule[name][symbols.unwrap]();
122
+ }
123
+ }