@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,185 @@
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 { randomFillSync } = require('crypto');
10
+
11
+ const SIZES = {
12
+ version: 1,
13
+ traceId: 16,
14
+ id: 8,
15
+ flags: 1,
16
+ parentId: 8,
17
+
18
+ // Aggregate sizes
19
+ ids: 24, // traceId + id
20
+ all: 34,
21
+ };
22
+
23
+ const OFFSETS = {
24
+ version: 0,
25
+ traceId: SIZES.version,
26
+ id: SIZES.version + SIZES.traceId,
27
+ flags: SIZES.version + SIZES.ids,
28
+
29
+ // Additional parentId is stored after the header content
30
+ parentId: SIZES.version + SIZES.ids + SIZES.flags,
31
+ };
32
+
33
+ const FLAGS = {
34
+ recorded: 0b00000001,
35
+ };
36
+
37
+ function defineLazyProp(obj, prop, fn) {
38
+ Object.defineProperty(obj, prop, {
39
+ configurable: true,
40
+ enumerable: true,
41
+ get() {
42
+ const value = fn();
43
+ if (value !== undefined) {
44
+ Object.defineProperty(obj, prop, {
45
+ configurable: true,
46
+ enumerable: true,
47
+ value,
48
+ });
49
+ }
50
+ return value;
51
+ },
52
+ });
53
+ }
54
+
55
+ function hexSliceFn(buffer, offset, length) {
56
+ return () => buffer.slice(offset, length).toString('hex');
57
+ }
58
+
59
+ function maybeHexSliceFn(buffer, offset, length) {
60
+ const fn = hexSliceFn(buffer, offset, length);
61
+ return () => {
62
+ const value = fn();
63
+ // Check for any non-zero characters to identify a valid ID
64
+ if (/[1-9a-f]/.test(value)) {
65
+ return value;
66
+ }
67
+ };
68
+ }
69
+
70
+ function makeChild(buffer) {
71
+ // Move current id into parentId region
72
+ buffer.copy(buffer, OFFSETS.parentId, OFFSETS.id, OFFSETS.flags);
73
+
74
+ // Generate new id
75
+ randomFillSync(buffer, OFFSETS.id, SIZES.id);
76
+
77
+ return new TraceParent(buffer);
78
+ }
79
+
80
+ function isValidHeader(header) {
81
+ return /^[\da-f]{2}-[\da-f]{32}-[\da-f]{16}-[\da-f]{2}$/.test(header);
82
+ }
83
+
84
+ // NOTE: The version byte is not fully supported yet, but is not important until
85
+ // we use the official header name rather than elastic-apm-traceparent.
86
+ // https://w3c.github.io/distributed-tracing/report-trace-context.html#versioning-of-traceparent
87
+ function headerToBuffer(header) {
88
+ const buffer = Buffer.alloc(SIZES.all);
89
+ buffer.write(header.replace(/-/g, ''), 'hex');
90
+ return buffer;
91
+ }
92
+
93
+ function resume(header) {
94
+ return makeChild(headerToBuffer(header));
95
+ }
96
+
97
+ function start(sampled = false) {
98
+ const buffer = Buffer.alloc(SIZES.all);
99
+
100
+ // Generate new ids
101
+ randomFillSync(buffer, OFFSETS.traceId, SIZES.ids);
102
+
103
+ if (sampled) {
104
+ buffer[OFFSETS.flags] |= FLAGS.recorded;
105
+ }
106
+
107
+ return new TraceParent(buffer);
108
+ }
109
+
110
+ const bufferSymbol = Symbol('trace-context-buffer');
111
+
112
+ class TraceParent {
113
+ constructor(buffer) {
114
+ this[bufferSymbol] = buffer;
115
+ Object.defineProperty(this, 'recorded', {
116
+ enumerable: true,
117
+ get: function () {
118
+ return !!(this[bufferSymbol][OFFSETS.flags] & FLAGS.recorded);
119
+ },
120
+ });
121
+
122
+ defineLazyProp(
123
+ this,
124
+ 'version',
125
+ hexSliceFn(buffer, OFFSETS.version, OFFSETS.traceId),
126
+ );
127
+ defineLazyProp(
128
+ this,
129
+ 'traceId',
130
+ hexSliceFn(buffer, OFFSETS.traceId, OFFSETS.id),
131
+ );
132
+ defineLazyProp(this, 'id', hexSliceFn(buffer, OFFSETS.id, OFFSETS.flags));
133
+ defineLazyProp(
134
+ this,
135
+ 'flags',
136
+ hexSliceFn(buffer, OFFSETS.flags, OFFSETS.parentId),
137
+ );
138
+ defineLazyProp(this, 'parentId', maybeHexSliceFn(buffer, OFFSETS.parentId));
139
+ }
140
+
141
+ static startOrResume(childOf, conf) {
142
+ if (childOf instanceof TraceParent) return childOf.child();
143
+ if (childOf && childOf._context instanceof TraceParent)
144
+ return childOf._context.child();
145
+
146
+ return isValidHeader(childOf)
147
+ ? resume(childOf)
148
+ : start(Math.random() <= conf.transactionSampleRate);
149
+ }
150
+
151
+ static fromString(header) {
152
+ return new TraceParent(headerToBuffer(header));
153
+ }
154
+
155
+ ensureParentId() {
156
+ let id = this.parentId;
157
+ if (!id) {
158
+ randomFillSync(this[bufferSymbol], OFFSETS.parentId, SIZES.id);
159
+ id = this.parentId;
160
+ }
161
+ return id;
162
+ }
163
+
164
+ child() {
165
+ return makeChild(Buffer.from(this[bufferSymbol]));
166
+ }
167
+
168
+ setRecorded(value) {
169
+ if (value) {
170
+ this[bufferSymbol][OFFSETS.flags] |= FLAGS.recorded;
171
+ } else {
172
+ this[bufferSymbol][OFFSETS.flags] &= ~FLAGS.recorded;
173
+ }
174
+ }
175
+
176
+ toString() {
177
+ return `${this.version}-${this.traceId}-${this.id}-${this.flags}`;
178
+ }
179
+ }
180
+
181
+ TraceParent.FLAGS = FLAGS;
182
+
183
+ module.exports = {
184
+ TraceParent,
185
+ };
@@ -0,0 +1,388 @@
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
+ // Indirect usage of the singleton `Agent` to log.
10
+ function getLogger() {
11
+ return require('../..').logger;
12
+ }
13
+
14
+ /**
15
+ * Class for Managing Tracestate
16
+ *
17
+ * Class that creates objects for managing trace state.
18
+ * This class is capable of parsing both tracestate strings
19
+ * and tracestate binary representations, allowing clients
20
+ * to get and set values in a single list-member/namespace
21
+ * while preserving values in the other namespaces.
22
+ *
23
+ * Capable of working with either the binary of string
24
+ * formatted tracestate values.
25
+ *
26
+ * Usage:
27
+ * const tracestate = TraceState.fromStringFormatString(headerTracestate, 'es')
28
+ * tracestate.setValue('s',1)
29
+ * const newHeader = tracestate.toW3cString()
30
+ */
31
+ class TraceState {
32
+ constructor(sourceBuffer, listMemberNamespace = 'es', defaultValues = {}) {
33
+ if (!this._validateVendorKey(listMemberNamespace)) {
34
+ throw new Error('Vendor namespace failed validation.');
35
+ }
36
+
37
+ // buffer representation of the trace state string.
38
+ // The initial value of this.buffer will keep the
39
+ // values set in the listMemberNamespace list-member,
40
+ // but as soon as an initial value is set (via setValue)
41
+ // then the listMemberNamespace values will be removed
42
+ // from this.buffer and stored in the this.values. While
43
+ // slightly more complicated, this allows us to maintain
44
+ // the order of list-member keys in an un-mutated tracestate
45
+ // string, per the W3C spec
46
+ this.buffer = sourceBuffer;
47
+
48
+ this.listMemberNamespace = listMemberNamespace;
49
+
50
+ // values for our namespace, set via setValue to
51
+ // ensure names conform
52
+ this.values = {};
53
+ for (const key in defaultValues) {
54
+ const value = defaultValues[key];
55
+ this.setValue(key, value);
56
+ }
57
+ }
58
+
59
+ setValue(key, value) {
60
+ const strKey = String(key);
61
+ const strValue = String(value);
62
+ if (!this._validateElasicKeyAndValue(strKey, strValue)) {
63
+ getLogger().trace(
64
+ 'could not set tracestate key, invalid characters detected',
65
+ );
66
+ return false;
67
+ }
68
+ const isFirstSet = Object.keys(this.values).length === 0;
69
+ const oldValue = this.values[strKey];
70
+ this.values[strKey] = value;
71
+
72
+ // per: https://github.com/elastic/apm/blob/d5b2c87326548befcfec6731713932a00e430b99/specs/agents/tracing-distributed-tracing.md
73
+ // If adding another key/value pair to the es entry would exceed the limit
74
+ // of 256 chars, that key/value pair MUST be ignored by agents.
75
+ // The key/value and entry separators : and ; have to be considered as well.
76
+ const serializedValue = this._serializeValues(this.values);
77
+ if (serializedValue.length > 256 && typeof oldValue === 'undefined') {
78
+ delete this.values[strKey];
79
+ return false;
80
+ }
81
+ if (serializedValue.length > 256 && typeof oldValue !== 'undefined') {
82
+ this.values[strKey] = oldValue;
83
+ return false;
84
+ }
85
+
86
+ // the first time we set a value, extract the mutable values from the
87
+ // buffer and set this.values appropriately
88
+ if (isFirstSet && Object.keys(this.values).length === 1) {
89
+ const [buffer, values] = TraceState._removeMemberNamespaceFromBuffer(
90
+ this.buffer,
91
+ this.listMemberNamespace,
92
+ );
93
+ this.buffer = buffer;
94
+ this.values = values;
95
+ values[strKey] = value;
96
+ }
97
+
98
+ return true;
99
+ }
100
+
101
+ getValue(keyToGet) {
102
+ const allValues = this.toObject();
103
+ const rawValue = allValues[this.listMemberNamespace];
104
+ if (!rawValue) {
105
+ return rawValue;
106
+ }
107
+ const values = TraceState._parseValues(rawValue);
108
+ return values[keyToGet];
109
+ }
110
+
111
+ toHexString() {
112
+ const newBuffer = Buffer.alloc(this.buffer.length);
113
+ let newBufferOffset = 0;
114
+ for (let i = 0; i < this.buffer.length; i++) {
115
+ const byte = this.buffer[i];
116
+ if (byte === 0) {
117
+ const indexOfKeyLength = i + 1;
118
+ const indexOfKey = i + 2;
119
+ const lengthKey = this.buffer[indexOfKeyLength];
120
+
121
+ const indexOfValueLength = indexOfKey + lengthKey;
122
+ const indexOfValue = indexOfValueLength + 1;
123
+ const lengthValue = this.buffer[indexOfValueLength];
124
+
125
+ const key = this.buffer
126
+ .slice(indexOfKey, indexOfKey + lengthKey)
127
+ .toString();
128
+ // bail out if this is our mutable namespace
129
+ if (key === this.listMemberNamespace) {
130
+ continue;
131
+ }
132
+
133
+ // if this is not our key copy from the `0` byte to the end of the value
134
+ this.buffer.copy(
135
+ newBuffer,
136
+ newBufferOffset,
137
+ i,
138
+ indexOfValue + lengthValue,
139
+ );
140
+ newBufferOffset += indexOfValue + lengthValue;
141
+
142
+ // skip ahead to first byte after end of value
143
+ i = indexOfValue + lengthValue - 1;
144
+ continue;
145
+ }
146
+ }
147
+
148
+ // now serialize the internal representation
149
+ const ourBytes = [];
150
+ if (Object.keys(this.values).length > 0) {
151
+ // the zero byte
152
+ ourBytes.push(0);
153
+
154
+ // the length of the vendor namespace
155
+ ourBytes.push(this.listMemberNamespace.length);
156
+ // the chars of the vendor namespace
157
+ for (let i = 0; i < this.listMemberNamespace.length; i++) {
158
+ ourBytes.push(this.listMemberNamespace.charCodeAt(i));
159
+ }
160
+
161
+ // add the length of the value
162
+ const serializedValue = this._serializeValues(this.values);
163
+ ourBytes.push(serializedValue.length);
164
+
165
+ // add the bytes of the value
166
+ for (let i = 0; i < serializedValue.length; i++) {
167
+ ourBytes.push(serializedValue.charCodeAt(i));
168
+ }
169
+ }
170
+ const ourBuffer = Buffer.from(ourBytes);
171
+ return Buffer.concat(
172
+ [newBuffer, ourBuffer],
173
+ newBuffer.length + ourBuffer.length,
174
+ ).toString('hex');
175
+ }
176
+
177
+ /**
178
+ * Returns JSON reprenstation of tracestate key/value pairs
179
+ *
180
+ * Does not parse the mutable list namespace
181
+ */
182
+ toObject() {
183
+ const map = this.toMap();
184
+ const obj = {};
185
+ for (const key of map.keys()) {
186
+ obj[key] = map.get(key);
187
+ }
188
+ return obj;
189
+ }
190
+
191
+ toMap() {
192
+ const map = new Map();
193
+
194
+ // first, serialize values from the internal representation. This means
195
+ // The W3C spec dictates that mutated values need to be on
196
+ // the left of the new trace string
197
+ if (Object.keys(this.values).length) {
198
+ map.set(this.listMemberNamespace, this._serializeValues(this.values));
199
+ }
200
+ for (let i = 0; i < this.buffer.length; i++) {
201
+ const byte = this.buffer[i];
202
+ if (byte === 0) {
203
+ const indexOfKeyLength = i + 1;
204
+ const indexOfKey = i + 2;
205
+ const lengthKey = this.buffer[indexOfKeyLength];
206
+
207
+ const indexOfValueLength = indexOfKey + lengthKey;
208
+ const indexOfValue = indexOfValueLength + 1;
209
+ const lengthValue = this.buffer[indexOfValueLength];
210
+
211
+ const key = this.buffer
212
+ .slice(indexOfKey, indexOfKey + lengthKey)
213
+ .toString();
214
+ const value = this.buffer
215
+ .slice(indexOfValue, indexOfValue + lengthValue)
216
+ .toString();
217
+
218
+ map.set(key, value);
219
+
220
+ // skip ahead
221
+ i = indexOfValue + lengthValue - 1;
222
+ continue;
223
+ }
224
+ }
225
+
226
+ return map;
227
+ }
228
+
229
+ toString() {
230
+ return this.toW3cString();
231
+ }
232
+
233
+ toW3cString() {
234
+ const json = this.toObject();
235
+ const chars = [];
236
+ for (const key in json) {
237
+ const value = json[key];
238
+ if (!value) {
239
+ continue;
240
+ }
241
+ chars.push(key);
242
+ chars.push('=');
243
+ chars.push(value);
244
+ chars.push(',');
245
+ }
246
+ chars.pop(); // remove final comma
247
+ return chars.join('');
248
+ }
249
+
250
+ _serializeValues(keyValues) {
251
+ const chars = [];
252
+ for (const key in keyValues) {
253
+ const value = keyValues[key];
254
+ chars.push(`${key}:${value}`);
255
+ chars.push(';');
256
+ }
257
+ chars.pop(); // last semi-colon
258
+ return chars.join('');
259
+ }
260
+
261
+ _validateVendorKey(key) {
262
+ if (key.length > 256 || key.length < 1) {
263
+ return false;
264
+ }
265
+ const re = /^[abcdefghijklmnopqrstuvwxyz0123456789_\-*/]*$/;
266
+ if (!key.match(re)) {
267
+ return false;
268
+ }
269
+ return true;
270
+ }
271
+
272
+ _validateElasicKeyAndValue(key, value) {
273
+ // 0x20` to `0x7E WITHOUT `,` or `=` or `;` or `;`
274
+ const re =
275
+ /^[ \][!"#$%&'()*+\-./0123456789<>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ^_abcdefghijklmnopqrstuvwxyz{|}~]*$/;
276
+
277
+ if (!key.match(re) || !value.match(re)) {
278
+ return false;
279
+ }
280
+
281
+ if (key.length > 256 || value.length > 256) {
282
+ return false;
283
+ }
284
+
285
+ return true;
286
+ }
287
+
288
+ static fromBinaryFormatHexString(string, listMemberNamespace = 'es') {
289
+ return new TraceState(Buffer.from(string, 'hex'), listMemberNamespace);
290
+ }
291
+
292
+ static fromStringFormatString(string = '', listMemberNamespace = 'es') {
293
+ // converts string format to byte format
294
+ const bytes = [];
295
+
296
+ const parts = string.split(',');
297
+ for (let part of parts) {
298
+ part = part.trim(); // optional whitespace (OWS)
299
+ if (!part) {
300
+ continue;
301
+ }
302
+ const [listMember, value] = part.split('=');
303
+ if (!listMember || !value) {
304
+ continue;
305
+ }
306
+ bytes.push(0);
307
+ bytes.push(listMember.length);
308
+ for (let i = 0; i < listMember.length; i++) {
309
+ bytes.push(listMember.charCodeAt(i));
310
+ }
311
+ bytes.push(value.length);
312
+ for (let i = 0; i < value.length; i++) {
313
+ bytes.push(value.charCodeAt(i));
314
+ }
315
+ }
316
+
317
+ return new TraceState(Buffer.from(bytes), listMemberNamespace);
318
+ }
319
+
320
+ static _parseValues(rawValues) {
321
+ const parsedValues = {};
322
+ const parts = rawValues.split(';');
323
+ for (const keyValue of parts) {
324
+ if (!keyValue) {
325
+ continue;
326
+ }
327
+ const [key, value] = keyValue.split(':');
328
+ if (!key || !value) {
329
+ continue;
330
+ }
331
+ parsedValues[key] = value;
332
+ }
333
+ return parsedValues;
334
+ }
335
+
336
+ static _removeMemberNamespaceFromBuffer(buffer, listMemberNamespace) {
337
+ const newBuffer = Buffer.alloc(buffer.length);
338
+ let newBufferOffset = 0;
339
+ const values = {};
340
+ for (let i = 0; i < buffer.length; i++) {
341
+ const byte = buffer[i];
342
+ if (byte === 0) {
343
+ const indexOfKeyLength = i + 1;
344
+ const indexOfKey = i + 2;
345
+ const lengthKey = buffer[indexOfKeyLength];
346
+
347
+ const indexOfValueLength = indexOfKey + lengthKey;
348
+ const indexOfValue = indexOfValueLength + 1;
349
+ const lengthValue = buffer[indexOfValueLength];
350
+
351
+ const key = buffer.slice(indexOfKey, indexOfKey + lengthKey).toString();
352
+
353
+ // if this is our mutable namespace extract
354
+ // and set the value in values, otherwise
355
+ // copy into new buffer
356
+ if (key === listMemberNamespace) {
357
+ const rawValues = buffer
358
+ .slice(indexOfValue, indexOfValue + lengthValue)
359
+ .toString();
360
+ const parsedValues = TraceState._parseValues(rawValues);
361
+ for (const key in parsedValues) {
362
+ values[key] = parsedValues[key];
363
+ }
364
+ continue;
365
+ } else {
366
+ buffer.copy(
367
+ newBuffer,
368
+ newBufferOffset,
369
+ i,
370
+ indexOfValue + lengthValue,
371
+ );
372
+ newBufferOffset += indexOfValue + lengthValue - i;
373
+ }
374
+
375
+ // skip ahead to first byte after end of value
376
+ i = indexOfValue + lengthValue - 1;
377
+ continue;
378
+ }
379
+ }
380
+
381
+ // trim off extra 0 bytes
382
+ const trimmedBuffer = newBuffer.slice(0, newBufferOffset);
383
+
384
+ return [trimmedBuffer, values];
385
+ }
386
+ }
387
+
388
+ module.exports = TraceState;
@@ -0,0 +1,52 @@
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
+ * Implements a Wildcard matcher
10
+ *
11
+ * Exports a function that implements a simple wildcard matcher
12
+ * per: https://github.com/elastic/apm/issues/144
13
+ */
14
+ const escapeStringRegexp = require('escape-string-regexp');
15
+
16
+ // Converts elastic-wildcard pattern into a
17
+ // a javascript regular expression.
18
+ const starMatchToRegex = (pattern) => {
19
+ // case insensative by default
20
+ let regexOpts = ['i'];
21
+ if (pattern.startsWith('(?-i)')) {
22
+ regexOpts = [];
23
+ pattern = pattern.slice(5);
24
+ }
25
+
26
+ const patternLength = pattern.length;
27
+ const reChars = ['^'];
28
+ for (let i = 0; i < patternLength; i++) {
29
+ const char = pattern[i];
30
+ switch (char) {
31
+ case '*':
32
+ reChars.push('.*');
33
+ break;
34
+ default:
35
+ reChars.push(escapeStringRegexp(char));
36
+ }
37
+ }
38
+ reChars.push('$');
39
+ return new RegExp(reChars.join(''), regexOpts.join(''));
40
+ };
41
+
42
+ class WildcardMatcher {
43
+ compile(pattern) {
44
+ return starMatchToRegex(pattern);
45
+ }
46
+
47
+ match(string, pattern) {
48
+ const re = this.compile(pattern);
49
+ return string.search(re) !== -1;
50
+ }
51
+ }
52
+ module.exports = { WildcardMatcher };
package/loader.mjs ADDED
@@ -0,0 +1,7 @@
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
+ export * from 'import-in-the-middle/hook.mjs';