dd-trace 2.25.1 → 2.26.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/index.d.ts +50 -0
- package/package.json +1 -1
- package/packages/datadog-instrumentations/src/fs.js +350 -4
- package/packages/datadog-instrumentations/src/helpers/hooks.js +2 -0
- package/packages/datadog-instrumentations/src/jest.js +11 -1
- package/packages/datadog-instrumentations/src/mocha.js +3 -2
- package/packages/datadog-instrumentations/src/mysql.js +7 -1
- package/packages/datadog-instrumentations/src/mysql2.js +7 -1
- package/packages/datadog-instrumentations/src/playwright.js +236 -0
- package/packages/datadog-plugin-fs/src/index.js +37 -574
- package/packages/datadog-plugin-jest/src/index.js +45 -23
- package/packages/datadog-plugin-mocha/src/index.js +34 -6
- package/packages/datadog-plugin-mysql/src/index.js +8 -7
- package/packages/datadog-plugin-playwright/src/index.js +171 -0
- package/packages/dd-trace/src/appsec/callbacks/ddwaf.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/analyzers.js +1 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/path-traversal-analyzer.js +60 -0
- package/packages/dd-trace/src/appsec/index.js +1 -1
- package/packages/dd-trace/src/appsec/recommended.json +247 -112
- package/packages/dd-trace/src/appsec/sdk/index.js +23 -0
- package/packages/dd-trace/src/appsec/sdk/noop.js +11 -0
- package/packages/dd-trace/src/appsec/sdk/track_event.js +74 -0
- package/packages/dd-trace/src/appsec/sdk/utils.js +10 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +1 -1
- package/packages/dd-trace/src/config.js +7 -0
- package/packages/dd-trace/src/encode/agentless-ci-visibility.js +44 -4
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +52 -37
- package/packages/dd-trace/src/log/channels.js +47 -0
- package/packages/dd-trace/src/log/index.js +79 -0
- package/packages/dd-trace/src/log/writer.js +108 -0
- package/packages/dd-trace/src/noop/proxy.js +3 -0
- package/packages/dd-trace/src/plugins/index.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -21
- package/packages/dd-trace/src/{appsec → plugins/util}/ip_blocklist.js +0 -0
- package/packages/dd-trace/src/{appsec → plugins/util}/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/test.js +27 -10
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +2 -7
- package/packages/dd-trace/src/plugins/util/web.js +11 -0
- package/packages/dd-trace/src/proxy.js +2 -0
- package/packages/dd-trace/src/startup-log.js +1 -1
- package/scripts/check-proposal-labels.js +71 -0
- package/packages/dd-trace/src/log.js +0 -143
|
@@ -1,582 +1,45 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
const
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
fchown: createFchownTags,
|
|
41
|
-
realpath: createPathTags,
|
|
42
|
-
readlink: createPathTags,
|
|
43
|
-
unlink: createPathTags,
|
|
44
|
-
symlink: createCopyFileTags,
|
|
45
|
-
link: createCopyFileTags,
|
|
46
|
-
rmdir: createPathTags,
|
|
47
|
-
rename: createCopyFileTags,
|
|
48
|
-
fsync: createFDTags,
|
|
49
|
-
fdatasync: createFDTags,
|
|
50
|
-
mkdir: createPathTags,
|
|
51
|
-
truncate: createPathTags,
|
|
52
|
-
ftruncate: createFDTags,
|
|
53
|
-
utimes: createPathTags,
|
|
54
|
-
futimes: createFDTags,
|
|
55
|
-
mkdtemp: createPathTags
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
const promisifiable = ['read', 'readv', 'write', 'writev']
|
|
59
|
-
|
|
60
|
-
const orphanable = false
|
|
61
|
-
|
|
62
|
-
function createWrapCreateReadStream (config, tracer) {
|
|
63
|
-
return function wrapCreateReadStream (createReadStream) {
|
|
64
|
-
return function createReadStreamWithTrace (path, options) {
|
|
65
|
-
if (!hasParent()) {
|
|
66
|
-
return createReadStream.apply(this, arguments)
|
|
3
|
+
const TracingPlugin = require('../../dd-trace/src/plugins/tracing')
|
|
4
|
+
|
|
5
|
+
class FsPlugin extends TracingPlugin {
|
|
6
|
+
static get name () { return 'fs' }
|
|
7
|
+
static get operation () { return 'operation' }
|
|
8
|
+
|
|
9
|
+
configure (...args) {
|
|
10
|
+
return super.configure(...args)
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
start ({ operation, ...params }) {
|
|
14
|
+
if (!this.activeSpan) return this.skip()
|
|
15
|
+
|
|
16
|
+
const lowerOp = operation.toLowerCase()
|
|
17
|
+
const flag = params.flag || params.flags || (params.options && (params.options.flag || params.options.flags))
|
|
18
|
+
const defaultFlag = ((lowerOp.includes('open') || lowerOp.includes('read')) && 'r') ||
|
|
19
|
+
(lowerOp.includes('write') && 'w') ||
|
|
20
|
+
(lowerOp.includes('append') && 'a')
|
|
21
|
+
const fd = params.fd || (typeof params.file === 'number' && params.file)
|
|
22
|
+
const path = params.path || params.prefix || params.filename || (typeof params.file === 'string' && params.file)
|
|
23
|
+
const uid = typeof params.uid === 'number' && params.uid.toString()
|
|
24
|
+
const gid = typeof params.gid === 'number' && params.gid.toString()
|
|
25
|
+
const mode = typeof params.mode === 'number' ? params.mode.toString(8) : params.mode
|
|
26
|
+
|
|
27
|
+
this.startSpan('fs.operation', {
|
|
28
|
+
service: this.config.service,
|
|
29
|
+
resource: operation,
|
|
30
|
+
kind: 'internal',
|
|
31
|
+
meta: {
|
|
32
|
+
'file.descriptor': (typeof fd === 'object' || typeof fd === 'number') ? fd.toString() : '',
|
|
33
|
+
'file.dest': params.dest || params.newPath || (params.target && params.path),
|
|
34
|
+
'file.flag': String(flag || defaultFlag || ''),
|
|
35
|
+
'file.gid': gid || '',
|
|
36
|
+
'file.mode': mode,
|
|
37
|
+
'file.path': path || '',
|
|
38
|
+
'file.src': params.src || params.oldPath || params.existingPath || params.target,
|
|
39
|
+
'file.uid': uid || ''
|
|
67
40
|
}
|
|
68
|
-
const tags = makeFSFlagTags('ReadStream', path, options, 'r', config, tracer)
|
|
69
|
-
return tracer.trace('fs.operation', { tags, orphanable }, (span, done) => {
|
|
70
|
-
const stream = createReadStream.apply(this, arguments)
|
|
71
|
-
stream.once('close', done)
|
|
72
|
-
stream.once('end', done)
|
|
73
|
-
stream.once('error', done)
|
|
74
|
-
return stream
|
|
75
|
-
})
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function createWrapCreateWriteStream (config, tracer) {
|
|
81
|
-
return function wrapCreateWriteStream (createWriteStream) {
|
|
82
|
-
return function createWriteStreamWithTrace (path, options) {
|
|
83
|
-
const tags = makeFSFlagTags('WriteStream', path, options, 'w', config, tracer)
|
|
84
|
-
return tracer.trace('fs.operation', { tags, orphanable }, (span, done) => {
|
|
85
|
-
const stream = createWriteStream.apply(this, arguments)
|
|
86
|
-
stream.once('close', done)
|
|
87
|
-
stream.once('finish', done)
|
|
88
|
-
stream.once('error', done)
|
|
89
|
-
return stream
|
|
90
|
-
})
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
function createWrapExists (config, tracer) {
|
|
96
|
-
return function wrapExists (exists) {
|
|
97
|
-
const existsWithTrace = function existsWithTrace (path, cb) {
|
|
98
|
-
if (typeof cb !== 'function') {
|
|
99
|
-
return exists.apply(this, arguments)
|
|
100
|
-
}
|
|
101
|
-
const tags = makeFSTags('exists', path, null, config, tracer)
|
|
102
|
-
return tracer.trace('fs.operation', { tags, orphanable }, (span, done) => {
|
|
103
|
-
arguments[1] = function (result) {
|
|
104
|
-
done()
|
|
105
|
-
cb.apply(this, arguments)
|
|
106
|
-
}
|
|
107
|
-
return exists.apply(this, arguments)
|
|
108
|
-
})
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
copySymbols(exists, existsWithTrace)
|
|
112
|
-
|
|
113
|
-
return existsWithTrace
|
|
114
|
-
}
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
function createWrapDirRead (config, tracer, sync) {
|
|
118
|
-
const name = sync ? 'dir.readSync' : 'dir.read'
|
|
119
|
-
return function wrapDirRead (read) {
|
|
120
|
-
function options () {
|
|
121
|
-
const tags = makeFSTags(name, this.path, null, config, tracer)
|
|
122
|
-
return { tags, orphanable }
|
|
123
|
-
}
|
|
124
|
-
return tracer.wrap('fs.operation', options, read, true)
|
|
125
|
-
}
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
function createWrapDirClose (config, tracer, sync) {
|
|
129
|
-
const name = sync ? 'dir.closeSync' : 'dir.close'
|
|
130
|
-
return function wrapDirClose (close) {
|
|
131
|
-
function options () {
|
|
132
|
-
const tags = makeFSTags(name, this.path, null, config, tracer)
|
|
133
|
-
return { tags, orphanable }
|
|
134
|
-
}
|
|
135
|
-
return tracer.wrap('fs.operation', options, close, true)
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
function createWrapDirAsyncIterator (config, tracer, instrumenter) {
|
|
140
|
-
return function wrapDirAsyncIterator (asyncIterator) {
|
|
141
|
-
return function asyncIteratorWithTrace () {
|
|
142
|
-
if (!kDirReadPromisified) {
|
|
143
|
-
const keys = Reflect.ownKeys(this)
|
|
144
|
-
for (const key of keys) {
|
|
145
|
-
if (kDirReadPromisified && kDirClosePromisified) break
|
|
146
|
-
if (typeof key !== 'symbol') continue
|
|
147
|
-
if (!kDirReadPromisified && getSymbolName(key).includes('kDirReadPromisified')) {
|
|
148
|
-
kDirReadPromisified = key
|
|
149
|
-
}
|
|
150
|
-
if (!kDirClosePromisified && getSymbolName(key).includes('kDirClosePromisified')) {
|
|
151
|
-
kDirClosePromisified = key
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
shimmer.wrap(this, kDirReadPromisified, createWrapDirRead(config, tracer))
|
|
156
|
-
shimmer.wrap(this, kDirClosePromisified, createWrapKDirClose(config, tracer, instrumenter))
|
|
157
|
-
return asyncIterator.apply(this, arguments)
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
function createWrapKDirClose (config, tracer, instrumenter) {
|
|
163
|
-
return function wrapKDirClose (kDirClose) {
|
|
164
|
-
return function kDirCloseWithTrace () {
|
|
165
|
-
const tags = makeFSTags('dir.close', this.path, null, config, tracer)
|
|
166
|
-
return tracer.trace('fs.operation', { tags, orphanable }, (span) => {
|
|
167
|
-
const p = kDirClose.apply(this, arguments)
|
|
168
|
-
const unwrapBoth = () => {
|
|
169
|
-
shimmer.unwrap(this, kDirReadPromisified)
|
|
170
|
-
shimmer.unwrap(this, kDirClosePromisified)
|
|
171
|
-
}
|
|
172
|
-
p.then(unwrapBoth, unwrapBoth)
|
|
173
|
-
return p
|
|
174
|
-
})
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
function createOpenTags (resourceName, config, tracer) {
|
|
180
|
-
return function openTags (path, flag, mode) {
|
|
181
|
-
if (!flag || typeof flag === 'function') {
|
|
182
|
-
flag = null
|
|
183
|
-
}
|
|
184
|
-
return makeFSFlagTags(resourceName, path, { flag }, 'r', config, tracer)
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
function createCloseTags (resourceName, config, tracer) {
|
|
189
|
-
return function closeTags (fd) {
|
|
190
|
-
if (typeof fd === 'undefined' && this && this[ddFhSym]) {
|
|
191
|
-
fd = this[ddFhSym].fd
|
|
192
|
-
}
|
|
193
|
-
if (typeof fd !== 'number' || !Number.isInteger(fd)) {
|
|
194
|
-
return
|
|
195
|
-
}
|
|
196
|
-
return makeFSTags(resourceName, fd, null, config, tracer)
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
function createReadFileTags (resourceName, config, tracer) {
|
|
201
|
-
return function readFileTags (path, options) {
|
|
202
|
-
return makeFSFlagTags(resourceName, path, options, 'r', config, tracer)
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
function createWriteFileTags (resourceName, config, tracer) {
|
|
207
|
-
return function writeFileTags (path, data, options) {
|
|
208
|
-
return makeFSFlagTags(resourceName, path, options, 'w', config, tracer)
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
function createAppendFileTags (resourceName, config, tracer) {
|
|
213
|
-
return function appendFileTags (path, data, options) {
|
|
214
|
-
return makeFSFlagTags(resourceName, path, options, 'a', config, tracer)
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
function createCopyFileTags (resourceName, config, tracer) {
|
|
219
|
-
return function copyFileTags (src, dest, flag) {
|
|
220
|
-
return makeFSTags(resourceName, { src, dest }, null, config, tracer)
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
function createChmodTags (resourceName, config, tracer) {
|
|
225
|
-
return function chmodTags (fd, mode) {
|
|
226
|
-
const tags = makeFSTags(resourceName, fd, null, config, tracer)
|
|
227
|
-
tags['file.mode'] = mode.toString(8)
|
|
228
|
-
return tags
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
function createFchmodTags (resourceName, config, tracer) {
|
|
233
|
-
return function fchmodTags (fd, mode) {
|
|
234
|
-
if (typeof this === 'object' && this !== null && this.fd) {
|
|
235
|
-
mode = fd
|
|
236
|
-
fd = this.fd
|
|
237
|
-
}
|
|
238
|
-
|
|
239
|
-
const tags = makeFSTags(resourceName, fd, null, config, tracer)
|
|
240
|
-
if (mode) {
|
|
241
|
-
tags['file.mode'] = mode.toString(8)
|
|
242
|
-
}
|
|
243
|
-
return tags
|
|
244
|
-
}
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
function createPathTags (resourceName, config, tracer) {
|
|
248
|
-
return function pathTags (path) {
|
|
249
|
-
return makeFSTags(resourceName, path, null, config, tracer)
|
|
250
|
-
}
|
|
251
|
-
}
|
|
252
|
-
|
|
253
|
-
function createFDTags (resourceName, config, tracer) {
|
|
254
|
-
return function fdTags (fd) {
|
|
255
|
-
if (typeof this === 'object' && this !== null && this.fd) {
|
|
256
|
-
fd = this.fd
|
|
257
|
-
}
|
|
258
|
-
return makeFSTags(resourceName, fd, null, config, tracer)
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
function createChownTags (resourceName, config, tracer) {
|
|
263
|
-
return function chownTags (fd, uid, gid) {
|
|
264
|
-
const tags = makeFSTags(resourceName, fd, null, config, tracer)
|
|
265
|
-
if (typeof uid === 'number') {
|
|
266
|
-
tags['file.uid'] = uid.toString()
|
|
267
|
-
}
|
|
268
|
-
if (typeof gid === 'number') {
|
|
269
|
-
tags['file.gid'] = gid.toString()
|
|
270
|
-
}
|
|
271
|
-
return tags
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
function createFchownTags (resourceName, config, tracer) {
|
|
276
|
-
return function fchownTags (fd, uid, gid) {
|
|
277
|
-
if (typeof this === 'object' && this !== null && this.fd) {
|
|
278
|
-
gid = uid
|
|
279
|
-
uid = fd
|
|
280
|
-
fd = this.fd
|
|
281
|
-
}
|
|
282
|
-
const tags = makeFSTags(resourceName, fd, null, config, tracer)
|
|
283
|
-
if (typeof uid === 'number') {
|
|
284
|
-
tags['file.uid'] = uid.toString()
|
|
285
|
-
}
|
|
286
|
-
if (typeof gid === 'number') {
|
|
287
|
-
tags['file.gid'] = gid.toString()
|
|
288
|
-
}
|
|
289
|
-
return tags
|
|
290
|
-
}
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
function getSymbolName (sym) {
|
|
294
|
-
return sym.description || sym.toString()
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
function hasParent () {
|
|
298
|
-
const store = storage.getStore()
|
|
299
|
-
|
|
300
|
-
return store && store.span && !store.noop
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
function createWrapCb (tracer, config, name, tagMaker) {
|
|
304
|
-
const makeTags = tagMaker(name, config, tracer)
|
|
305
|
-
return function wrapFunction (fn) {
|
|
306
|
-
return tracer.wrap('fs.operation', function () {
|
|
307
|
-
if (typeof arguments[arguments.length - 1] !== 'function') {
|
|
308
|
-
return
|
|
309
|
-
}
|
|
310
|
-
const tags = makeTags.apply(this, arguments)
|
|
311
|
-
return tags ? { tags, orphanable } : { orphanable }
|
|
312
|
-
}, fn, true)
|
|
313
|
-
}
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
function createWrap (tracer, config, name, tagMaker) {
|
|
317
|
-
const makeTags = tagMaker(name, config, tracer)
|
|
318
|
-
|
|
319
|
-
return function wrapSyncFunction (fn) {
|
|
320
|
-
return tracer.wrap('fs.operation', function () {
|
|
321
|
-
const tags = makeTags.apply(this, arguments)
|
|
322
|
-
return tags ? { tags, orphanable } : { orphanable }
|
|
323
|
-
}, fn, true)
|
|
324
|
-
}
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
function makeFSFlagTags (resourceName, path, options, defaultFlag, config, tracer) {
|
|
328
|
-
const tags = makeFSTags(resourceName, path, options, config, tracer)
|
|
329
|
-
|
|
330
|
-
if (tags) {
|
|
331
|
-
let flag = defaultFlag
|
|
332
|
-
if (typeof options === 'object' && options !== null) {
|
|
333
|
-
if (options.flag) {
|
|
334
|
-
flag = options.flag
|
|
335
|
-
} else if (options.flags) {
|
|
336
|
-
flag = options.flags
|
|
337
|
-
}
|
|
338
|
-
}
|
|
339
|
-
tags['file.flag'] = flag
|
|
340
|
-
return tags
|
|
341
|
-
}
|
|
342
|
-
}
|
|
343
|
-
|
|
344
|
-
function makeFSTags (resourceName, path, options, config, tracer) {
|
|
345
|
-
path = options && typeof options === 'object' && 'fd' in options ? options.fd : path
|
|
346
|
-
const tags = {
|
|
347
|
-
'component': 'fs',
|
|
348
|
-
'span.kind': 'internal',
|
|
349
|
-
'resource.name': resourceName,
|
|
350
|
-
'service.name': fsConfig.service || tracer._service
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
switch (typeof path) {
|
|
354
|
-
case 'object': {
|
|
355
|
-
if (path === null) return tags
|
|
356
|
-
const src = 'src' in path ? path.src : null
|
|
357
|
-
const dest = 'dest' in path ? path.dest : null
|
|
358
|
-
if (src || dest) {
|
|
359
|
-
tags['file.src'] = src
|
|
360
|
-
tags['file.dest'] = dest
|
|
361
|
-
} else {
|
|
362
|
-
tags['file.path'] = path
|
|
363
|
-
}
|
|
364
|
-
break
|
|
365
|
-
}
|
|
366
|
-
case 'string': {
|
|
367
|
-
tags['file.path'] = path
|
|
368
|
-
break
|
|
369
|
-
}
|
|
370
|
-
case 'number': {
|
|
371
|
-
tags['file.descriptor'] = path.toString()
|
|
372
|
-
break
|
|
373
|
-
}
|
|
374
|
-
}
|
|
375
|
-
|
|
376
|
-
return tags
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
function copySymbols (from, to) {
|
|
380
|
-
const props = Object.getOwnPropertyDescriptors(from)
|
|
381
|
-
const keys = Reflect.ownKeys(props)
|
|
382
|
-
|
|
383
|
-
for (const key of keys) {
|
|
384
|
-
if (typeof key !== 'symbol' || to.hasOwnProperty(key)) continue
|
|
385
|
-
|
|
386
|
-
Object.defineProperty(to, key, props[key])
|
|
387
|
-
}
|
|
388
|
-
}
|
|
389
|
-
|
|
390
|
-
function getFileHandlePrototype (fs) {
|
|
391
|
-
return fs.promises.open(__filename, 'r')
|
|
392
|
-
.then(fh => {
|
|
393
|
-
if (!kHandle) {
|
|
394
|
-
kHandle = Reflect.ownKeys(fh).find(key => typeof key === 'symbol' && key.toString().includes('kHandle'))
|
|
395
|
-
}
|
|
396
|
-
fh.close()
|
|
397
|
-
|
|
398
|
-
return Object.getPrototypeOf(fh)
|
|
399
41
|
})
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
function patchClassicFunctions (fs, tracer, config) {
|
|
403
|
-
for (const name in fs) {
|
|
404
|
-
if (!fs[name]) continue
|
|
405
|
-
const tagMakerName = name.endsWith('Sync') ? name.substr(0, name.length - 4) : name
|
|
406
|
-
const original = fs[name]
|
|
407
|
-
if (tagMakerName in tagMakers) {
|
|
408
|
-
const tagMaker = tagMakers[tagMakerName]
|
|
409
|
-
if (name.endsWith('Sync')) {
|
|
410
|
-
shimmer.wrap(fs, name, createWrap(tracer, config, name, tagMaker))
|
|
411
|
-
} else {
|
|
412
|
-
shimmer.wrap(fs, name, createWrapCb(tracer, config, name, tagMaker))
|
|
413
|
-
}
|
|
414
|
-
if (name in promisifiable) {
|
|
415
|
-
copySymbols(original, fs[name])
|
|
416
|
-
}
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
|
|
421
|
-
function patchFileHandle (fs, tracer, config) {
|
|
422
|
-
getFileHandlePrototype(fs).then((fileHandlePrototype) => {
|
|
423
|
-
for (const name of Reflect.ownKeys(fileHandlePrototype)) {
|
|
424
|
-
if (typeof name !== 'string' || name === 'constructor' || name === 'fd' || name === 'getAsyncId') {
|
|
425
|
-
continue
|
|
426
|
-
}
|
|
427
|
-
let tagMaker
|
|
428
|
-
const fName = 'f' + name
|
|
429
|
-
if (fName in tagMakers) {
|
|
430
|
-
tagMaker = tagMakers[fName]
|
|
431
|
-
} else {
|
|
432
|
-
tagMaker = createFDTags
|
|
433
|
-
}
|
|
434
|
-
|
|
435
|
-
const desc = Reflect.getOwnPropertyDescriptor(fileHandlePrototype, kHandle)
|
|
436
|
-
if (!desc || !desc.get) {
|
|
437
|
-
Reflect.defineProperty(fileHandlePrototype, kHandle, {
|
|
438
|
-
get () {
|
|
439
|
-
return this[ddFhSym]
|
|
440
|
-
},
|
|
441
|
-
set (h) {
|
|
442
|
-
this[ddFhSym] = h
|
|
443
|
-
shimmer.wrap(this, 'close', createWrap(tracer, config, 'filehandle.close', tagMakers.close))
|
|
444
|
-
},
|
|
445
|
-
configurable: true
|
|
446
|
-
})
|
|
447
|
-
}
|
|
448
|
-
|
|
449
|
-
shimmer.wrap(fileHandlePrototype, name, createWrap(tracer, config, 'filehandle.' + name, tagMaker))
|
|
450
|
-
}
|
|
451
|
-
})
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
function patchPromiseFunctions (fs, tracer, config) {
|
|
455
|
-
for (const name in fs.promises) {
|
|
456
|
-
if (name in tagMakers) {
|
|
457
|
-
const tagMaker = tagMakers[name]
|
|
458
|
-
shimmer.wrap(fs.promises, name, createWrap(tracer, config, 'promises.' + name, tagMaker))
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
}
|
|
462
|
-
|
|
463
|
-
function patchDirFunctions (fs, tracer, config) {
|
|
464
|
-
shimmer.wrap(fs.Dir.prototype, 'close', createWrapDirClose(config, tracer))
|
|
465
|
-
shimmer.wrap(fs.Dir.prototype, 'closeSync', createWrapDirClose(config, tracer, true))
|
|
466
|
-
shimmer.wrap(fs.Dir.prototype, 'read', createWrapDirRead(config, tracer))
|
|
467
|
-
shimmer.wrap(fs.Dir.prototype, 'readSync', createWrapDirRead(config, tracer, true))
|
|
468
|
-
shimmer.wrap(fs.Dir.prototype, Symbol.asyncIterator, createWrapDirAsyncIterator(config, tracer, this))
|
|
469
|
-
}
|
|
470
|
-
|
|
471
|
-
function unpatchClassicFunctions (fs) {
|
|
472
|
-
for (const name in fs) {
|
|
473
|
-
if (!fs[name]) continue
|
|
474
|
-
const tagMakerName = name.endsWith('Sync') ? name.substr(0, name.length - 4) : name
|
|
475
|
-
if (tagMakerName in tagMakers) {
|
|
476
|
-
shimmer.unwrap(fs, name)
|
|
477
|
-
}
|
|
478
|
-
}
|
|
479
|
-
}
|
|
480
|
-
|
|
481
|
-
function unpatchFileHandle (fs) {
|
|
482
|
-
getFileHandlePrototype(fs).then(fileHandlePrototype => {
|
|
483
|
-
for (const name of Reflect.ownKeys(fileHandlePrototype)) {
|
|
484
|
-
if (typeof name !== 'string' || name === 'constructor' || name === 'fd' || name === 'getAsyncId') {
|
|
485
|
-
continue
|
|
486
|
-
}
|
|
487
|
-
shimmer.unwrap(fileHandlePrototype, name)
|
|
488
|
-
}
|
|
489
|
-
delete fileHandlePrototype[kHandle]
|
|
490
|
-
})
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
function unpatchPromiseFunctions (fs) {
|
|
494
|
-
for (const name in fs.promises) {
|
|
495
|
-
if (name in tagMakers) {
|
|
496
|
-
shimmer.unwrap(fs.promises, name)
|
|
497
|
-
}
|
|
498
|
-
}
|
|
499
|
-
}
|
|
500
|
-
|
|
501
|
-
function unpatchDirFunctions (fs) {
|
|
502
|
-
shimmer.unwrap(fs.Dir.prototype, 'close')
|
|
503
|
-
shimmer.unwrap(fs.Dir.prototype, 'closeSync')
|
|
504
|
-
shimmer.unwrap(fs.Dir.prototype, 'read')
|
|
505
|
-
shimmer.unwrap(fs.Dir.prototype, 'readSync')
|
|
506
|
-
shimmer.unwrap(fs.Dir.prototype, Symbol.asyncIterator)
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
const hookChannel = channel('apm:fs:hook')
|
|
510
|
-
|
|
511
|
-
hookChannel.subscribe(fs => {
|
|
512
|
-
fsInstance = fs
|
|
513
|
-
})
|
|
514
|
-
|
|
515
|
-
class FsPlugin extends Plugin {
|
|
516
|
-
static get name () {
|
|
517
|
-
return 'fs'
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
configure (config) {
|
|
521
|
-
fsConfig = config
|
|
522
|
-
|
|
523
|
-
super.configure(config)
|
|
524
|
-
|
|
525
|
-
this._unpatch()
|
|
526
|
-
|
|
527
|
-
if (this._enabled) {
|
|
528
|
-
this._patch()
|
|
529
|
-
}
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
_patch () {
|
|
533
|
-
const fs = fsInstance
|
|
534
|
-
const tracer = this.tracer
|
|
535
|
-
const config = this.config
|
|
536
|
-
const realpathNative = fs.realpath.native
|
|
537
|
-
const realpathSyncNative = fs.realpathSync.native
|
|
538
|
-
patchClassicFunctions.call(this, fs, tracer, config)
|
|
539
|
-
if (fs.promises) {
|
|
540
|
-
patchFileHandle.call(this, fs, tracer, config)
|
|
541
|
-
patchPromiseFunctions.call(this, fs, tracer, config)
|
|
542
|
-
}
|
|
543
|
-
if (fs.Dir) {
|
|
544
|
-
patchDirFunctions.call(this, fs, tracer, config)
|
|
545
|
-
}
|
|
546
|
-
shimmer.wrap(fs, 'createReadStream', createWrapCreateReadStream(config, tracer))
|
|
547
|
-
shimmer.wrap(fs, 'createWriteStream', createWrapCreateWriteStream(config, tracer))
|
|
548
|
-
shimmer.wrap(fs, 'existsSync', createWrap(tracer, config, 'existsSync', createPathTags))
|
|
549
|
-
shimmer.wrap(fs, 'exists', createWrapExists(config, tracer))
|
|
550
|
-
if (realpathNative) {
|
|
551
|
-
fs.realpath.native = createWrapCb(tracer, config, 'realpath.native', createPathTags)(realpathNative)
|
|
552
|
-
}
|
|
553
|
-
if (realpathSyncNative) {
|
|
554
|
-
fs.realpathSync.native = createWrap(tracer, config, 'realpath.native', createPathTags)(realpathSyncNative)
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
|
|
558
|
-
_unpatch () {
|
|
559
|
-
const fs = fsInstance
|
|
560
|
-
unpatchClassicFunctions.call(this, fs)
|
|
561
|
-
if (fs.promises) {
|
|
562
|
-
unpatchFileHandle.call(this, fs)
|
|
563
|
-
unpatchPromiseFunctions.call(this, fs)
|
|
564
|
-
}
|
|
565
|
-
if (fs.Dir) {
|
|
566
|
-
unpatchDirFunctions.call(this, fs)
|
|
567
|
-
}
|
|
568
|
-
shimmer.unwrap(fs, 'createReadStream')
|
|
569
|
-
shimmer.unwrap(fs, 'createWriteStream')
|
|
570
|
-
shimmer.unwrap(fs, 'existsSync')
|
|
571
|
-
shimmer.unwrap(fs, 'exists')
|
|
572
42
|
}
|
|
573
43
|
}
|
|
574
44
|
|
|
575
45
|
module.exports = FsPlugin
|
|
576
|
-
|
|
577
|
-
/** TODO fs functions:
|
|
578
|
-
|
|
579
|
-
unwatchFile
|
|
580
|
-
watch
|
|
581
|
-
watchFile
|
|
582
|
-
*/
|