diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 56b09f72..92b822a4 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -51,11 +51,20 @@ jobs: image: redis:7 ports: - 6379:6379 + mongodb: image: mongo:7 ports: - 27017:27017 + postgres: + image: postgres:16 + ports: + - "5432:5432" + env: + POSTGRES_HOST_AUTH_METHOD: 'trust' + POSTGRES_USER: 'postgres' + steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 diff --git a/package-lock.json b/package-lock.json index 8c996c8f..6d05bd34 100644 --- a/package-lock.json +++ b/package-lock.json @@ -751,6 +751,18 @@ "@opentelemetry/api": "^1.3.0" } }, + "node_modules/@opentelemetry/instrumentation-pg": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.39.1.tgz", + "integrity": "sha512-pX5ujDOyGpPcrZlzaD3LJzmyaSMMMKAP+ffTHJp9vasvZJr+LifCk53TMPVUafcXKV/xX/IIkvADO+67M1Z25g==", + "dependencies": { + "@opentelemetry/instrumentation": "^0.49.1", + "@opentelemetry/semantic-conventions": "^1.0.0", + "@opentelemetry/sql-common": "^0.40.0", + "@types/pg": "8.6.1", + "@types/pg-pool": "2.0.4" + } + }, "node_modules/@opentelemetry/instrumentation-mongodb": { "version": "0.41.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.41.0.tgz", @@ -985,6 +997,20 @@ "node": ">=14" } }, + "node_modules/@opentelemetry/sql-common": { + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.0.tgz", + "integrity": "sha512-vSqRJYUPJVjMFQpYkQS3ruexCPSZJ8esne3LazLwtCPaPRvzZ7WG3tX44RouAn7w4wMp8orKguBqtt+ng2UTnw==", + "dependencies": { + "@opentelemetry/core": "^1.1.0" + }, + "engines": { + "node": ">=14" + }, + "peerDependencies": { + "@opentelemetry/api": "^1.1.0" + } + }, "node_modules/@pkgjs/parseargs": { "version": "0.11.0", "dev": true, @@ -1115,6 +1141,24 @@ "undici-types": "~5.26.4" } }, + "node_modules/@types/pg": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", + "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "dependencies": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "node_modules/@types/pg-pool": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.4.tgz", + "integrity": "sha512-qZAvkv1K3QbmHHFYSNRYPkRjOWRLBYrL4B9c+wG0GSVGBw0NtJwPcgx/DSddeDJvRGMHCEQ4VMEVfuJ/0gZ3XQ==", + "dependencies": { + "@types/pg": "*" + } + }, "node_modules/@types/shimmer": { "version": "1.0.5", "license": "MIT" @@ -4727,6 +4771,92 @@ "node": ">=8" } }, + "node_modules/pg": { + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.5.tgz", + "integrity": "sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==", + "dev": true, + "dependencies": { + "pg-connection-string": "^2.6.4", + "pg-pool": "^3.6.2", + "pg-protocol": "^1.6.1", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "dev": true, + "optional": true + }, + "node_modules/pg-connection-string": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", + "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==", + "dev": true + }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", + "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", + "dev": true, + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", + "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dev": true, + "dependencies": { + "split2": "^4.1.0" + } + }, "node_modules/picomatch": { "version": "2.3.1", "dev": true, @@ -4843,6 +4973,41 @@ "node": ">=4" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "dev": true, @@ -6359,7 +6524,6 @@ }, "node_modules/xtend": { "version": "4.0.2", - "dev": true, "license": "MIT", "engines": { "node": ">=0.4" @@ -6447,6 +6611,7 @@ "@opentelemetry/instrumentation-http": "^0.49.1", "@opentelemetry/instrumentation-ioredis": "^0.38.0", "@opentelemetry/instrumentation-mongodb": "^0.41.0", + "@opentelemetry/instrumentation-pg": "^0.39.1", "@opentelemetry/resources": "^1.20.0", "@opentelemetry/sdk-logs": "^0.49.1", "@opentelemetry/sdk-node": "^0.49.1", @@ -6463,6 +6628,7 @@ "ioredis": "^5.3.2", "module-details-from-path": "^1.0.3", "mongodb": "^6.3.0", + "pg": "^8.11.5", "semver": "^7.6.0", "tape": "^5.7.5" }, @@ -6555,6 +6721,7 @@ "@opentelemetry/instrumentation-http": "^0.49.1", "@opentelemetry/instrumentation-ioredis": "^0.38.0", "@opentelemetry/instrumentation-mongodb": "^0.41.0", + "@opentelemetry/instrumentation-pg": "^0.39.1", "@opentelemetry/resources": "^1.20.0", "@opentelemetry/sdk-logs": "^0.49.1", "@opentelemetry/sdk-node": "^0.49.1", @@ -6566,6 +6733,7 @@ "ioredis": "^5.3.2", "module-details-from-path": "^1.0.3", "mongodb": "^6.3.0", + "pg": "^8.11.5", "safe-stable-stringify": "^2.4.3", "semver": "^7.6.0", "tape": "^5.7.5" @@ -7057,6 +7225,18 @@ "@types/ioredis4": "npm:@types/ioredis@^4.28.10" } }, + "@opentelemetry/instrumentation-pg": { + "version": "0.39.1", + "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-pg/-/instrumentation-pg-0.39.1.tgz", + "integrity": "sha512-pX5ujDOyGpPcrZlzaD3LJzmyaSMMMKAP+ffTHJp9vasvZJr+LifCk53TMPVUafcXKV/xX/IIkvADO+67M1Z25g==", + "requires": { + "@opentelemetry/instrumentation": "^0.49.1", + "@opentelemetry/semantic-conventions": "^1.0.0", + "@opentelemetry/sql-common": "^0.40.0", + "@types/pg": "8.6.1", + "@types/pg-pool": "2.0.4" + } + }, "@opentelemetry/instrumentation-mongodb": { "version": "0.41.0", "resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation-mongodb/-/instrumentation-mongodb-0.41.0.tgz", @@ -7206,6 +7386,14 @@ "resolved": "https://registry.npmjs.org/@opentelemetry/semantic-conventions/-/semantic-conventions-1.22.0.tgz", "integrity": "sha512-CAOgFOKLybd02uj/GhCdEeeBjOS0yeoDeo/CA7ASBSmenpZHAKGB3iDm/rv3BQLcabb/OprDEsSQ1y0P8A7Siw==" }, + "@opentelemetry/sql-common": { + "version": "0.40.0", + "resolved": "https://registry.npmjs.org/@opentelemetry/sql-common/-/sql-common-0.40.0.tgz", + "integrity": "sha512-vSqRJYUPJVjMFQpYkQS3ruexCPSZJ8esne3LazLwtCPaPRvzZ7WG3tX44RouAn7w4wMp8orKguBqtt+ng2UTnw==", + "requires": { + "@opentelemetry/core": "^1.1.0" + } + }, "@pkgjs/parseargs": { "version": "0.11.0", "dev": true, @@ -7311,6 +7499,24 @@ "undici-types": "~5.26.4" } }, + "@types/pg": { + "version": "8.6.1", + "resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.6.1.tgz", + "integrity": "sha512-1Kc4oAGzAl7uqUStZCDvaLFqZrW9qWSjXOmBfdgyBP5La7Us6Mg4GBvRlSoaZMhQF/zSj1C8CtKMBkoiT8eL8w==", + "requires": { + "@types/node": "*", + "pg-protocol": "*", + "pg-types": "^2.2.0" + } + }, + "@types/pg-pool": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/pg-pool/-/pg-pool-2.0.4.tgz", + "integrity": "sha512-qZAvkv1K3QbmHHFYSNRYPkRjOWRLBYrL4B9c+wG0GSVGBw0NtJwPcgx/DSddeDJvRGMHCEQ4VMEVfuJ/0gZ3XQ==", + "requires": { + "@types/pg": "*" + } + }, "@types/shimmer": { "version": "1.0.5" }, @@ -9724,6 +9930,71 @@ "version": "4.0.0", "dev": true }, + "pg": { + "version": "8.11.5", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.5.tgz", + "integrity": "sha512-jqgNHSKL5cbDjFlHyYsCXmQDrfIX/3RsNwYqpd4N0Kt8niLuNoRNH+aazv6cOd43gPh9Y4DjQCtb+X0MH0Hvnw==", + "dev": true, + "requires": { + "pg-cloudflare": "^1.1.1", + "pg-connection-string": "^2.6.4", + "pg-pool": "^3.6.2", + "pg-protocol": "^1.6.1", + "pg-types": "^2.1.0", + "pgpass": "1.x" + } + }, + "pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "dev": true, + "optional": true + }, + "pg-connection-string": { + "version": "2.6.4", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.4.tgz", + "integrity": "sha512-v+Z7W/0EO707aNMaAEfiGnGL9sxxumwLl2fJvCQtMn9Fxsg+lPpPkdcyBSv/KFgpGdYkMfn+EI1Or2EHjpgLCA==", + "dev": true + }, + "pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==" + }, + "pg-pool": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.2.tgz", + "integrity": "sha512-Htjbg8BlwXqSBQ9V8Vjtc+vzf/6fVUuak/3/XXKA9oxZprwW3IMDQTGHP+KDmVL7rtd+R1QjbnCFPuTHm3G4hg==", + "dev": true, + "requires": {} + }, + "pg-protocol": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.1.tgz", + "integrity": "sha512-jPIlvgoD63hrEuihvIg+tJhoGjUsLPn6poJY9N5CnlPd91c2T18T/9zBtLxZSb1EhYxBRoZJtzScCaWlYLtktg==" + }, + "pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "requires": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + } + }, + "pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dev": true, + "requires": { + "split2": "^4.1.0" + } + }, "picomatch": { "version": "2.3.1", "dev": true @@ -9805,6 +10076,29 @@ } } }, + "postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==" + }, + "postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==" + }, + "postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==" + }, + "postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "requires": { + "xtend": "^4.0.0" + } + }, "prelude-ls": { "version": "1.2.1", "dev": true @@ -10804,8 +11098,7 @@ "dev": true }, "xtend": { - "version": "4.0.2", - "dev": true + "version": "4.0.2" }, "y18n": { "version": "5.0.8" diff --git a/packages/opentelemetry-node/lib/instrumentations.js b/packages/opentelemetry-node/lib/instrumentations.js index b3bec2c1..40f7378f 100644 --- a/packages/opentelemetry-node/lib/instrumentations.js +++ b/packages/opentelemetry-node/lib/instrumentations.js @@ -11,6 +11,7 @@ * "@opentelemetry/instrumentation-express": import('@opentelemetry/instrumentation-express').ExpressInstrumentationConfig | InstrumentationFactory, * "@opentelemetry/instrumentation-fastify": import('@opentelemetry/instrumentation-fastify').FastifyInstrumentation | InstrumentationFactory, * "@opentelemetry/instrumentation-mongodb": import('@opentelemetry/instrumentation-mongodb').MongoDBInstrumentation | InstrumentationFactory + * "@opentelemetry/instrumentation-pg": import('@opentelemetry/instrumentation-pg').PgInstrumentation | InstrumentationFactory * }} InstrumentaionsMap */ @@ -30,6 +31,7 @@ const { const { MongoDBInstrumentation, } = require('@opentelemetry/instrumentation-mongodb'); +const {PgInstrumentation} = require('@opentelemetry/instrumentation-pg'); // Instrumentations attach their Hook (for require-in-the-middle or import-in-the-middle) // when the `enable` method is called and this happens inside their constructor @@ -52,6 +54,7 @@ const INSTRUMENTATIONS = { new IORedisInstrumentation(cfg), '@opentelemetry/instrumentation-mongodb': (cfg) => new MongoDBInstrumentation(cfg), + '@opentelemetry/instrumentation-pg': (cfg) => new PgInstrumentation(cfg), }; /** diff --git a/packages/opentelemetry-node/package.json b/packages/opentelemetry-node/package.json index c49fed56..3cb7326d 100644 --- a/packages/opentelemetry-node/package.json +++ b/packages/opentelemetry-node/package.json @@ -46,6 +46,7 @@ "@opentelemetry/instrumentation-http": "^0.49.1", "@opentelemetry/instrumentation-ioredis": "^0.38.0", "@opentelemetry/instrumentation-mongodb": "^0.41.0", + "@opentelemetry/instrumentation-pg": "^0.39.1", "@opentelemetry/resources": "^1.20.0", "@opentelemetry/sdk-logs": "^0.49.1", "@opentelemetry/sdk-node": "^0.49.1", @@ -62,6 +63,7 @@ "ioredis": "^5.3.2", "module-details-from-path": "^1.0.3", "mongodb": "^6.3.0", + "pg": "^8.11.5", "semver": "^7.6.0", "tape": "^5.7.5" } diff --git a/packages/opentelemetry-node/test/docker-compose.yaml b/packages/opentelemetry-node/test/docker-compose.yaml index 25a639a1..8b680a8f 100644 --- a/packages/opentelemetry-node/test/docker-compose.yaml +++ b/packages/opentelemetry-node/test/docker-compose.yaml @@ -1,5 +1,8 @@ # A `docker compose` config file to run tests services for testing -# `@elastic/opentelemetry-node`. +# `@elastic/opentelemetry-node` locally. +# +# Note: This isn't used in CI. CI uses GitHub Actions' `services: ...` for +# defining test services. # # Usage: # npm run test-services:start [services...] @@ -19,8 +22,6 @@ services: retries: 30 mongodb: - # TODO: discuss here if keep this version or use latest (7) - # my take is this is preferred if we want to run TAV tests image: mongo:7 ports: - "27017:27017" @@ -29,3 +30,17 @@ services: interval: 1s timeout: 10s retries: 30 + + postgres: + # https://github.com/docker-library/docs/blob/master/postgres/README.md#how-to-extend-this-image + image: postgres:16 + ports: + - "5432:5432" + environment: + POSTGRES_HOST_AUTH_METHOD: 'trust' + POSTGRES_USER: 'postgres' + healthcheck: + test: ["CMD", "pg_isready"] + interval: 1s + timeout: 10s + retries: 30 diff --git a/packages/opentelemetry-node/test/fixtures/use-pg.js b/packages/opentelemetry-node/test/fixtures/use-pg.js new file mode 100644 index 00000000..3a45f0ae --- /dev/null +++ b/packages/opentelemetry-node/test/fixtures/use-pg.js @@ -0,0 +1,22 @@ +// Usage: node -r ../../start.js use-pg.js + +const otel = require('@opentelemetry/api'); +const {Client} = require('pg'); + +async function main() { + const client = new Client({ + user: process.env.PGUSER || 'postgres', + }); + await client.connect(); + + const res = await client.query('SELECT $1::text as message', ['hi']); + console.log('SELECT result:', res.rows[0].message); + + await client.end(); +} + +const tracer = otel.trace.getTracer('test'); +tracer.startActiveSpan('manual-parent-span', (span) => { + main(); + span.end(); +}); diff --git a/packages/opentelemetry-node/test/instr-pg.test.js b/packages/opentelemetry-node/test/instr-pg.test.js new file mode 100644 index 00000000..0b93b4a5 --- /dev/null +++ b/packages/opentelemetry-node/test/instr-pg.test.js @@ -0,0 +1,45 @@ +const test = require('tape'); +const {runTestFixtures} = require('./testutils'); + +const skip = process.env.PGHOST === undefined; +if (skip) { + console.log( + '# SKIP pg tests: PGHOST is not set (try with `PGHOST=localhost`)' + ); +} + +/** @type {import('./testutils').TestFixture[]} */ +const testFixtures = [ + { + name: 'use-pg', + args: ['./fixtures/use-pg.js'], + cwd: __dirname, + env: { + NODE_OPTIONS: '--require=../start.js', + }, + // verbose: true, + checkTelemetry: (t, col) => { + // Expected a trace like this: + // ------ trace 9169b6 (3 spans) ------ + // span 102150 "manual-parent-span" (7.5ms, SPAN_KIND_INTERNAL) + // +3ms `- span 539d9d "pg.connect" (12.0ms, SPAN_KIND_CLIENT) + // +13ms `- span 115c08 "pg.query:SELECT postgres" (2.4ms, SPAN_KIND_CLIENT) + const spans = col.sortedSpans; + t.equal(spans.length, 3); + spans.slice(1).forEach((s) => { + t.equal(s.traceId, spans[0].traceId, 'traceId'); + t.equal(s.parentSpanId, spans[0].spanId, 'parentSpanId'); + t.equal(s.kind, 'SPAN_KIND_CLIENT', 'kind'); + t.equal(s.scope.name, '@opentelemetry/instrumentation-pg'); + t.equal(s.attributes['db.system'], 'postgresql'); + }); + t.equal(spans[1].name, 'pg.connect'); + t.equal(spans[2].name, 'pg.query:SELECT postgres'); + }, + }, +]; + +test('pg instrumentation', {skip}, (suite) => { + runTestFixtures(suite, testFixtures); + suite.end(); +}); diff --git a/packages/opentelemetry-node/test/test-services.env b/packages/opentelemetry-node/test/test-services.env index 42ebb0f3..08cf1fac 100644 --- a/packages/opentelemetry-node/test/test-services.env +++ b/packages/opentelemetry-node/test/test-services.env @@ -1,2 +1,3 @@ REDIS_HOST=localhost +PGHOST=localhost MONGODB_HOST=localhost