diff --git a/package-lock.json b/package-lock.json
index 4a35f3134f..4464c66ed1 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -9543,6 +9543,8 @@
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
"integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
"dev": true,
+ "optional": true,
+ "peer": true,
"peerDependencies": {
"@redis/client": "^1.0.0"
}
@@ -9552,6 +9554,8 @@
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.1.tgz",
"integrity": "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==",
"dev": true,
+ "optional": true,
+ "peer": true,
"dependencies": {
"cluster-key-slot": "1.1.2",
"generic-pool": "3.9.0",
@@ -9566,6 +9570,8 @@
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
"dev": true,
+ "optional": true,
+ "peer": true,
"engines": {
"node": ">= 4"
}
@@ -9574,13 +9580,17 @@
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
+ "dev": true,
+ "optional": true,
+ "peer": true
},
"node_modules/@redis/graph": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
"integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
"dev": true,
+ "optional": true,
+ "peer": true,
"peerDependencies": {
"@redis/client": "^1.0.0"
}
@@ -9590,6 +9600,8 @@
"resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz",
"integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
"dev": true,
+ "optional": true,
+ "peer": true,
"peerDependencies": {
"@redis/client": "^1.0.0"
}
@@ -9599,6 +9611,8 @@
"resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz",
"integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
"dev": true,
+ "optional": true,
+ "peer": true,
"peerDependencies": {
"@redis/client": "^1.0.0"
}
@@ -9608,6 +9622,8 @@
"resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz",
"integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
"dev": true,
+ "optional": true,
+ "peer": true,
"peerDependencies": {
"@redis/client": "^1.0.0"
}
@@ -27419,6 +27435,8 @@
"resolved": "https://registry.npmjs.org/redis/-/redis-4.7.1.tgz",
"integrity": "sha512-S1bJDnqLftzHXHP8JsT5II/CtHWQrASX5K96REjWjlmWKrviSOLWmM7QnRLstAWsu1VBBV1ffV6DzCvxNP0UJQ==",
"dev": true,
+ "optional": true,
+ "peer": true,
"dependencies": {
"@redis/bloom": "1.2.0",
"@redis/client": "1.6.1",
@@ -34841,7 +34859,7 @@
"@types/node": "18.18.14",
"cross-env": "7.0.3",
"nyc": "17.1.0",
- "redis": "^4.7.1",
+ "redis": "^5.6.0",
"rimraf": "5.0.10",
"test-all-versions": "6.1.0",
"typescript": "5.0.4"
@@ -34853,6 +34871,71 @@
"@opentelemetry/api": "^1.3.0"
}
},
+ "packages/instrumentation-redis/node_modules/@redis/bloom": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.6.0.tgz",
+ "integrity": "sha512-l13/d6BaZDJzogzZJEphIeZ8J0hpQpjkMiozomTm6nJiMNYkoPsNOBOOQua4QsG0fFjyPmLMDJFPAp5FBQtTXg==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "@redis/client": "^5.6.0"
+ }
+ },
+ "packages/instrumentation-redis/node_modules/@redis/client": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.6.0.tgz",
+ "integrity": "sha512-wmP9kCFElCSr4MM4+1E4VckDuN4wLtiXSM/J0rKVQppajxQhowci89RGZr2OdLualowb8SRJ/R6OjsXrn9ZNFA==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "cluster-key-slot": "1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "packages/instrumentation-redis/node_modules/@redis/json": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/json/-/json-5.6.0.tgz",
+ "integrity": "sha512-YQN9ZqaSDpdLfJqwzcF4WeuJMGru/h4WsV7GeeNtXsSeyQjHTyDxrd48xXfRRJGv7HitA7zGnzdHplNeKOgrZA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "@redis/client": "^5.6.0"
+ }
+ },
+ "packages/instrumentation-redis/node_modules/@redis/search": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/search/-/search-5.6.0.tgz",
+ "integrity": "sha512-sLgQl92EyMVNHtri5K8Q0j2xt9c0cO9HYurXz667Un4xeUYR+B/Dw5lLG35yqO7VvVxb9amHJo9sAWumkKZYwA==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "@redis/client": "^5.6.0"
+ }
+ },
+ "packages/instrumentation-redis/node_modules/@redis/time-series": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-5.6.0.tgz",
+ "integrity": "sha512-tXABmN1vu4aTNL3WI4Iolpvx/5jgil2Bs31ozvKblT+jkUoRkk8ykmYo9Pv/Mp7Gk6/Qkr/2rMgVminrt/4BBQ==",
+ "dev": true,
+ "license": "MIT",
+ "engines": {
+ "node": ">= 18"
+ },
+ "peerDependencies": {
+ "@redis/client": "^5.6.0"
+ }
+ },
"packages/instrumentation-redis/node_modules/@types/node": {
"version": "18.18.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.14.tgz",
@@ -34862,6 +34945,36 @@
"undici-types": "~5.26.4"
}
},
+ "packages/instrumentation-redis/node_modules/redis": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-5.6.0.tgz",
+ "integrity": "sha512-0x3pM3SlYA5azdNwO8qgfMBzoOqSqr9M+sd1hojbcn0ZDM5zsmKeMM+zpTp6LIY+mbQomIc/RTTQKuBzr8QKzQ==",
+ "dev": true,
+ "license": "MIT",
+ "dependencies": {
+ "@redis/bloom": "5.6.0",
+ "@redis/client": "5.6.0",
+ "@redis/json": "5.6.0",
+ "@redis/search": "5.6.0",
+ "@redis/time-series": "5.6.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "packages/instrumentation-redis/node_modules/typescript": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
+ "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
+ "dev": true,
+ "bin": {
+ "tsc": "bin/tsc",
+ "tsserver": "bin/tsserver"
+ },
+ "engines": {
+ "node": ">=12.20"
+ }
+ },
"packages/instrumentation-redis/node_modules/undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
@@ -45266,12 +45379,49 @@
"@types/node": "18.18.14",
"cross-env": "7.0.3",
"nyc": "17.1.0",
- "redis": "^4.7.1",
+ "redis": "^5.6.0",
"rimraf": "5.0.10",
"test-all-versions": "6.1.0",
"typescript": "5.0.4"
},
"dependencies": {
+ "@redis/bloom": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-5.6.0.tgz",
+ "integrity": "sha512-l13/d6BaZDJzogzZJEphIeZ8J0hpQpjkMiozomTm6nJiMNYkoPsNOBOOQua4QsG0fFjyPmLMDJFPAp5FBQtTXg==",
+ "dev": true,
+ "requires": {}
+ },
+ "@redis/client": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/client/-/client-5.6.0.tgz",
+ "integrity": "sha512-wmP9kCFElCSr4MM4+1E4VckDuN4wLtiXSM/J0rKVQppajxQhowci89RGZr2OdLualowb8SRJ/R6OjsXrn9ZNFA==",
+ "dev": true,
+ "requires": {
+ "cluster-key-slot": "1.1.2"
+ }
+ },
+ "@redis/json": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/json/-/json-5.6.0.tgz",
+ "integrity": "sha512-YQN9ZqaSDpdLfJqwzcF4WeuJMGru/h4WsV7GeeNtXsSeyQjHTyDxrd48xXfRRJGv7HitA7zGnzdHplNeKOgrZA==",
+ "dev": true,
+ "requires": {}
+ },
+ "@redis/search": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/search/-/search-5.6.0.tgz",
+ "integrity": "sha512-sLgQl92EyMVNHtri5K8Q0j2xt9c0cO9HYurXz667Un4xeUYR+B/Dw5lLG35yqO7VvVxb9amHJo9sAWumkKZYwA==",
+ "dev": true,
+ "requires": {}
+ },
+ "@redis/time-series": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-5.6.0.tgz",
+ "integrity": "sha512-tXABmN1vu4aTNL3WI4Iolpvx/5jgil2Bs31ozvKblT+jkUoRkk8ykmYo9Pv/Mp7Gk6/Qkr/2rMgVminrt/4BBQ==",
+ "dev": true,
+ "requires": {}
+ },
"@types/node": {
"version": "18.18.14",
"resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.14.tgz",
@@ -45281,6 +45431,25 @@
"undici-types": "~5.26.4"
}
},
+ "redis": {
+ "version": "5.6.0",
+ "resolved": "https://registry.npmjs.org/redis/-/redis-5.6.0.tgz",
+ "integrity": "sha512-0x3pM3SlYA5azdNwO8qgfMBzoOqSqr9M+sd1hojbcn0ZDM5zsmKeMM+zpTp6LIY+mbQomIc/RTTQKuBzr8QKzQ==",
+ "dev": true,
+ "requires": {
+ "@redis/bloom": "5.6.0",
+ "@redis/client": "5.6.0",
+ "@redis/json": "5.6.0",
+ "@redis/search": "5.6.0",
+ "@redis/time-series": "5.6.0"
+ }
+ },
+ "typescript": {
+ "version": "5.0.4",
+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.0.4.tgz",
+ "integrity": "sha512-cW9T5W9xY37cc+jfEnaUvX91foxtHkza3Nw3wkoF4sSlKn0MONdkdEndig/qPBWXNkmplh3NzayQzCiHM4/hqw==",
+ "dev": true
+ },
"undici-types": {
"version": "5.26.5",
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
@@ -46947,6 +47116,8 @@
"resolved": "https://registry.npmjs.org/@redis/bloom/-/bloom-1.2.0.tgz",
"integrity": "sha512-HG2DFjYKbpNmVXsa0keLHp/3leGJz1mjh09f2RLGGLQZzSHpkmZWuwJbAvo3QcRY8p80m5+ZdXZdYOSBLlp7Cg==",
"dev": true,
+ "optional": true,
+ "peer": true,
"requires": {}
},
"@redis/client": {
@@ -46954,6 +47125,8 @@
"resolved": "https://registry.npmjs.org/@redis/client/-/client-1.6.1.tgz",
"integrity": "sha512-/KCsg3xSlR+nCK8/8ZYSknYxvXHwubJrU82F3Lm1Fp6789VQ0/3RJKfsmRXjqfaTA++23CvC3hqmqe/2GEt6Kw==",
"dev": true,
+ "optional": true,
+ "peer": true,
"requires": {
"cluster-key-slot": "1.1.2",
"generic-pool": "3.9.0",
@@ -46964,13 +47137,17 @@
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/generic-pool/-/generic-pool-3.9.0.tgz",
"integrity": "sha512-hymDOu5B53XvN4QT9dBmZxPX4CWhBPPLguTZ9MMFeFa/Kg0xWVfylOVNlJji/E7yTZWFd/q9GO5TxDLq156D7g==",
- "dev": true
+ "dev": true,
+ "optional": true,
+ "peer": true
},
"yallist": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==",
- "dev": true
+ "dev": true,
+ "optional": true,
+ "peer": true
}
}
},
@@ -46979,6 +47156,8 @@
"resolved": "https://registry.npmjs.org/@redis/graph/-/graph-1.1.1.tgz",
"integrity": "sha512-FEMTcTHZozZciLRl6GiiIB4zGm5z5F3F6a6FZCyrfxdKOhFlGkiAqlexWMBzCi4DcRoyiOsuLfW+cjlGWyExOw==",
"dev": true,
+ "optional": true,
+ "peer": true,
"requires": {}
},
"@redis/json": {
@@ -46986,6 +47165,8 @@
"resolved": "https://registry.npmjs.org/@redis/json/-/json-1.0.7.tgz",
"integrity": "sha512-6UyXfjVaTBTJtKNG4/9Z8PSpKE6XgSyEb8iwaqDcy+uKrd/DGYHTWkUdnQDyzm727V7p21WUMhsqz5oy65kPcQ==",
"dev": true,
+ "optional": true,
+ "peer": true,
"requires": {}
},
"@redis/search": {
@@ -46993,6 +47174,8 @@
"resolved": "https://registry.npmjs.org/@redis/search/-/search-1.2.0.tgz",
"integrity": "sha512-tYoDBbtqOVigEDMAcTGsRlMycIIjwMCgD8eR2t0NANeQmgK/lvxNAvYyb6bZDD4frHRhIHkJu2TBRvB0ERkOmw==",
"dev": true,
+ "optional": true,
+ "peer": true,
"requires": {}
},
"@redis/time-series": {
@@ -47000,6 +47183,8 @@
"resolved": "https://registry.npmjs.org/@redis/time-series/-/time-series-1.1.0.tgz",
"integrity": "sha512-c1Q99M5ljsIuc4YdaCwfUEXsofakb9c8+Zse2qxTadu8TalLXuAESzLvFAvNVbkmSlvlzIQOLpBCmWI9wTOt+g==",
"dev": true,
+ "optional": true,
+ "peer": true,
"requires": {}
},
"@rollup/plugin-commonjs": {
@@ -60688,6 +60873,8 @@
"resolved": "https://registry.npmjs.org/redis/-/redis-4.7.1.tgz",
"integrity": "sha512-S1bJDnqLftzHXHP8JsT5II/CtHWQrASX5K96REjWjlmWKrviSOLWmM7QnRLstAWsu1VBBV1ffV6DzCvxNP0UJQ==",
"dev": true,
+ "optional": true,
+ "peer": true,
"requires": {
"@redis/bloom": "1.2.0",
"@redis/client": "1.6.1",
diff --git a/packages/instrumentation-redis/.tav.yml b/packages/instrumentation-redis/.tav.yml
index 12aa469538..47d23f9878 100644
--- a/packages/instrumentation-redis/.tav.yml
+++ b/packages/instrumentation-redis/.tav.yml
@@ -4,8 +4,8 @@ redis:
mode: latest-minors
commands: npm run test-v2-v3
- versions:
- include: '>=4 <5'
+ include: '>=4 <6'
# "4.6.9" was a bad release that accidentally broke node v14 support.
exclude: "4.6.9"
mode: latest-minors
- commands: npm test
+ commands: npm run test
\ No newline at end of file
diff --git a/packages/instrumentation-redis/README.md b/packages/instrumentation-redis/README.md
index b2827e72f4..b45de68231 100644
--- a/packages/instrumentation-redis/README.md
+++ b/packages/instrumentation-redis/README.md
@@ -3,7 +3,7 @@
[![NPM Published Version][npm-img]][npm-url]
[![Apache License][license-image]][license-image]
-This module provides automatic instrumentation for the [`redis`](https://github.com/NodeRedis/node_redis) module versions `>=2.6.0 <5`, which may be loaded using the [`@opentelemetry/sdk-trace-node`](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node) package and is included in the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle.
+This module provides automatic instrumentation for the [`redis`](https://github.com/NodeRedis/node_redis) module versions `>=2.6.0 <6`, which may be loaded using the [`@opentelemetry/sdk-trace-node`](https://github.com/open-telemetry/opentelemetry-js/tree/main/packages/opentelemetry-sdk-trace-node) package and is included in the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle.
If total installation size is not constrained, it is recommended to use the [`@opentelemetry/auto-instrumentations-node`](https://www.npmjs.com/package/@opentelemetry/auto-instrumentations-node) bundle with [@opentelemetry/sdk-node](`https://www.npmjs.com/package/@opentelemetry/sdk-node`) for the most seamless instrumentation experience.
@@ -17,7 +17,7 @@ npm install --save @opentelemetry/instrumentation-redis
### Supported Versions
-- [`redis`](https://www.npmjs.com/package/redis) versions `>=2.6.0 <5`
+- [`redis`](https://www.npmjs.com/package/redis) versions `>=2.6.0 <6`
## Usage
@@ -75,10 +75,16 @@ const redisInstrumentation = new RedisInstrumentation({
## Semantic Conventions
-This package uses `@opentelemetry/semantic-conventions` version `1.22+`, which implements Semantic Convention [Version 1.7.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/semantic_conventions/README.md)
+
+This package uses `@opentelemetry/semantic-conventions` version `1.22+`, which implements Semantic Convention [Version 1.7.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/semantic_conventions/README.md) ("old" conventions).
+
+It also supports the new stable semantic conventions introduced in [Version 1.33.0]
+By default, old semantic conventions are used. Use the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable to control which version to emit.
Attributes collected:
+### Old Semantic Conventions (default)
+
| Attribute | Short Description |
|------------------------|--------------------------------------------------------------|
| `db.connection_string` | URL to Redis server address, of the form `redis://host:port` |
@@ -87,6 +93,17 @@ Attributes collected:
| `net.peer.name` | Hostname or IP of the connected Redis server |
| `net.peer.port` | Port of the connected Redis server |
+### Stable Semantic Conventions (v1.33.0)
+
+| Attribute | Short Description |
+|------------------------|--------------------------------------------------------------|
+| `db.operation.name` | Redis command name |
+| `db.operation.batch.size` | Number of commands in a Redis `MULTI/EXEC` transaction |
+| `db.query.text` | The database query being executed |
+| `db.system.name` | Database identifier; always `redis` |
+| `server.address` | Hostname or IP of the connected Redis server |
+| `server.port` | Port of the connected Redis server |
+
## Useful links
- For more information on OpenTelemetry, visit:
diff --git a/packages/instrumentation-redis/package.json b/packages/instrumentation-redis/package.json
index 63b02835e8..0ebfa3d4d5 100644
--- a/packages/instrumentation-redis/package.json
+++ b/packages/instrumentation-redis/package.json
@@ -19,7 +19,7 @@
"prepublishOnly": "npm run compile",
"tdd": "npm run test -- --watch-extensions ts --watch",
"test-v2-v3": "nyc mocha --require '@opentelemetry/contrib-test-utils' 'test/v2-v3/*.test.ts'",
- "test": "nyc mocha --require '@opentelemetry/contrib-test-utils' 'test/v4/*.test.ts'",
+ "test": "nyc mocha --require '@opentelemetry/contrib-test-utils' 'test/v4-v5/*.test.ts'",
"test:debug": "cross-env RUN_REDIS_TESTS=true mocha --inspect-brk --no-timeouts 'test/**/*.test.ts'",
"test:with-services-env": "cross-env NODE_OPTIONS='-r dotenv/config' DOTENV_CONFIG_PATH=../../test/test-services.env npm test",
"test-all-versions": "tav",
@@ -62,7 +62,7 @@
"@types/node": "18.18.14",
"cross-env": "7.0.3",
"nyc": "17.1.0",
- "redis": "^4.7.1",
+ "redis": "^5.6.0",
"rimraf": "5.0.10",
"test-all-versions": "6.1.0",
"typescript": "5.0.4"
diff --git a/packages/instrumentation-redis/src/redis.ts b/packages/instrumentation-redis/src/redis.ts
index 14c2003dce..fb9bfe331d 100644
--- a/packages/instrumentation-redis/src/redis.ts
+++ b/packages/instrumentation-redis/src/redis.ts
@@ -19,7 +19,7 @@ import { RedisInstrumentationConfig } from './types';
import { PACKAGE_NAME, PACKAGE_VERSION } from './version';
import { RedisInstrumentationV2_V3 } from './v2-v3/instrumentation';
import { TracerProvider } from '@opentelemetry/api';
-import { RedisInstrumentationV4 } from './v4/instrumentation';
+import { RedisInstrumentationV4_V5 } from './v4-v5/instrumentation';
const DEFAULT_CONFIG: RedisInstrumentationConfig = {
requireParentSpan: false,
@@ -28,7 +28,7 @@ const DEFAULT_CONFIG: RedisInstrumentationConfig = {
// Wrapper RedisInstrumentation that address all supported versions
export class RedisInstrumentation extends InstrumentationBase {
private instrumentationV2_V3: RedisInstrumentationV2_V3;
- private instrumentationV4: RedisInstrumentationV4;
+ private instrumentationV4_V5: RedisInstrumentationV4_V5;
// this is used to bypass a flaw in the base class constructor, which is calling
// member functions before the constructor has a chance to fully initialize the member variables.
@@ -39,7 +39,7 @@ export class RedisInstrumentation extends InstrumentationBase {
static readonly COMPONENT = 'redis';
+ private _semconvStability: SemconvStability;
constructor(config: RedisInstrumentationConfig = {}) {
super(PACKAGE_NAME, PACKAGE_VERSION, config);
+ this._semconvStability = config.semconvStability
+ ? config.semconvStability
+ : semconvStabilityFromStr(
+ 'database',
+ process.env.OTEL_SEMCONV_STABILITY_OPT_IN
+ );
+ }
+
+ override setConfig(config: RedisInstrumentationConfig = {}) {
+ super.setConfig(config);
+ this._semconvStability = config.semconvStability
+ ? config.semconvStability
+ : semconvStabilityFromStr(
+ 'database',
+ process.env.OTEL_SEMCONV_STABILITY_OPT_IN
+ );
}
protected init() {
@@ -127,28 +151,60 @@ export class RedisInstrumentationV2_V3 extends InstrumentationBase;
}
-export class RedisInstrumentationV4 extends InstrumentationBase {
+export class RedisInstrumentationV4_V5 extends InstrumentationBase {
static readonly COMPONENT = 'redis';
+ private _semconvStability: SemconvStability;
constructor(config: RedisInstrumentationConfig = {}) {
super(PACKAGE_NAME, PACKAGE_VERSION, config);
+ this._semconvStability = config.semconvStability
+ ? config.semconvStability
+ : semconvStabilityFromStr(
+ 'database',
+ process.env.OTEL_SEMCONV_STABILITY_OPT_IN
+ );
+ }
+
+ override setConfig(config: RedisInstrumentationConfig = {}) {
+ super.setConfig(config);
+ this._semconvStability = config.semconvStability
+ ? config.semconvStability
+ : semconvStabilityFromStr(
+ 'database',
+ process.env.OTEL_SEMCONV_STABILITY_OPT_IN
+ );
}
protected init() {
@@ -111,7 +134,7 @@ export class RedisInstrumentationV4 extends InstrumentationBase {
const redisClientMultiCommandPrototype =
moduleExports?.default?.prototype;
@@ -150,7 +173,7 @@ export class RedisInstrumentationV4 extends InstrumentationBase {
const redisClientPrototype = moduleExports?.default?.prototype;
@@ -213,7 +236,7 @@ export class RedisInstrumentationV4 extends InstrumentationBase {
return moduleExports;
},
@@ -327,11 +350,14 @@ export class RedisInstrumentationV4 extends InstrumentationBase {
const options = this.options;
-
- const attributes = getClientAttributes(plugin._diag, options);
+ const attributes = getClientAttributes(
+ plugin._diag,
+ options,
+ plugin._semconvStability
+ );
const span = plugin.tracer.startSpan(
- `${RedisInstrumentationV4.COMPONENT}-connect`,
+ `${RedisInstrumentationV4_V5.COMPONENT}-connect`,
{
kind: SpanKind.CLIENT,
attributes,
@@ -379,12 +405,23 @@ export class RedisInstrumentationV4 extends InstrumentationBase {
description: string;
command: string;
args: string[];
- expectedDbStatement: string;
+ expectedDbStatementOld: string;
+ expectedDbStatementStable: string;
method: (cb: Callback) => unknown;
}> = [
{
description: 'insert',
command: 'hset',
args: ['hash', 'random', 'random'],
- expectedDbStatement: 'hash random [1 other arguments]',
+ expectedDbStatementOld: 'hash random [1 other arguments]',
+ expectedDbStatementStable: 'hset hash random [1 other arguments]',
method: (cb: Callback) =>
client.hset('hash', 'random', 'random', cb),
},
@@ -120,14 +132,16 @@ describe('redis v2-v3', () => {
description: 'get',
command: 'get',
args: ['test'],
- expectedDbStatement: 'test',
+ expectedDbStatementOld: 'test',
+ expectedDbStatementStable: 'get test',
method: (cb: Callback) => client.get('test', cb),
},
{
description: 'delete',
command: 'del',
args: ['test'],
- expectedDbStatement: 'test',
+ expectedDbStatementOld: 'test',
+ expectedDbStatementStable: 'del test',
method: (cb: Callback) => client.del('test', cb),
},
];
@@ -157,13 +171,135 @@ describe('redis v2-v3', () => {
done();
});
});
+ describe('semconv stability config', () => {
+ function recordSpanForOperation(operation: any, cb: (span: any) => void) {
+ operation.method((err: unknown) => {
+ assert.ifError(err);
+ const [span] = testUtils.getTestSpans();
+ cb(span);
+ });
+ }
+
+ describe('semconv stability with get operation', () => {
+ const operation = REDIS_OPERATIONS.find(op => op.command === 'get')!;
+
+ it('should emit only old attributes when set to OLD', done => {
+ instrumentation.setConfig({ semconvStability: SemconvStability.OLD });
+
+ recordSpanForOperation(operation, span => {
+ assert.strictEqual(span.attributes[SEMATTRS_DB_SYSTEM], 'redis');
+ assert.strictEqual(
+ span.attributes[SEMATTRS_DB_STATEMENT],
+ `${operation.command} ${operation.expectedDbStatementOld}`
+ );
+
+ assert.ok(!(ATTR_DB_SYSTEM_NAME in span.attributes));
+ assert.ok(!(ATTR_DB_QUERY_TEXT in span.attributes));
+ assert.ok(!(ATTR_DB_OPERATION_NAME in span.attributes));
+
+ assert.strictEqual(
+ span.attributes[SEMATTRS_NET_PEER_NAME],
+ CONFIG.host
+ );
+ assert.strictEqual(
+ span.attributes[SEMATTRS_NET_PEER_PORT],
+ CONFIG.port
+ );
+ assert.strictEqual(
+ span.attributes[SEMATTRS_DB_CONNECTION_STRING],
+ URL
+ );
+
+ assert.ok(!(ATTR_SERVER_ADDRESS in span.attributes));
+ assert.ok(!(ATTR_SERVER_PORT in span.attributes));
+ done();
+ });
+ });
+
+ it('should emit only new attributes when set to STABLE', done => {
+ instrumentation.setConfig({
+ semconvStability: SemconvStability.STABLE,
+ });
+
+ recordSpanForOperation(operation, span => {
+ assert.strictEqual(span.attributes[ATTR_DB_SYSTEM_NAME], 'redis');
+ assert.strictEqual(
+ span.attributes[ATTR_DB_QUERY_TEXT],
+ operation.expectedDbStatementStable
+ );
+ assert.strictEqual(
+ span.attributes[ATTR_DB_OPERATION_NAME],
+ operation.command
+ );
+
+ assert.ok(!(SEMATTRS_DB_SYSTEM in span.attributes));
+ assert.ok(!(SEMATTRS_DB_STATEMENT in span.attributes));
+
+ assert.strictEqual(
+ span.attributes[ATTR_SERVER_ADDRESS],
+ CONFIG.host
+ );
+ assert.strictEqual(span.attributes[ATTR_SERVER_PORT], CONFIG.port);
+
+ assert.ok(!(SEMATTRS_NET_PEER_NAME in span.attributes));
+ assert.ok(!(SEMATTRS_NET_PEER_PORT in span.attributes));
+ assert.ok(!(SEMATTRS_DB_CONNECTION_STRING in span.attributes));
+ done();
+ });
+ });
+
+ it('should emit both old and new attributes when set to DUPLICATE', done => {
+ instrumentation.setConfig({
+ semconvStability: SemconvStability.DUPLICATE,
+ });
+
+ recordSpanForOperation(operation, span => {
+ assert.strictEqual(span.attributes[SEMATTRS_DB_SYSTEM], 'redis');
+ assert.strictEqual(
+ span.attributes[SEMATTRS_DB_STATEMENT],
+ `${operation.command} ${operation.expectedDbStatementOld}`
+ );
+ assert.strictEqual(span.attributes[ATTR_DB_SYSTEM_NAME], 'redis');
+ assert.strictEqual(
+ span.attributes[ATTR_DB_QUERY_TEXT],
+ operation.expectedDbStatementStable
+ );
+ assert.strictEqual(
+ span.attributes[ATTR_DB_OPERATION_NAME],
+ operation.command
+ );
+
+ assert.strictEqual(
+ span.attributes[SEMATTRS_NET_PEER_NAME],
+ CONFIG.host
+ );
+ assert.strictEqual(
+ span.attributes[SEMATTRS_NET_PEER_PORT],
+ CONFIG.port
+ );
+ assert.strictEqual(
+ span.attributes[ATTR_SERVER_ADDRESS],
+ CONFIG.host
+ );
+ assert.strictEqual(span.attributes[ATTR_SERVER_PORT], CONFIG.port);
+ assert.strictEqual(
+ span.attributes[SEMATTRS_DB_CONNECTION_STRING],
+ URL
+ );
+ done();
+ });
+ });
+ });
+ });
describe('Instrumenting query operations', () => {
REDIS_OPERATIONS.forEach(operation => {
it(`should create a child span for ${operation.description}`, done => {
const attributes = {
...DEFAULT_ATTRIBUTES,
- [SEMATTRS_DB_STATEMENT]: `${operation.command} ${operation.expectedDbStatement}`,
+ [ATTR_DB_OPERATION_NAME]: operation.command,
+ [ATTR_DB_QUERY_TEXT]: operation.expectedDbStatementStable,
+ [SEMATTRS_DB_STATEMENT]: `${operation.command} ${operation.expectedDbStatementOld}`,
};
const span = tracer.startSpan('test span');
context.with(trace.setSpan(context.active(), span), () => {
@@ -177,6 +313,7 @@ describe('redis v2-v3', () => {
endedSpans[0].name,
`redis-${operation.command}`
);
+
testUtils.assertSpan(
endedSpans[0],
SpanKind.CLIENT,
@@ -233,6 +370,11 @@ describe('redis v2-v3', () => {
endedSpans[0].attributes[SEMATTRS_DB_STATEMENT],
expectedStatement
);
+
+ assert.strictEqual(
+ endedSpans[0].attributes[ATTR_DB_QUERY_TEXT],
+ expectedStatement
+ );
done();
});
});
diff --git a/packages/instrumentation-redis/test/v4/redis.test.ts b/packages/instrumentation-redis/test/v4-v5/redis.test.ts
similarity index 73%
rename from packages/instrumentation-redis/test/v4/redis.test.ts
rename to packages/instrumentation-redis/test/v4-v5/redis.test.ts
index 9b92d52f75..d749056c31 100644
--- a/packages/instrumentation-redis/test/v4/redis.test.ts
+++ b/packages/instrumentation-redis/test/v4-v5/redis.test.ts
@@ -20,11 +20,12 @@ import {
registerInstrumentationTesting,
} from '@opentelemetry/contrib-test-utils';
import { RedisInstrumentation } from '../../src';
-import type { MultiErrorReply } from '../../src/v4/internal-types';
+import type { MultiErrorReply } from '../../src/v4-v5/internal-types';
import * as assert from 'assert';
import { redisTestConfig, redisTestUrl, shouldTest } from './utils';
+process.env.OTEL_SEMCONV_STABILITY_OPT_IN = 'database/dup';
const instrumentation = registerInstrumentationTesting(
new RedisInstrumentation()
);
@@ -45,11 +46,18 @@ import {
SEMATTRS_EXCEPTION_MESSAGE,
SEMATTRS_NET_PEER_NAME,
SEMATTRS_NET_PEER_PORT,
+ ATTR_DB_SYSTEM_NAME,
+ ATTR_DB_OPERATION_NAME,
+ ATTR_DB_QUERY_TEXT,
+ ATTR_SERVER_ADDRESS,
+ ATTR_SERVER_PORT,
+ ATTR_EXCEPTION_MESSAGE,
} from '@opentelemetry/semantic-conventions';
import { RedisResponseCustomAttributeFunction } from '../../src/types';
import { hrTimeToMilliseconds, suppressTracing } from '@opentelemetry/core';
+import { SemconvStability } from '@opentelemetry/instrumentation';
-describe('redis v4', () => {
+describe('redis v4-v5', () => {
before(function () {
// needs to be "function" to have MochaContext "this" context
if (!shouldTest) {
@@ -88,19 +96,33 @@ describe('redis v4', () => {
assert.ok(setSpan);
assert.strictEqual(setSpan?.kind, SpanKind.CLIENT);
assert.strictEqual(setSpan?.name, 'redis-SET');
+ assert.strictEqual(setSpan?.attributes[ATTR_DB_SYSTEM_NAME], 'redis');
assert.strictEqual(setSpan?.attributes[SEMATTRS_DB_SYSTEM], 'redis');
assert.strictEqual(
setSpan?.attributes[SEMATTRS_DB_STATEMENT],
'SET key [1 other arguments]'
);
+ assert.strictEqual(
+ setSpan?.attributes[ATTR_DB_QUERY_TEXT],
+ 'SET key [1 other arguments]'
+ );
assert.strictEqual(
setSpan?.attributes[SEMATTRS_NET_PEER_NAME],
redisTestConfig.host
);
+ assert.strictEqual(
+ setSpan?.attributes[ATTR_SERVER_ADDRESS],
+ redisTestConfig.host
+ );
assert.strictEqual(
setSpan?.attributes[SEMATTRS_NET_PEER_PORT],
redisTestConfig.port
);
+ assert.strictEqual(
+ setSpan?.attributes[ATTR_SERVER_PORT],
+ redisTestConfig.port
+ );
+ assert.strictEqual(setSpan?.attributes[ATTR_DB_OPERATION_NAME], 'SET');
assert.strictEqual(
setSpan?.attributes[SEMATTRS_DB_CONNECTION_STRING],
redisTestUrl
@@ -110,16 +132,26 @@ describe('redis v4', () => {
assert.ok(getSpan);
assert.strictEqual(getSpan?.kind, SpanKind.CLIENT);
assert.strictEqual(getSpan?.name, 'redis-GET');
+ assert.strictEqual(getSpan?.attributes[ATTR_DB_SYSTEM_NAME], 'redis');
+ assert.strictEqual(getSpan?.attributes[ATTR_DB_QUERY_TEXT], 'GET key');
assert.strictEqual(getSpan?.attributes[SEMATTRS_DB_SYSTEM], 'redis');
assert.strictEqual(getSpan?.attributes[SEMATTRS_DB_STATEMENT], 'GET key');
assert.strictEqual(
getSpan?.attributes[SEMATTRS_NET_PEER_NAME],
redisTestConfig.host
);
+ assert.strictEqual(
+ getSpan?.attributes[ATTR_SERVER_ADDRESS],
+ redisTestConfig.host
+ );
assert.strictEqual(
getSpan?.attributes[SEMATTRS_NET_PEER_PORT],
redisTestConfig.port
);
+ assert.strictEqual(
+ getSpan?.attributes[ATTR_SERVER_PORT],
+ redisTestConfig.port
+ );
assert.strictEqual(
getSpan?.attributes[SEMATTRS_DB_CONNECTION_STRING],
redisTestUrl
@@ -137,14 +169,27 @@ describe('redis v4', () => {
setSpan?.attributes[SEMATTRS_DB_STATEMENT],
'SET key [1 other arguments]'
);
+ assert.strictEqual(
+ setSpan?.attributes[ATTR_DB_QUERY_TEXT],
+ 'SET key [1 other arguments]'
+ );
assert.strictEqual(
setSpan?.attributes[SEMATTRS_NET_PEER_NAME],
redisTestConfig.host
);
+ assert.strictEqual(
+ setSpan?.attributes[ATTR_SERVER_ADDRESS],
+ redisTestConfig.host
+ );
assert.strictEqual(
setSpan?.attributes[SEMATTRS_NET_PEER_PORT],
redisTestConfig.port
);
+ assert.strictEqual(
+ setSpan?.attributes[ATTR_SERVER_PORT],
+ redisTestConfig.port
+ );
+ assert.strictEqual(setSpan?.attributes[ATTR_DB_OPERATION_NAME], 'SET');
});
it('command with error', async () => {
@@ -168,6 +213,10 @@ describe('redis v4', () => {
exceptions?.[0].attributes?.[SEMATTRS_EXCEPTION_MESSAGE],
'ERR value is not an integer or out of range'
);
+ assert.strictEqual(
+ exceptions?.[0].attributes?.[ATTR_EXCEPTION_MESSAGE],
+ 'ERR value is not an integer or out of range'
+ );
});
});
@@ -188,14 +237,23 @@ describe('redis v4', () => {
assert.strictEqual(span.name, 'redis-connect');
assert.strictEqual(span.attributes[SEMATTRS_DB_SYSTEM], 'redis');
+ assert.strictEqual(span.attributes[ATTR_DB_SYSTEM_NAME], 'redis');
assert.strictEqual(
span.attributes[SEMATTRS_NET_PEER_NAME],
redisTestConfig.host
);
+ assert.strictEqual(
+ span.attributes[ATTR_SERVER_ADDRESS],
+ redisTestConfig.host
+ );
assert.strictEqual(
span.attributes[SEMATTRS_NET_PEER_PORT],
redisTestConfig.port
);
+ assert.strictEqual(
+ span.attributes[ATTR_SERVER_PORT],
+ redisTestConfig.port
+ );
assert.strictEqual(
span.attributes[SEMATTRS_DB_CONNECTION_STRING],
redisTestUrl
@@ -312,6 +370,46 @@ describe('redis v4', () => {
});
});
+ describe('Redis client connect with malformed URL', () => {
+ it('malformed URL should trigger diag error and reject connection', async () => {
+ instrumentation.setConfig({ semconvStability: SemconvStability.OLD });
+
+ const diagErrors: any[] = [];
+ diag.setLogger(
+ {
+ verbose() {},
+ debug() {},
+ info() {},
+ warn() {},
+ error(...args) {
+ diagErrors.push(args);
+ },
+ },
+ DiagLogLevel.ALL
+ );
+
+ const client = createClient({
+ socket: { host: 'localhost', port: 9999 },
+ });
+
+ const opts = (client as any).options;
+ if (opts) opts.url = '://malformed-url-no-protocol';
+
+ await assert.rejects(() => client.connect());
+
+ try {
+ await client.disconnect();
+ } catch {}
+
+ assert.ok(diagErrors.length > 0, 'Expected at least one diag error');
+ const found = diagErrors.some(args =>
+ args.includes('failed to sanitize redis connection url')
+ );
+
+ assert.ok(found, 'Expected sanitize URL diag error');
+ });
+ });
+
describe('multi (transactions) commands', () => {
it('multi commands', async () => {
await client.set('another-key', 'another-value');
@@ -334,18 +432,34 @@ describe('redis v4', () => {
multiSetSpan.attributes[SEMATTRS_DB_STATEMENT],
'SET key [1 other arguments]'
);
+ assert.strictEqual(
+ multiSetSpan.attributes[ATTR_DB_QUERY_TEXT],
+ 'SET key [1 other arguments]'
+ );
assert.strictEqual(
multiSetSpan?.attributes[SEMATTRS_NET_PEER_NAME],
redisTestConfig.host
);
+ assert.strictEqual(
+ multiSetSpan?.attributes[ATTR_SERVER_ADDRESS],
+ redisTestConfig.host
+ );
assert.strictEqual(
multiSetSpan?.attributes[SEMATTRS_NET_PEER_PORT],
redisTestConfig.port
);
+ assert.strictEqual(
+ multiSetSpan?.attributes[ATTR_SERVER_PORT],
+ redisTestConfig.port
+ );
assert.strictEqual(
multiSetSpan?.attributes[SEMATTRS_DB_CONNECTION_STRING],
redisTestUrl
);
+ assert.strictEqual(
+ multiSetSpan?.attributes[ATTR_DB_OPERATION_NAME],
+ 'SET'
+ );
assert.ok(multiGetSpan);
assert.strictEqual(multiGetSpan.name, 'redis-GET');
@@ -353,18 +467,34 @@ describe('redis v4', () => {
multiGetSpan.attributes[SEMATTRS_DB_STATEMENT],
'GET another-key'
);
+ assert.strictEqual(
+ multiGetSpan.attributes[ATTR_DB_QUERY_TEXT],
+ 'GET another-key'
+ );
assert.strictEqual(
multiGetSpan?.attributes[SEMATTRS_NET_PEER_NAME],
redisTestConfig.host
);
+ assert.strictEqual(
+ multiGetSpan?.attributes[ATTR_SERVER_ADDRESS],
+ redisTestConfig.host
+ );
assert.strictEqual(
multiGetSpan?.attributes[SEMATTRS_NET_PEER_PORT],
redisTestConfig.port
);
+ assert.strictEqual(
+ multiGetSpan?.attributes[ATTR_SERVER_PORT],
+ redisTestConfig.port
+ );
assert.strictEqual(
multiGetSpan?.attributes[SEMATTRS_DB_CONNECTION_STRING],
redisTestUrl
);
+ assert.strictEqual(
+ multiGetSpan?.attributes[ATTR_DB_OPERATION_NAME],
+ 'GET'
+ );
});
it('multi command with generic command', async () => {
@@ -380,18 +510,34 @@ describe('redis v4', () => {
multiSetSpan.attributes[SEMATTRS_DB_STATEMENT],
'SET key [1 other arguments]'
);
+ assert.strictEqual(
+ multiSetSpan.attributes[ATTR_DB_QUERY_TEXT],
+ 'SET key [1 other arguments]'
+ );
assert.strictEqual(
multiSetSpan?.attributes[SEMATTRS_NET_PEER_NAME],
redisTestConfig.host
);
+ assert.strictEqual(
+ multiSetSpan?.attributes[ATTR_SERVER_ADDRESS],
+ redisTestConfig.host
+ );
assert.strictEqual(
multiSetSpan?.attributes[SEMATTRS_NET_PEER_PORT],
redisTestConfig.port
);
+ assert.strictEqual(
+ multiSetSpan?.attributes[ATTR_SERVER_PORT],
+ redisTestConfig.port
+ );
assert.strictEqual(
multiSetSpan?.attributes[SEMATTRS_DB_CONNECTION_STRING],
redisTestUrl
);
+ assert.strictEqual(
+ multiSetSpan?.attributes[ATTR_DB_OPERATION_NAME],
+ 'SET'
+ );
});
it('multi command with error', async () => {
@@ -444,7 +590,7 @@ describe('redis v4', () => {
it('duration covers create until server response', async () => {
await client.set('another-key', 'another-value');
const multiClient = client.multi();
- let commands = multiClient.set('key', 'value');
+ let commands: any = multiClient.set('key', 'value');
// wait 10 ms before adding next command
// simulate long operation
await new Promise(resolve => setTimeout(resolve, 10));
@@ -533,6 +679,10 @@ describe('redis v4', () => {
span.attributes[SEMATTRS_DB_STATEMENT],
'SET key value'
);
+ assert.strictEqual(
+ span.attributes[ATTR_DB_QUERY_TEXT],
+ 'SET key value'
+ );
});
it('dbStatementSerializer throws', async () => {
@@ -545,6 +695,7 @@ describe('redis v4', () => {
const [span] = getTestSpans();
assert.ok(span);
assert.ok(!(SEMATTRS_DB_STATEMENT in span.attributes));
+ assert.ok(!(ATTR_DB_QUERY_TEXT in span.attributes));
});
});
@@ -606,4 +757,80 @@ describe('redis v4', () => {
});
});
});
+
+ describe('semconv stability configuration', () => {
+ async function getSpan(client: RedisClientType) {
+ await client.set('key', 'value');
+ const spans = getTestSpans();
+ return spans.find(s => s.name.includes('SET'));
+ }
+
+ it('should emit only old attributes when semconvStability is OLD', async () => {
+ instrumentation.setConfig({ semconvStability: SemconvStability.OLD });
+ const setSpan = await getSpan(client);
+ assert.ok(setSpan);
+
+ assert.strictEqual(setSpan.attributes[SEMATTRS_DB_SYSTEM], 'redis');
+ assert.strictEqual(
+ setSpan.attributes[SEMATTRS_DB_STATEMENT],
+ 'SET key [1 other arguments]'
+ );
+ assert.strictEqual(
+ setSpan.attributes[SEMATTRS_NET_PEER_NAME],
+ redisTestConfig.host
+ );
+
+ assert.ok(!(ATTR_DB_SYSTEM_NAME in setSpan.attributes));
+ assert.ok(!(ATTR_DB_QUERY_TEXT in setSpan.attributes));
+ assert.ok(!(ATTR_SERVER_ADDRESS in setSpan.attributes));
+ });
+
+ it('should emit only new attributes when semconvStability is STABLE', async () => {
+ instrumentation.setConfig({ semconvStability: SemconvStability.STABLE });
+ const setSpan = await getSpan(client);
+ assert.ok(setSpan);
+
+ assert.strictEqual(setSpan.attributes[ATTR_DB_SYSTEM_NAME], 'redis');
+ assert.strictEqual(
+ setSpan.attributes[ATTR_DB_QUERY_TEXT],
+ 'SET key [1 other arguments]'
+ );
+ assert.strictEqual(
+ setSpan.attributes[ATTR_SERVER_ADDRESS],
+ redisTestConfig.host
+ );
+
+ assert.ok(!(SEMATTRS_DB_SYSTEM in setSpan.attributes));
+ assert.ok(!(SEMATTRS_DB_STATEMENT in setSpan.attributes));
+ assert.ok(!(SEMATTRS_NET_PEER_NAME in setSpan.attributes));
+ });
+
+ it('should emit both old and new attributes when semconvStability is DUPLICATE', async () => {
+ instrumentation.setConfig({
+ semconvStability: SemconvStability.DUPLICATE,
+ });
+ const setSpan = await getSpan(client);
+ assert.ok(setSpan);
+
+ assert.strictEqual(setSpan.attributes[SEMATTRS_DB_SYSTEM], 'redis');
+ assert.strictEqual(
+ setSpan.attributes[SEMATTRS_DB_STATEMENT],
+ 'SET key [1 other arguments]'
+ );
+ assert.strictEqual(
+ setSpan.attributes[SEMATTRS_NET_PEER_NAME],
+ redisTestConfig.host
+ );
+
+ assert.strictEqual(setSpan.attributes[ATTR_DB_SYSTEM_NAME], 'redis');
+ assert.strictEqual(
+ setSpan.attributes[ATTR_DB_QUERY_TEXT],
+ 'SET key [1 other arguments]'
+ );
+ assert.strictEqual(
+ setSpan.attributes[ATTR_SERVER_ADDRESS],
+ redisTestConfig.host
+ );
+ });
+ });
});
diff --git a/packages/instrumentation-redis/test/v4/utils.ts b/packages/instrumentation-redis/test/v4-v5/utils.ts
similarity index 100%
rename from packages/instrumentation-redis/test/v4/utils.ts
rename to packages/instrumentation-redis/test/v4-v5/utils.ts
diff --git a/packages/instrumentation-redis/tsconfig.json b/packages/instrumentation-redis/tsconfig.json
index 4078877ce6..1d2135f1cc 100644
--- a/packages/instrumentation-redis/tsconfig.json
+++ b/packages/instrumentation-redis/tsconfig.json
@@ -2,7 +2,12 @@
"extends": "../../tsconfig.base",
"compilerOptions": {
"rootDir": ".",
- "outDir": "build"
+ "outDir": "build",
+ /* Work-around for the node-redis type-checking bug
+ (see https://github.com/redis/node-redis/issues/3009). */
+ "esModuleInterop": true,
+ "allowSyntheticDefaultImports": true,
+ "skipLibCheck": true
},
"include": [
"src/**/*.ts",