From 93a2031d60ed1981f79aad8d26ada20c303d5957 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 9 Aug 2024 08:30:18 +0000 Subject: [PATCH 1/4] feat(node): Add `fsInstrumentation` --- packages/node/package.json | 1 + packages/node/src/index.ts | 1 + packages/node/src/integrations/fs.ts | 190 +++++++++++++++++++++++++++ yarn.lock | 8 ++ 4 files changed, 200 insertions(+) create mode 100644 packages/node/src/integrations/fs.ts diff --git a/packages/node/package.json b/packages/node/package.json index 6d19c1e7513c..2a09af669ad5 100644 --- a/packages/node/package.json +++ b/packages/node/package.json @@ -72,6 +72,7 @@ "@opentelemetry/instrumentation-connect": "0.38.0", "@opentelemetry/instrumentation-express": "0.41.1", "@opentelemetry/instrumentation-fastify": "0.38.0", + "@opentelemetry/instrumentation-fs": "0.14.0", "@opentelemetry/instrumentation-graphql": "0.42.0", "@opentelemetry/instrumentation-hapi": "0.40.0", "@opentelemetry/instrumentation-http": "0.52.1", diff --git a/packages/node/src/index.ts b/packages/node/src/index.ts index 1fdc32d3d77a..9ef89ab42fb7 100644 --- a/packages/node/src/index.ts +++ b/packages/node/src/index.ts @@ -1,5 +1,6 @@ export { httpIntegration } from './integrations/http'; export { nativeNodeFetchIntegration } from './integrations/node-fetch'; +export { fsIntegration } from './integrations/fs'; export { consoleIntegration } from './integrations/console'; export { nodeContextIntegration } from './integrations/context'; diff --git a/packages/node/src/integrations/fs.ts b/packages/node/src/integrations/fs.ts new file mode 100644 index 000000000000..0b2c257fb97e --- /dev/null +++ b/packages/node/src/integrations/fs.ts @@ -0,0 +1,190 @@ +import { FsInstrumentation } from '@opentelemetry/instrumentation-fs'; +import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, defineIntegration } from '@sentry/core'; +import { generateInstrumentOnce } from '../otel/instrument'; + +const INTEGRATION_NAME = 'FileSystem'; + +/** + * This integration will create spans for `fs` API operations, like reading and writing files. + * + * **WARNING:** This integration may add significant overhead to your application. Especially in scenarios with a lot of + * file I/O, like for example when running a framework dev server, including this integration can massively slow down + * your application. + * + * @param options Configuration for this integration. + */ +export const fsIntegration = defineIntegration( + ( + options: { + /** + * Setting this option to `true` will include any filepath arguments from your `fs` API calls as span attributes. + * + * Defaults to `false`. + */ + recordFilePaths?: boolean; + + /** + * Setting this option to `true` will include the error messages of failed `fs` API calls as a span attribute. + * + * Defaults to `false`. + */ + recordErrorMessagesAsSpanAttributes?: boolean; + } = {}, + ) => { + return { + name: INTEGRATION_NAME, + setupOnce() { + generateInstrumentOnce( + INTEGRATION_NAME, + () => + new FsInstrumentation({ + requireParentSpan: true, + // eslint-disable-next-line complexity + endHook(functionName, { args, span, error }) { + span.updateName(`fs.${functionName}`); + + span.setAttributes({ + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }); + + if (options.recordErrorMessagesAsSpanAttributes) { + if ( + typeof args[0] === 'string' && + (FS_OPERATIONS_WITH_PATH_ARG.includes(functionName) || + FS_OPERATIONS_WITH_PATH_ARG_PROMISES_PREFIXED.includes(functionName) || + FS_OPERATIONS_WITH_PATH_ARG_PROMISIFY_POSTFIXED.includes(functionName)) + ) { + span.setAttribute('path_argument', args[0]); + } else if ( + typeof args[0] === 'string' && + (FS_OPERATIONS_WITH_TARGET_PATH.includes(functionName) || + FS_OPERATIONS_WITH_TARGET_PATH_PROMISES_PREFIXED.includes(functionName) || + FS_OPERATIONS_WITH_TARGET_PATH_PROMISIFY_POSTFIXED.includes(functionName)) + ) { + span.setAttribute('target_path_argument', args[0]); + } else if ( + typeof args[0] === 'string' && + (FS_OPERATIONS_WITH_PREFIX.includes(functionName) || + FS_OPERATIONS_WITH_PREFIX_PROMISES_PREFIXED.includes(functionName) || + FS_OPERATIONS_WITH_PREFIX_PROMISIFY_POSTFIXED.includes(functionName)) + ) { + span.setAttribute('prefix_argument', args[0]); + } else if ( + typeof args[0] === 'string' && + typeof args[1] === 'string' && + (FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH.includes(functionName) || + FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH_PROMISES_PREFIXED.includes(functionName) || + FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH_PROMISIFY_POSTFIXED.includes(functionName)) + ) { + span.setAttribute('existing_path_argument', args[0]); + span.setAttribute('new_path_argument', args[1]); + } else if ( + typeof args[0] === 'string' && + typeof args[1] === 'string' && + (FS_OPERATIONS_WITH_SRC_DEST.includes(functionName) || + FS_OPERATIONS_WITH_SRC_DEST_PROMISES_PREFIXED.includes(functionName) || + FS_OPERATIONS_WITH_SRC_DEST_PROMISIFY_POSTFIXED.includes(functionName)) + ) { + span.setAttribute('src_argument', args[0]); + span.setAttribute('dest_argument', args[1]); + } else if ( + typeof args[0] === 'string' && + typeof args[1] === 'string' && + (FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH.includes(functionName) || + FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH_PROMISES_PREFIXED.includes(functionName) || + FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH_PROMISIFY_POSTFIXED.includes(functionName)) + ) { + span.setAttribute('old_path_argument', args[0]); + span.setAttribute('new_path_argument', args[1]); + } + } + + if (error && options.recordErrorMessagesAsSpanAttributes) { + span.setAttribute('fs_error', error.message); + } + }, + }), + )(); + }, + }; + }, +); + +const FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH = ['rename', 'renameSync']; +const FS_OPERATIONS_WITH_SRC_DEST = ['copyFile', 'cp', 'copyFileSync', 'cpSync']; +const FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH = ['link', 'linkSync']; +const FS_OPERATIONS_WITH_PREFIX = ['mkdtemp', 'mkdtempSync']; +const FS_OPERATIONS_WITH_TARGET_PATH = ['symlink', 'symlinkSync']; +const FS_OPERATIONS_WITH_PATH_ARG = [ + 'access', + 'appendFile', + 'chmod', + 'chown', + 'exists', + 'mkdir', + 'lchown', + 'lstat', + 'lutimes', + 'open', + 'opendir', + 'readdir', + 'readFile', + 'readlink', + 'realpath', + 'realpath.native', + 'rm', + 'rmdir', + 'stat', + 'truncate', + 'unlink', + 'utimes', + 'writeFile', + 'accessSync', + 'appendFileSync', + 'chmodSync', + 'chownSync', + 'existsSync', + 'lchownSync', + 'lstatSync', + 'lutimesSync', + 'opendirSync', + 'mkdirSync', + 'openSync', + 'readdirSync', + 'readFileSync', + 'readlinkSync', + 'realpathSync', + 'realpathSync.native', + 'rmdirSync', + 'rmSync', + 'statSync', + 'truncateSync', + 'unlinkSync', + 'utimesSync', + 'writeFileSync', +]; + +const FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH.map( + p => `${p}.__promisify__`, +); +const FS_OPERATIONS_WITH_SRC_DEST_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_SRC_DEST.map(p => `${p}.__promisify__`); +const FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH.map( + p => `${p}.__promisify__`, +); +const FS_OPERATIONS_WITH_PREFIX_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_PREFIX.map(p => `${p}.__promisify__`); +const FS_OPERATIONS_WITH_TARGET_PATH_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_TARGET_PATH.map( + p => `${p}.__promisify__`, +); +const FS_OPERATIONS_WITH_PATH_ARG_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_PATH_ARG.map(p => `${p}.__promisify__`); + +const FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH_PROMISES_PREFIXED = FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH.map( + p => `promises.${p}`, +); +const FS_OPERATIONS_WITH_SRC_DEST_PROMISES_PREFIXED = FS_OPERATIONS_WITH_SRC_DEST.map(p => `promises.${p}`); +const FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH_PROMISES_PREFIXED = FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH.map( + p => `promises.${p}`, +); +const FS_OPERATIONS_WITH_PREFIX_PROMISES_PREFIXED = FS_OPERATIONS_WITH_PREFIX.map(p => `promises.${p}`); +const FS_OPERATIONS_WITH_TARGET_PATH_PROMISES_PREFIXED = FS_OPERATIONS_WITH_TARGET_PATH.map(p => `promises.${p}`); +const FS_OPERATIONS_WITH_PATH_ARG_PROMISES_PREFIXED = FS_OPERATIONS_WITH_PATH_ARG.map(p => `promises.${p}`); diff --git a/yarn.lock b/yarn.lock index 660c53cce594..08a7a3eb7487 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7113,6 +7113,14 @@ "@opentelemetry/instrumentation" "^0.52.0" "@opentelemetry/semantic-conventions" "^1.22.0" +"@opentelemetry/instrumentation-fs@0.14.0": + version "0.14.0" + resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-fs/-/instrumentation-fs-0.14.0.tgz#19f1cb38a8c2d05f3b96af67f1c8d43f0af2829b" + integrity sha512-pVc8P5AgliC1DphyyBUgsxXlm2XaPH4BpYvt7rAZDMIqUpRk8gs19SioABtKqqxvFzg5jPtgJfJsdxq0Y+maLw== + dependencies: + "@opentelemetry/core" "^1.8.0" + "@opentelemetry/instrumentation" "^0.52.0" + "@opentelemetry/instrumentation-graphql@0.42.0": version "0.42.0" resolved "https://registry.yarnpkg.com/@opentelemetry/instrumentation-graphql/-/instrumentation-graphql-0.42.0.tgz#588a18c39e3b3f655bc09243566172ab0b638d35" From e59b33bde721ec51da192580696c0b98e1192440 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 9 Aug 2024 09:38:59 +0000 Subject: [PATCH 2/4] Add integration tests --- .../suites/fs-instrumentation/.gitignore | 11 + .../suites/fs-instrumentation/server.ts | 125 +++++++++ .../fs-instrumentation/some-file-promises.txt | 8 + .../some-file-promisify.txt | 8 + .../suites/fs-instrumentation/some-file.txt | 8 + .../suites/fs-instrumentation/test.ts | 260 ++++++++++++++++++ packages/node/src/integrations/fs.ts | 59 +--- 7 files changed, 429 insertions(+), 50 deletions(-) create mode 100644 dev-packages/node-integration-tests/suites/fs-instrumentation/.gitignore create mode 100644 dev-packages/node-integration-tests/suites/fs-instrumentation/server.ts create mode 100644 dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promises.txt create mode 100644 dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promisify.txt create mode 100644 dev-packages/node-integration-tests/suites/fs-instrumentation/some-file.txt create mode 100644 dev-packages/node-integration-tests/suites/fs-instrumentation/test.ts diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/.gitignore b/dev-packages/node-integration-tests/suites/fs-instrumentation/.gitignore new file mode 100644 index 000000000000..37ca947946e1 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/fs-instrumentation/.gitignore @@ -0,0 +1,11 @@ +some-file.txt.copy +some-file-promises.txt.copy +some-file-promisify.txt.copy + +some-file.txt.link +some-file-promises.txt.link +some-file-promisify.txt.link + +some-file.txt.symlink +some-file-promises.txt.symlink +some-file-promisify.txt.symlink diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/server.ts b/dev-packages/node-integration-tests/suites/fs-instrumentation/server.ts new file mode 100644 index 000000000000..3e820fc78be4 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/fs-instrumentation/server.ts @@ -0,0 +1,125 @@ +import { loggingTransport } from '@sentry-internal/node-integration-tests'; +import * as Sentry from '@sentry/node'; + +Sentry.init({ + dsn: 'https://public@dsn.ingest.sentry.io/1337', + release: '1.0', + transport: loggingTransport, + tracesSampleRate: 1, + integrations: [ + Sentry.fsIntegration({ + recordFilePaths: true, + recordErrorMessagesAsSpanAttributes: true, + }), + ], +}); + +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; +import * as util from 'util'; +import { startExpressServerAndSendPortToRunner } from '@sentry-internal/node-integration-tests'; +import express from 'express'; + +const app = express(); + +app.get('/readFile-error', async (_, res) => { + try { + await fs.promises.readFile(path.join(__dirname, 'some-file-that-doesnt-exist.txt'), 'utf-8'); + } catch { + // noop + } + res.send('done'); +}); + +app.get('/readFile', async (_, res) => { + await new Promise(resolve => { + fs.readFile(path.join(__dirname, 'some-file.txt'), 'utf-8', () => { + resolve(); + }); + }); + await fs.promises.readFile(path.join(__dirname, 'some-file-promises.txt'), 'utf-8'); + await util.promisify(fs.readFile)(path.join(__dirname, 'some-file-promisify.txt'), 'utf-8'); + res.send('done'); +}); + +app.get('/copyFile', async (_, res) => { + await new Promise(resolve => { + fs.copyFile(path.join(__dirname, 'some-file.txt'), path.join(__dirname, 'some-file.txt.copy'), () => { + resolve(); + }); + }); + await fs.promises.copyFile( + path.join(__dirname, 'some-file-promises.txt'), + path.join(__dirname, 'some-file-promises.txt.copy'), + ); + await util.promisify(fs.copyFile)( + path.join(__dirname, 'some-file-promisify.txt'), + path.join(__dirname, 'some-file-promisify.txt.copy'), + ); + res.send('done'); +}); + +app.get('/link', async (_, res) => { + await new Promise(resolve => { + fs.link(path.join(__dirname, 'some-file.txt'), path.join(__dirname, 'some-file.txt.link'), () => { + resolve(); + }); + }); + await fs.promises.link( + path.join(__dirname, 'some-file-promises.txt'), + path.join(__dirname, 'some-file-promises.txt.link'), + ); + await util.promisify(fs.link)( + path.join(__dirname, 'some-file-promisify.txt'), + path.join(__dirname, 'some-file-promisify.txt.link'), + ); + + await Promise.all([ + fs.promises.unlink(path.join(__dirname, 'some-file.txt.link')), + fs.promises.unlink(path.join(__dirname, 'some-file-promises.txt.link')), + fs.promises.unlink(path.join(__dirname, 'some-file-promisify.txt.link')), + ]); + + res.send('done'); +}); + +app.get('/mkdtemp', async (_, res) => { + await new Promise(resolve => { + fs.mkdtemp(path.join(os.tmpdir(), 'foo-'), () => { + resolve(); + }); + }); + await fs.promises.mkdtemp(path.join(os.tmpdir(), 'foo-')); + await util.promisify(fs.mkdtemp)(path.join(os.tmpdir(), 'foo-')); + + res.send('done'); +}); + +app.get('/symlink', async (_, res) => { + await new Promise(resolve => { + fs.symlink(path.join(__dirname, 'some-file.txt'), path.join(__dirname, 'some-file.txt.symlink'), () => { + resolve(); + }); + }); + await fs.promises.symlink( + path.join(__dirname, 'some-file-promises.txt'), + path.join(__dirname, 'some-file-promises.txt.symlink'), + ); + await util.promisify(fs.symlink)( + path.join(__dirname, 'some-file-promisify.txt'), + path.join(__dirname, 'some-file-promisify.txt.symlink'), + ); + + await Promise.all([ + fs.promises.unlink(path.join(__dirname, 'some-file.txt.symlink')), + fs.promises.unlink(path.join(__dirname, 'some-file-promises.txt.symlink')), + fs.promises.unlink(path.join(__dirname, 'some-file-promisify.txt.symlink')), + ]); + + res.send('done'); +}); + +Sentry.setupExpressErrorHandler(app); + +startExpressServerAndSendPortToRunner(app); diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promises.txt b/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promises.txt new file mode 100644 index 000000000000..00a0fd7faa1a --- /dev/null +++ b/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promises.txt @@ -0,0 +1,8 @@ + _____________________________ +< gimme some fs instrumentation > + ----------------------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\\ + ||----w | + || || diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promisify.txt b/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promisify.txt new file mode 100644 index 000000000000..00a0fd7faa1a --- /dev/null +++ b/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promisify.txt @@ -0,0 +1,8 @@ + _____________________________ +< gimme some fs instrumentation > + ----------------------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\\ + ||----w | + || || diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file.txt b/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file.txt new file mode 100644 index 000000000000..00a0fd7faa1a --- /dev/null +++ b/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file.txt @@ -0,0 +1,8 @@ + _____________________________ +< gimme some fs instrumentation > + ----------------------------- + \ ^__^ + \ (oo)\_______ + (__)\ )\/\\ + ||----w | + || || diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/test.ts b/dev-packages/node-integration-tests/suites/fs-instrumentation/test.ts new file mode 100644 index 000000000000..70c92c92b863 --- /dev/null +++ b/dev-packages/node-integration-tests/suites/fs-instrumentation/test.ts @@ -0,0 +1,260 @@ +import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/node'; +import { cleanupChildProcesses, createRunner } from '../../utils/runner'; + +afterAll(() => { + cleanupChildProcesses(); +}); + +test('should create spans for fs operations that take target argument', done => { + const runner = createRunner(__dirname, 'server.ts') + .expect({ + transaction: { + transaction: 'GET /readFile-error', + spans: expect.arrayContaining([ + expect.objectContaining({ + description: 'fs.readFile', + op: 'file', + status: 'unknown_error', + data: { + fs_error: expect.stringMatching('ENOENT: no such file or directory,'), + path_argument: expect.stringMatching('/some-file-that-doesnt-exist.txt'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + ]), + }, + }) + .start(done); + + expect(runner.makeRequest('get', '/readFile-error')).resolves.toBe('done'); +}); + +test('should create spans for fs operations that take one path', done => { + const runner = createRunner(__dirname, 'server.ts') + .expect({ + transaction: { + transaction: 'GET /readFile', + spans: expect.arrayContaining([ + expect.objectContaining({ + description: 'fs.readFile', + op: 'file', + status: 'ok', + data: { + path_argument: expect.stringMatching('/some-file.txt'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.readFile', + op: 'file', + status: 'ok', + data: { + path_argument: expect.stringMatching('/some-file-promises.txt'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.readFile', + op: 'file', + status: 'ok', + data: { + path_argument: expect.stringMatching('/some-file-promisify.txt'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + ]), + }, + }) + .start(done); + + expect(runner.makeRequest('get', '/readFile')).resolves.toBe('done'); +}); + +test('should create spans for fs operations that take src and dest arguments', done => { + const runner = createRunner(__dirname, 'server.ts') + .expect({ + transaction: { + transaction: 'GET /copyFile', + spans: expect.arrayContaining([ + expect.objectContaining({ + description: 'fs.copyFile', + op: 'file', + status: 'ok', + data: { + src_argument: expect.stringMatching('/some-file.txt'), + dest_argument: expect.stringMatching('/some-file.txt.copy'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.copyFile', + op: 'file', + status: 'ok', + data: { + src_argument: expect.stringMatching('/some-file-promises.txt'), + dest_argument: expect.stringMatching('/some-file-promises.txt.copy'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.copyFile', + op: 'file', + status: 'ok', + data: { + src_argument: expect.stringMatching('/some-file-promisify.txt'), + dest_argument: expect.stringMatching('/some-file-promisify.txt.copy'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + ]), + }, + }) + .start(done); + + expect(runner.makeRequest('get', '/copyFile')).resolves.toBe('done'); +}); + +test('should create spans for fs operations that take existing path and new path arguments', done => { + const runner = createRunner(__dirname, 'server.ts') + .expect({ + transaction: { + transaction: 'GET /link', + spans: expect.arrayContaining([ + expect.objectContaining({ + description: 'fs.link', + op: 'file', + status: 'ok', + data: { + existing_path_argument: expect.stringMatching('/some-file.txt'), + new_path_argument: expect.stringMatching('/some-file.txt.link'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.link', + op: 'file', + status: 'ok', + data: { + existing_path_argument: expect.stringMatching('/some-file-promises.txt'), + new_path_argument: expect.stringMatching('/some-file-promises.txt.link'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.link', + op: 'file', + status: 'ok', + data: { + existing_path_argument: expect.stringMatching('/some-file-promisify.txt'), + new_path_argument: expect.stringMatching('/some-file-promisify.txt.link'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + ]), + }, + }) + .start(done); + + expect(runner.makeRequest('get', '/link')).resolves.toBe('done'); +}); + +test('should create spans for fs operations that take prefix argument', done => { + const runner = createRunner(__dirname, 'server.ts') + .expect({ + transaction: { + transaction: 'GET /mkdtemp', + spans: expect.arrayContaining([ + expect.objectContaining({ + description: 'fs.mkdtemp', + op: 'file', + status: 'ok', + data: { + prefix_argument: expect.stringMatching('/foo-'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.mkdtemp', + op: 'file', + status: 'ok', + data: { + prefix_argument: expect.stringMatching('/foo-'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.mkdtemp', + op: 'file', + status: 'ok', + data: { + prefix_argument: expect.stringMatching('/foo-'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + ]), + }, + }) + .start(done); + + expect(runner.makeRequest('get', '/mkdtemp')).resolves.toBe('done'); +}); + +test('should create spans for fs operations that take target argument', done => { + const runner = createRunner(__dirname, 'server.ts') + .expect({ + transaction: { + transaction: 'GET /symlink', + spans: expect.arrayContaining([ + expect.objectContaining({ + description: 'fs.symlink', + op: 'file', + status: 'ok', + data: { + target_argument: expect.stringMatching('/some-file-promisify.txt'), + path_argument: expect.stringMatching('/some-file-promisify.txt.symlink'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.symlink', + op: 'file', + status: 'ok', + data: { + target_argument: expect.stringMatching('/some-file-promisify.txt'), + path_argument: expect.stringMatching('/some-file-promisify.txt.symlink'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + expect.objectContaining({ + description: 'fs.symlink', + op: 'file', + status: 'ok', + data: { + target_argument: expect.stringMatching('/some-file-promisify.txt'), + path_argument: expect.stringMatching('/some-file-promisify.txt.symlink'), + [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', + [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', + }, + }), + ]), + }, + }) + .start(done); + + expect(runner.makeRequest('get', '/symlink')).resolves.toBe('done'); +}); diff --git a/packages/node/src/integrations/fs.ts b/packages/node/src/integrations/fs.ts index 0b2c257fb97e..2288096dad43 100644 --- a/packages/node/src/integrations/fs.ts +++ b/packages/node/src/integrations/fs.ts @@ -39,7 +39,6 @@ export const fsIntegration = defineIntegration( () => new FsInstrumentation({ requireParentSpan: true, - // eslint-disable-next-line complexity endHook(functionName, { args, span, error }) { span.updateName(`fs.${functionName}`); @@ -49,51 +48,35 @@ export const fsIntegration = defineIntegration( }); if (options.recordErrorMessagesAsSpanAttributes) { - if ( - typeof args[0] === 'string' && - (FS_OPERATIONS_WITH_PATH_ARG.includes(functionName) || - FS_OPERATIONS_WITH_PATH_ARG_PROMISES_PREFIXED.includes(functionName) || - FS_OPERATIONS_WITH_PATH_ARG_PROMISIFY_POSTFIXED.includes(functionName)) - ) { + if (typeof args[0] === 'string' && FS_OPERATIONS_WITH_PATH_ARG.includes(functionName)) { span.setAttribute('path_argument', args[0]); } else if ( typeof args[0] === 'string' && - (FS_OPERATIONS_WITH_TARGET_PATH.includes(functionName) || - FS_OPERATIONS_WITH_TARGET_PATH_PROMISES_PREFIXED.includes(functionName) || - FS_OPERATIONS_WITH_TARGET_PATH_PROMISIFY_POSTFIXED.includes(functionName)) - ) { - span.setAttribute('target_path_argument', args[0]); - } else if ( - typeof args[0] === 'string' && - (FS_OPERATIONS_WITH_PREFIX.includes(functionName) || - FS_OPERATIONS_WITH_PREFIX_PROMISES_PREFIXED.includes(functionName) || - FS_OPERATIONS_WITH_PREFIX_PROMISIFY_POSTFIXED.includes(functionName)) + typeof args[1] === 'string' && + FS_OPERATIONS_WITH_TARGET_PATH.includes(functionName) ) { + span.setAttribute('target_argument', args[0]); + span.setAttribute('path_argument', args[1]); + } else if (typeof args[0] === 'string' && FS_OPERATIONS_WITH_PREFIX.includes(functionName)) { span.setAttribute('prefix_argument', args[0]); } else if ( typeof args[0] === 'string' && typeof args[1] === 'string' && - (FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH.includes(functionName) || - FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH_PROMISES_PREFIXED.includes(functionName) || - FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH_PROMISIFY_POSTFIXED.includes(functionName)) + FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH.includes(functionName) ) { span.setAttribute('existing_path_argument', args[0]); span.setAttribute('new_path_argument', args[1]); } else if ( typeof args[0] === 'string' && typeof args[1] === 'string' && - (FS_OPERATIONS_WITH_SRC_DEST.includes(functionName) || - FS_OPERATIONS_WITH_SRC_DEST_PROMISES_PREFIXED.includes(functionName) || - FS_OPERATIONS_WITH_SRC_DEST_PROMISIFY_POSTFIXED.includes(functionName)) + FS_OPERATIONS_WITH_SRC_DEST.includes(functionName) ) { span.setAttribute('src_argument', args[0]); span.setAttribute('dest_argument', args[1]); } else if ( typeof args[0] === 'string' && typeof args[1] === 'string' && - (FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH.includes(functionName) || - FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH_PROMISES_PREFIXED.includes(functionName) || - FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH_PROMISIFY_POSTFIXED.includes(functionName)) + FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH.includes(functionName) ) { span.setAttribute('old_path_argument', args[0]); span.setAttribute('new_path_argument', args[1]); @@ -164,27 +147,3 @@ const FS_OPERATIONS_WITH_PATH_ARG = [ 'utimesSync', 'writeFileSync', ]; - -const FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH.map( - p => `${p}.__promisify__`, -); -const FS_OPERATIONS_WITH_SRC_DEST_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_SRC_DEST.map(p => `${p}.__promisify__`); -const FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH.map( - p => `${p}.__promisify__`, -); -const FS_OPERATIONS_WITH_PREFIX_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_PREFIX.map(p => `${p}.__promisify__`); -const FS_OPERATIONS_WITH_TARGET_PATH_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_TARGET_PATH.map( - p => `${p}.__promisify__`, -); -const FS_OPERATIONS_WITH_PATH_ARG_PROMISIFY_POSTFIXED = FS_OPERATIONS_WITH_PATH_ARG.map(p => `${p}.__promisify__`); - -const FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH_PROMISES_PREFIXED = FS_OPERATIONS_WITH_OLD_PATH_NEW_PATH.map( - p => `promises.${p}`, -); -const FS_OPERATIONS_WITH_SRC_DEST_PROMISES_PREFIXED = FS_OPERATIONS_WITH_SRC_DEST.map(p => `promises.${p}`); -const FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH_PROMISES_PREFIXED = FS_OPERATIONS_WITH_EXISTING_PATH_NEW_PATH.map( - p => `promises.${p}`, -); -const FS_OPERATIONS_WITH_PREFIX_PROMISES_PREFIXED = FS_OPERATIONS_WITH_PREFIX.map(p => `promises.${p}`); -const FS_OPERATIONS_WITH_TARGET_PATH_PROMISES_PREFIXED = FS_OPERATIONS_WITH_TARGET_PATH.map(p => `promises.${p}`); -const FS_OPERATIONS_WITH_PATH_ARG_PROMISES_PREFIXED = FS_OPERATIONS_WITH_PATH_ARG.map(p => `promises.${p}`); From 7190436066b1f7844a6f8b682fa0fb1ea43f08c3 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 9 Aug 2024 09:41:58 +0000 Subject: [PATCH 3/4] fix exports --- packages/astro/src/index.server.ts | 1 + packages/aws-serverless/src/index.ts | 1 + packages/bun/src/index.ts | 1 + packages/google-cloud-serverless/src/index.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/packages/astro/src/index.server.ts b/packages/astro/src/index.server.ts index 7f52ad0dc0bb..be3f002dcbb8 100644 --- a/packages/astro/src/index.server.ts +++ b/packages/astro/src/index.server.ts @@ -40,6 +40,7 @@ export { extraErrorDataIntegration, fastifyIntegration, flush, + fsIntegration, functionToStringIntegration, generateInstrumentOnce, getActiveSpan, diff --git a/packages/aws-serverless/src/index.ts b/packages/aws-serverless/src/index.ts index 20ef9eeaf09f..7b05f8df3a86 100644 --- a/packages/aws-serverless/src/index.ts +++ b/packages/aws-serverless/src/index.ts @@ -86,6 +86,7 @@ export { connectIntegration, setupConnectErrorHandler, fastifyIntegration, + fsIntegration, graphqlIntegration, mongoIntegration, mongooseIntegration, diff --git a/packages/bun/src/index.ts b/packages/bun/src/index.ts index 4de55fd1c5f7..e49e4163af31 100644 --- a/packages/bun/src/index.ts +++ b/packages/bun/src/index.ts @@ -77,6 +77,7 @@ export { nodeContextIntegration, localVariablesIntegration, requestDataIntegration, + fsIntegration, functionToStringIntegration, inboundFiltersIntegration, linkedErrorsIntegration, diff --git a/packages/google-cloud-serverless/src/index.ts b/packages/google-cloud-serverless/src/index.ts index 73f24f9cf39e..9a501307e79f 100644 --- a/packages/google-cloud-serverless/src/index.ts +++ b/packages/google-cloud-serverless/src/index.ts @@ -57,6 +57,7 @@ export { nodeContextIntegration, localVariablesIntegration, requestDataIntegration, + fsIntegration, functionToStringIntegration, inboundFiltersIntegration, linkedErrorsIntegration, From 04d76e9f1f7e96d37632625871adf5b1f8793710 Mon Sep 17 00:00:00 2001 From: Luca Forstner Date: Fri, 9 Aug 2024 11:09:20 +0000 Subject: [PATCH 4/4] move to fixtures and clean gitignore --- .../suites/fs-instrumentation/.gitignore | 11 --- .../fs-instrumentation/fixtures/.gitignore | 3 + .../{ => fixtures}/some-file-promises.txt | 0 .../{ => fixtures}/some-file-promisify.txt | 0 .../{ => fixtures}/some-file.txt | 0 .../suites/fs-instrumentation/server.ts | 74 +++++++++++-------- .../suites/fs-instrumentation/test.ts | 36 ++++----- 7 files changed, 64 insertions(+), 60 deletions(-) delete mode 100644 dev-packages/node-integration-tests/suites/fs-instrumentation/.gitignore create mode 100644 dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/.gitignore rename dev-packages/node-integration-tests/suites/fs-instrumentation/{ => fixtures}/some-file-promises.txt (100%) rename dev-packages/node-integration-tests/suites/fs-instrumentation/{ => fixtures}/some-file-promisify.txt (100%) rename dev-packages/node-integration-tests/suites/fs-instrumentation/{ => fixtures}/some-file.txt (100%) diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/.gitignore b/dev-packages/node-integration-tests/suites/fs-instrumentation/.gitignore deleted file mode 100644 index 37ca947946e1..000000000000 --- a/dev-packages/node-integration-tests/suites/fs-instrumentation/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -some-file.txt.copy -some-file-promises.txt.copy -some-file-promisify.txt.copy - -some-file.txt.link -some-file-promises.txt.link -some-file-promisify.txt.link - -some-file.txt.symlink -some-file-promises.txt.symlink -some-file-promisify.txt.symlink diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/.gitignore b/dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/.gitignore new file mode 100644 index 000000000000..814ce048cf6b --- /dev/null +++ b/dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/.gitignore @@ -0,0 +1,3 @@ +some-file.txt.* +some-file-promises.txt.* +some-file-promisify.txt.* diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promises.txt b/dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/some-file-promises.txt similarity index 100% rename from dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promises.txt rename to dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/some-file-promises.txt diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promisify.txt b/dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/some-file-promisify.txt similarity index 100% rename from dev-packages/node-integration-tests/suites/fs-instrumentation/some-file-promisify.txt rename to dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/some-file-promisify.txt diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/some-file.txt b/dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/some-file.txt similarity index 100% rename from dev-packages/node-integration-tests/suites/fs-instrumentation/some-file.txt rename to dev-packages/node-integration-tests/suites/fs-instrumentation/fixtures/some-file.txt diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/server.ts b/dev-packages/node-integration-tests/suites/fs-instrumentation/server.ts index 3e820fc78be4..1320d7c3b4e2 100644 --- a/dev-packages/node-integration-tests/suites/fs-instrumentation/server.ts +++ b/dev-packages/node-integration-tests/suites/fs-instrumentation/server.ts @@ -25,7 +25,7 @@ const app = express(); app.get('/readFile-error', async (_, res) => { try { - await fs.promises.readFile(path.join(__dirname, 'some-file-that-doesnt-exist.txt'), 'utf-8'); + await fs.promises.readFile(path.join(__dirname, 'fixtures', 'some-file-that-doesnt-exist.txt'), 'utf-8'); } catch { // noop } @@ -34,51 +34,59 @@ app.get('/readFile-error', async (_, res) => { app.get('/readFile', async (_, res) => { await new Promise(resolve => { - fs.readFile(path.join(__dirname, 'some-file.txt'), 'utf-8', () => { + fs.readFile(path.join(__dirname, 'fixtures', 'some-file.txt'), 'utf-8', () => { resolve(); }); }); - await fs.promises.readFile(path.join(__dirname, 'some-file-promises.txt'), 'utf-8'); - await util.promisify(fs.readFile)(path.join(__dirname, 'some-file-promisify.txt'), 'utf-8'); + await fs.promises.readFile(path.join(__dirname, 'fixtures', 'some-file-promises.txt'), 'utf-8'); + await util.promisify(fs.readFile)(path.join(__dirname, 'fixtures', 'some-file-promisify.txt'), 'utf-8'); res.send('done'); }); app.get('/copyFile', async (_, res) => { await new Promise(resolve => { - fs.copyFile(path.join(__dirname, 'some-file.txt'), path.join(__dirname, 'some-file.txt.copy'), () => { - resolve(); - }); + fs.copyFile( + path.join(__dirname, 'fixtures', 'some-file.txt'), + path.join(__dirname, 'fixtures', 'some-file.txt.copy'), + () => { + resolve(); + }, + ); }); await fs.promises.copyFile( - path.join(__dirname, 'some-file-promises.txt'), - path.join(__dirname, 'some-file-promises.txt.copy'), + path.join(__dirname, 'fixtures', 'some-file-promises.txt'), + path.join(__dirname, 'fixtures', 'some-file-promises.txt.copy'), ); await util.promisify(fs.copyFile)( - path.join(__dirname, 'some-file-promisify.txt'), - path.join(__dirname, 'some-file-promisify.txt.copy'), + path.join(__dirname, 'fixtures', 'some-file-promisify.txt'), + path.join(__dirname, 'fixtures', 'some-file-promisify.txt.copy'), ); res.send('done'); }); app.get('/link', async (_, res) => { await new Promise(resolve => { - fs.link(path.join(__dirname, 'some-file.txt'), path.join(__dirname, 'some-file.txt.link'), () => { - resolve(); - }); + fs.link( + path.join(__dirname, 'fixtures', 'some-file.txt'), + path.join(__dirname, 'fixtures', 'some-file.txt.link'), + () => { + resolve(); + }, + ); }); await fs.promises.link( - path.join(__dirname, 'some-file-promises.txt'), - path.join(__dirname, 'some-file-promises.txt.link'), + path.join(__dirname, 'fixtures', 'some-file-promises.txt'), + path.join(__dirname, 'fixtures', 'some-file-promises.txt.link'), ); await util.promisify(fs.link)( - path.join(__dirname, 'some-file-promisify.txt'), - path.join(__dirname, 'some-file-promisify.txt.link'), + path.join(__dirname, 'fixtures', 'some-file-promisify.txt'), + path.join(__dirname, 'fixtures', 'some-file-promisify.txt.link'), ); await Promise.all([ - fs.promises.unlink(path.join(__dirname, 'some-file.txt.link')), - fs.promises.unlink(path.join(__dirname, 'some-file-promises.txt.link')), - fs.promises.unlink(path.join(__dirname, 'some-file-promisify.txt.link')), + fs.promises.unlink(path.join(__dirname, 'fixtures', 'some-file.txt.link')), + fs.promises.unlink(path.join(__dirname, 'fixtures', 'some-file-promises.txt.link')), + fs.promises.unlink(path.join(__dirname, 'fixtures', 'some-file-promisify.txt.link')), ]); res.send('done'); @@ -98,23 +106,27 @@ app.get('/mkdtemp', async (_, res) => { app.get('/symlink', async (_, res) => { await new Promise(resolve => { - fs.symlink(path.join(__dirname, 'some-file.txt'), path.join(__dirname, 'some-file.txt.symlink'), () => { - resolve(); - }); + fs.symlink( + path.join(__dirname, 'fixtures', 'some-file.txt'), + path.join(__dirname, 'fixtures', 'some-file.txt.symlink'), + () => { + resolve(); + }, + ); }); await fs.promises.symlink( - path.join(__dirname, 'some-file-promises.txt'), - path.join(__dirname, 'some-file-promises.txt.symlink'), + path.join(__dirname, 'fixtures', 'some-file-promises.txt'), + path.join(__dirname, 'fixtures', 'some-file-promises.txt.symlink'), ); await util.promisify(fs.symlink)( - path.join(__dirname, 'some-file-promisify.txt'), - path.join(__dirname, 'some-file-promisify.txt.symlink'), + path.join(__dirname, 'fixtures', 'some-file-promisify.txt'), + path.join(__dirname, 'fixtures', 'some-file-promisify.txt.symlink'), ); await Promise.all([ - fs.promises.unlink(path.join(__dirname, 'some-file.txt.symlink')), - fs.promises.unlink(path.join(__dirname, 'some-file-promises.txt.symlink')), - fs.promises.unlink(path.join(__dirname, 'some-file-promisify.txt.symlink')), + fs.promises.unlink(path.join(__dirname, 'fixtures', 'some-file.txt.symlink')), + fs.promises.unlink(path.join(__dirname, 'fixtures', 'some-file-promises.txt.symlink')), + fs.promises.unlink(path.join(__dirname, 'fixtures', 'some-file-promisify.txt.symlink')), ]); res.send('done'); diff --git a/dev-packages/node-integration-tests/suites/fs-instrumentation/test.ts b/dev-packages/node-integration-tests/suites/fs-instrumentation/test.ts index 70c92c92b863..05860fa1ce26 100644 --- a/dev-packages/node-integration-tests/suites/fs-instrumentation/test.ts +++ b/dev-packages/node-integration-tests/suites/fs-instrumentation/test.ts @@ -17,7 +17,7 @@ test('should create spans for fs operations that take target argument', done => status: 'unknown_error', data: { fs_error: expect.stringMatching('ENOENT: no such file or directory,'), - path_argument: expect.stringMatching('/some-file-that-doesnt-exist.txt'), + path_argument: expect.stringMatching('/fixtures/some-file-that-doesnt-exist.txt'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -41,7 +41,7 @@ test('should create spans for fs operations that take one path', done => { op: 'file', status: 'ok', data: { - path_argument: expect.stringMatching('/some-file.txt'), + path_argument: expect.stringMatching('/fixtures/some-file.txt'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -51,7 +51,7 @@ test('should create spans for fs operations that take one path', done => { op: 'file', status: 'ok', data: { - path_argument: expect.stringMatching('/some-file-promises.txt'), + path_argument: expect.stringMatching('/fixtures/some-file-promises.txt'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -61,7 +61,7 @@ test('should create spans for fs operations that take one path', done => { op: 'file', status: 'ok', data: { - path_argument: expect.stringMatching('/some-file-promisify.txt'), + path_argument: expect.stringMatching('/fixtures/some-file-promisify.txt'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -85,8 +85,8 @@ test('should create spans for fs operations that take src and dest arguments', d op: 'file', status: 'ok', data: { - src_argument: expect.stringMatching('/some-file.txt'), - dest_argument: expect.stringMatching('/some-file.txt.copy'), + src_argument: expect.stringMatching('/fixtures/some-file.txt'), + dest_argument: expect.stringMatching('/fixtures/some-file.txt.copy'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -96,8 +96,8 @@ test('should create spans for fs operations that take src and dest arguments', d op: 'file', status: 'ok', data: { - src_argument: expect.stringMatching('/some-file-promises.txt'), - dest_argument: expect.stringMatching('/some-file-promises.txt.copy'), + src_argument: expect.stringMatching('/fixtures/some-file-promises.txt'), + dest_argument: expect.stringMatching('/fixtures/some-file-promises.txt.copy'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -107,8 +107,8 @@ test('should create spans for fs operations that take src and dest arguments', d op: 'file', status: 'ok', data: { - src_argument: expect.stringMatching('/some-file-promisify.txt'), - dest_argument: expect.stringMatching('/some-file-promisify.txt.copy'), + src_argument: expect.stringMatching('/fixtures/some-file-promisify.txt'), + dest_argument: expect.stringMatching('/fixtures/some-file-promisify.txt.copy'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -132,8 +132,8 @@ test('should create spans for fs operations that take existing path and new path op: 'file', status: 'ok', data: { - existing_path_argument: expect.stringMatching('/some-file.txt'), - new_path_argument: expect.stringMatching('/some-file.txt.link'), + existing_path_argument: expect.stringMatching('/fixtures/some-file.txt'), + new_path_argument: expect.stringMatching('/fixtures/some-file.txt.link'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -154,8 +154,8 @@ test('should create spans for fs operations that take existing path and new path op: 'file', status: 'ok', data: { - existing_path_argument: expect.stringMatching('/some-file-promisify.txt'), - new_path_argument: expect.stringMatching('/some-file-promisify.txt.link'), + existing_path_argument: expect.stringMatching('/fixtures/some-file-promisify.txt'), + new_path_argument: expect.stringMatching('/fixtures/some-file-promisify.txt.link'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -234,8 +234,8 @@ test('should create spans for fs operations that take target argument', done => op: 'file', status: 'ok', data: { - target_argument: expect.stringMatching('/some-file-promisify.txt'), - path_argument: expect.stringMatching('/some-file-promisify.txt.symlink'), + target_argument: expect.stringMatching('/fixtures/some-file-promisify.txt'), + path_argument: expect.stringMatching('/fixtures/some-file-promisify.txt.symlink'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', }, @@ -245,8 +245,8 @@ test('should create spans for fs operations that take target argument', done => op: 'file', status: 'ok', data: { - target_argument: expect.stringMatching('/some-file-promisify.txt'), - path_argument: expect.stringMatching('/some-file-promisify.txt.symlink'), + target_argument: expect.stringMatching('/fixtures/some-file-promisify.txt'), + path_argument: expect.stringMatching('/fixtures/some-file-promisify.txt.symlink'), [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'file', [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.file.fs', },