diff --git a/package-lock.json b/package-lock.json index 064e56329f..e705e6df8b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14670,6 +14670,17 @@ "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "dev": true }, + "node_modules/better-sqlite3": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.0.0.tgz", + "integrity": "sha512-1NnNhmT3EZTsKtofJlMox1jkMxdedILury74PwUbQBjWgo4tL4kf7uTAjU55mgQwjdzqakSTjkf+E1imrFwjnA==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -15790,9 +15801,9 @@ "dev": true }, "node_modules/colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, "node_modules/colors": { @@ -19836,9 +19847,9 @@ } }, "node_modules/getopts": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", - "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", + "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==", "dev": true }, "node_modules/getpass": { @@ -22816,32 +22827,36 @@ } }, "node_modules/knex": { - "version": "0.95.9", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.9.tgz", - "integrity": "sha512-iy8Wue3ofGBVZENgz32fx2uYSYhXCQEE7lemMIdm/FDtgwwmrzkYm9BdGZ4wb8Fg/oCgezMGWSdCflWicX4sdA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz", + "integrity": "sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==", "dev": true, "dependencies": { - "colorette": "1.2.1", - "commander": "^7.1.0", - "debug": "4.3.2", + "colorette": "2.0.19", + "commander": "^10.0.0", + "debug": "4.3.4", "escalade": "^3.1.1", "esm": "^3.2.25", - "getopts": "2.2.5", + "get-package-type": "^0.1.0", + "getopts": "2.3.0", "interpret": "^2.2.0", "lodash": "^4.17.21", - "pg-connection-string": "2.5.0", - "rechoir": "0.7.0", + "pg-connection-string": "2.6.2", + "rechoir": "^0.8.0", "resolve-from": "^5.0.0", - "tarn": "^3.0.1", + "tarn": "^3.0.2", "tildify": "2.0.0" }, "bin": { "knex": "bin/cli.js" }, "engines": { - "node": ">=10" + "node": ">=16" }, "peerDependenciesMeta": { + "better-sqlite3": { + "optional": true + }, "mysql": { "optional": true }, @@ -22851,6 +22866,9 @@ "pg": { "optional": true }, + "pg-native": { + "optional": true + }, "sqlite3": { "optional": true }, @@ -22859,19 +22877,10 @@ } } }, - "node_modules/knex/node_modules/commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true, - "engines": { - "node": ">= 10" - } - }, "node_modules/knex/node_modules/debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -28728,9 +28737,9 @@ } }, "node_modules/pg-connection-string": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", - "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==", "dev": true }, "node_modules/pg-int8": { @@ -30010,15 +30019,15 @@ } }, "node_modules/rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "dependencies": { - "resolve": "^1.9.0" + "resolve": "^1.20.0" }, "engines": { - "node": ">= 0.10" + "node": ">= 10.13.0" } }, "node_modules/redent": { @@ -34757,18 +34766,6 @@ "node": ">=10.13.0" } }, - "node_modules/webpack-cli/node_modules/rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "dependencies": { - "resolve": "^1.20.0" - }, - "engines": { - "node": ">= 10.13.0" - } - }, "node_modules/webpack-merge": { "version": "5.10.0", "resolved": "https://registry.npmjs.org/webpack-merge/-/webpack-merge-5.10.0.tgz", @@ -38129,7 +38126,8 @@ "@opentelemetry/sdk-trace-node": "^1.8.0", "@types/mocha": "7.0.2", "@types/node": "18.18.14", - "knex": "0.95.9", + "better-sqlite3": "11.0.0", + "knex": "3.1.0", "nyc": "15.1.0", "rimraf": "5.0.10", "sqlite3": "5.1.7", @@ -48218,7 +48216,8 @@ "@opentelemetry/semantic-conventions": "^1.27.0", "@types/mocha": "7.0.2", "@types/node": "18.18.14", - "knex": "0.95.9", + "better-sqlite3": "11.0.0", + "knex": "3.1.0", "nyc": "15.1.0", "rimraf": "5.0.10", "sqlite3": "5.1.7", @@ -54403,6 +54402,16 @@ "integrity": "sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==", "dev": true }, + "better-sqlite3": { + "version": "11.0.0", + "resolved": "https://registry.npmjs.org/better-sqlite3/-/better-sqlite3-11.0.0.tgz", + "integrity": "sha512-1NnNhmT3EZTsKtofJlMox1jkMxdedILury74PwUbQBjWgo4tL4kf7uTAjU55mgQwjdzqakSTjkf+E1imrFwjnA==", + "dev": true, + "requires": { + "bindings": "^1.5.0", + "prebuild-install": "^7.1.1" + } + }, "big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -55256,9 +55265,9 @@ "dev": true }, "colorette": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/colorette/-/colorette-1.2.1.tgz", - "integrity": "sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw==", + "version": "2.0.19", + "resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.19.tgz", + "integrity": "sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ==", "dev": true }, "colors": { @@ -58386,9 +58395,9 @@ } }, "getopts": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.2.5.tgz", - "integrity": "sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/getopts/-/getopts-2.3.0.tgz", + "integrity": "sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA==", "dev": true }, "getpass": { @@ -60641,36 +60650,31 @@ "dev": true }, "knex": { - "version": "0.95.9", - "resolved": "https://registry.npmjs.org/knex/-/knex-0.95.9.tgz", - "integrity": "sha512-iy8Wue3ofGBVZENgz32fx2uYSYhXCQEE7lemMIdm/FDtgwwmrzkYm9BdGZ4wb8Fg/oCgezMGWSdCflWicX4sdA==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/knex/-/knex-3.1.0.tgz", + "integrity": "sha512-GLoII6hR0c4ti243gMs5/1Rb3B+AjwMOfjYm97pu0FOQa7JH56hgBxYf5WK2525ceSbBY1cjeZ9yk99GPMB6Kw==", "dev": true, "requires": { - "colorette": "1.2.1", - "commander": "^7.1.0", - "debug": "4.3.2", + "colorette": "2.0.19", + "commander": "^10.0.0", + "debug": "4.3.4", "escalade": "^3.1.1", "esm": "^3.2.25", - "getopts": "2.2.5", + "get-package-type": "^0.1.0", + "getopts": "2.3.0", "interpret": "^2.2.0", "lodash": "^4.17.21", - "pg-connection-string": "2.5.0", - "rechoir": "0.7.0", + "pg-connection-string": "2.6.2", + "rechoir": "^0.8.0", "resolve-from": "^5.0.0", - "tarn": "^3.0.1", + "tarn": "^3.0.2", "tildify": "2.0.0" }, "dependencies": { - "commander": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", - "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", - "dev": true - }, "debug": { - "version": "4.3.2", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", - "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -65298,9 +65302,9 @@ } }, "pg-connection-string": { - "version": "2.5.0", - "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz", - "integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ==", + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==", "dev": true }, "pg-int8": { @@ -66280,12 +66284,12 @@ "dev": true }, "rechoir": { - "version": "0.7.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.7.0.tgz", - "integrity": "sha512-ADsDEH2bvbjltXEP+hTIAmeFekTFK0V2BTxMkok6qILyAJEXV0AFfoWcAq4yfll5VdIMd/RVXq0lR+wQi5ZU3Q==", + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", + "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", "dev": true, "requires": { - "resolve": "^1.9.0" + "resolve": "^1.20.0" } }, "redent": { @@ -69890,15 +69894,6 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-3.1.1.tgz", "integrity": "sha512-6xwYfHbajpoF0xLW+iwLkhwgvLoZDfjYfoFNu8ftMoXINzwuymNLd9u/KmwtdT2GbR+/Cz66otEGEVVUHX9QLQ==", "dev": true - }, - "rechoir": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/rechoir/-/rechoir-0.8.0.tgz", - "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==", - "dev": true, - "requires": { - "resolve": "^1.20.0" - } } } }, diff --git a/plugins/node/opentelemetry-instrumentation-knex/package.json b/plugins/node/opentelemetry-instrumentation-knex/package.json index f0dc382ede..498dffe944 100644 --- a/plugins/node/opentelemetry-instrumentation-knex/package.json +++ b/plugins/node/opentelemetry-instrumentation-knex/package.json @@ -48,7 +48,8 @@ "@opentelemetry/sdk-trace-node": "^1.8.0", "@types/mocha": "7.0.2", "@types/node": "18.18.14", - "knex": "0.95.9", + "better-sqlite3": "11.0.0", + "knex": "3.1.0", "nyc": "15.1.0", "rimraf": "5.0.10", "sqlite3": "5.1.7", diff --git a/plugins/node/opentelemetry-instrumentation-knex/src/instrumentation.ts b/plugins/node/opentelemetry-instrumentation-knex/src/instrumentation.ts index ca144b2751..5b7086895d 100644 --- a/plugins/node/opentelemetry-instrumentation-knex/src/instrumentation.ts +++ b/plugins/node/opentelemetry-instrumentation-knex/src/instrumentation.ts @@ -185,8 +185,8 @@ export class KnexInstrumentation extends InstrumentationBase { @@ -43,21 +40,27 @@ export const getFormatter = (runner: any) => { return () => ''; }; -export const cloneErrorWithNewMessage = (err: Exception, message: string) => { - if (err && err instanceof Error) { - const clonedError = new (err.constructor as Exception)(message); - clonedError.code = err.code; - clonedError.stack = err.stack; - clonedError.errno = err.errno; - return clonedError; +export function otelExceptionFromKnexError( + err: KnexError, + message: string +): Exception { + if (!(err && err instanceof Error)) { + return err; } - return err; -}; + + return { + message, + code: err.code, + stack: err.stack, + name: err.name, + }; +} const systemMap = new Map([ ['sqlite3', DBSYSTEMVALUES_SQLITE], ['pg', DBSYSTEMVALUES_POSTGRESQL], ]); + export const mapSystem = (knexSystem: string) => { return systemMap.get(knexSystem) || knexSystem; }; diff --git a/plugins/node/opentelemetry-instrumentation-knex/test/index.test.ts b/plugins/node/opentelemetry-instrumentation-knex/test/index.test.ts index 61f7be90b2..4b5bd1d8f3 100644 --- a/plugins/node/opentelemetry-instrumentation-knex/test/index.test.ts +++ b/plugins/node/opentelemetry-instrumentation-knex/test/index.test.ts @@ -197,6 +197,61 @@ describe('Knex instrumentation', () => { ); }); + it('should catch better-sqlite3 errors', async () => { + client = knex({ + client: 'better-sqlite3', + connection: { + filename: ':memory:', + }, + useNullAsDefault: true, + }); + + const parentSpan = tracer.startSpan('parentSpan'); + const MESSAGE = 'no such table: testTable1'; + const CODE = 'SQLITE_ERROR'; + + await context.with( + trace.setSpan(context.active(), parentSpan), + async () => { + try { + await client + .insert({ title: 'test1' }) + .into('testTable1') + .catch((err: any) => { + assertMatch(err.message, /SQLITE_ERROR/, err); + }); + } catch (e) { + // skip + } + parentSpan.end(); + + const events = memoryExporter.getFinishedSpans()[0].events!; + + assert.strictEqual(events.length, 1); + assert.strictEqual(events[0].name, 'exception'); + assert.strictEqual( + events[0].attributes?.['exception.message'], + MESSAGE + ); + assert.strictEqual(events[0].attributes?.['exception.type'], CODE); + + assertSpans( + memoryExporter.getFinishedSpans(), + [ + { + op: 'insert', + table: 'testTable1', + statement: 'insert into `testTable1` (`title`) values (?)', + parentSpan, + }, + null, + ], + { dbSystem: 'better-sqlite3' } + ); + } + ); + }); + describe('nested queries', () => { it('should correctly identify the table in nested queries', async () => { const parentSpan = tracer.startSpan('parentSpan'); @@ -527,7 +582,15 @@ describe('Knex instrumentation', () => { }); }); -const assertSpans = (actualSpans: any[], expectedSpans: any[]) => { +const assertSpans = ( + actualSpans: any[], + expectedSpans: any[], + options?: { dbSystem?: string } +) => { + const customAssertOptions = { + dbSystem: 'sqlite', + ...options, + }; assert(Array.isArray(actualSpans), 'Expected `actualSpans` to be an array'); assert( Array.isArray(expectedSpans), @@ -547,7 +610,10 @@ const assertSpans = (actualSpans: any[], expectedSpans: any[]) => { assert.strictEqual(span.kind, SpanKind.CLIENT); assertMatch(span.name, new RegExp(expected.op)); assertMatch(span.name, new RegExp(':memory:')); - assert.strictEqual(span.attributes['db.system'], 'sqlite'); + assert.strictEqual( + span.attributes['db.system'], + customAssertOptions.dbSystem + ); assert.strictEqual(span.attributes['db.name'], ':memory:'); assert.strictEqual(span.attributes['db.sql.table'], expected.table); assert.strictEqual(span.attributes['db.statement'], expected.statement);