Skip to content

Commit 825441a

Browse files
deejay1trentm
andauthored
feat(instrumentation-knex): Use newer semantic conventions (#2671)
Co-authored-by: Trent Mick <[email protected]>
1 parent 55cc256 commit 825441a

File tree

6 files changed

+185
-46
lines changed

6 files changed

+185
-46
lines changed

package-lock.json

Lines changed: 72 additions & 10 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

plugins/node/opentelemetry-instrumentation-knex/README.md

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -54,21 +54,38 @@ registerInstrumentations({
5454

5555
## Semantic Conventions
5656

57-
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)
57+
This package uses `@opentelemetry/semantic-conventions` version `1.33+`, which implements Semantic Convention [Version 1.7.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/semantic_conventions/README.md)
58+
59+
This package is capable of emitting both Semantic Convention [Version 1.7.0](https://github.com/open-telemetry/opentelemetry-specification/blob/v1.7.0/semantic_conventions/README.md) and [Version 1.33.0](https://github.com/open-telemetry/semantic-conventions/blob/v1.33.0/docs/database/database-spans.md)
60+
It is controlled using the environment variable `OTEL_SEMCONV_STABILITY_OPT_IN`, which is a comma separated list of values.
61+
The values `database` and `database/dup` control this instrumentation.
62+
See details for the behavior of each of these values below.
63+
If neither `database` or `database/dup` is included in `OTEL_SEMCONV_STABILITY_OPT_IN`, the old experimental semantic conventions will be used by default.
64+
65+
### Upgrading Semantic Conventions
66+
67+
When upgrading to the new semantic conventions, it is recommended to do so in the following order:
68+
69+
1. Upgrade `@opentelemetry/instrumentation-knex` to the latest version
70+
2. Set `OTEL_SEMCONV_STABILITY_OPT_IN=database/dup` to emit both old and new semantic conventions
71+
3. Modify alerts, dashboards, metrics, and other processes to expect the new semantic conventions
72+
4. Set `OTEL_SEMCONV_STABILITY_OPT_IN=database` to emit only the new semantic conventions
73+
74+
This will cause both the old and new semantic conventions to be emitted during the transition period.
5875

5976
Attributes collected:
6077

61-
| Attribute | Short Description |
62-
| ----------------------- | ------------------------------------------------------------------------------ |
63-
| `db.name` | This attribute is used to report the name of the database being accessed. |
64-
| `db.operation` | The name of the operation being executed. |
65-
| `db.sql.table` | The name of the primary table that the operation is acting upon. |
66-
| `db.statement` | The database statement being executed. |
67-
| `db.system` | An identifier for the database management system (DBMS) product being used. |
68-
| `db.user` | Username for accessing the database. |
69-
| `net.peer.name` | Remote hostname or similar. |
70-
| `net.peer.port` | Remote port number. |
71-
| `net.transport` | Transport protocol used. |
78+
| v1.7.0 semconv | v1.23.0 semconv | Short Description |
79+
|-----------------|----------------------|-----------------------------------------------------------------------------|
80+
| `db.name` | `db.namespace` | This attribute is used to report the name of the database being accessed. |
81+
| `db.operation` | `db.operation.name` | The name of the operation being executed. |
82+
| `db.sql.table` | `db.collection.name` | The name of the primary table that the operation is acting upon. |
83+
| `db.statement` | `db.query.text` | The database statement being executed. |
84+
| `db.system` | `db.system.name` | An identifier for the database management system (DBMS) product being used. |
85+
| `db.user` | (not included) | Username for accessing the database. |
86+
| `net.peer.name` | `server.address` | Remote hostname or similar. |
87+
| `net.peer.port` | `server.port` | Remote port number. |
88+
| `net.transport` | (not included) | Transport protocol used. |
7289

7390
## Useful links
7491

plugins/node/opentelemetry-instrumentation-knex/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@
5656
"typescript": "5.0.4"
5757
},
5858
"dependencies": {
59-
"@opentelemetry/instrumentation": "^0.201.0",
60-
"@opentelemetry/semantic-conventions": "^1.27.0"
59+
"@opentelemetry/instrumentation": "^0.201.1",
60+
"@opentelemetry/semantic-conventions": "^1.33.1"
6161
},
6262
"homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/plugins/node/opentelemetry-instrumentation-knex#readme"
6363
}

plugins/node/opentelemetry-instrumentation-knex/src/instrumentation.ts

Lines changed: 52 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,19 @@ import {
2323
InstrumentationNodeModuleDefinition,
2424
InstrumentationNodeModuleFile,
2525
isWrapped,
26+
SemconvStability,
27+
semconvStabilityFromStr,
2628
} from '@opentelemetry/instrumentation';
29+
import * as utils from './utils';
30+
import { KnexInstrumentationConfig } from './types';
2731
import {
32+
ATTR_DB_COLLECTION_NAME,
33+
ATTR_DB_NAMESPACE,
34+
ATTR_DB_OPERATION_NAME,
35+
ATTR_DB_QUERY_TEXT,
36+
ATTR_DB_SYSTEM_NAME,
37+
ATTR_SERVER_ADDRESS,
38+
ATTR_SERVER_PORT,
2839
SEMATTRS_DB_NAME,
2940
SEMATTRS_DB_OPERATION,
3041
SEMATTRS_DB_SQL_TABLE,
@@ -35,8 +46,6 @@ import {
3546
SEMATTRS_NET_PEER_PORT,
3647
SEMATTRS_NET_TRANSPORT,
3748
} from '@opentelemetry/semantic-conventions';
38-
import * as utils from './utils';
39-
import { KnexInstrumentationConfig } from './types';
4049

4150
const contextSymbol = Symbol('opentelemetry.instrumentation-knex.context');
4251
const DEFAULT_CONFIG: KnexInstrumentationConfig = {
@@ -45,8 +54,15 @@ const DEFAULT_CONFIG: KnexInstrumentationConfig = {
4554
};
4655

4756
export class KnexInstrumentation extends InstrumentationBase<KnexInstrumentationConfig> {
57+
private _semconvStability: SemconvStability;
58+
4859
constructor(config: KnexInstrumentationConfig = {}) {
4960
super(PACKAGE_NAME, PACKAGE_VERSION, { ...DEFAULT_CONFIG, ...config });
61+
62+
this._semconvStability = semconvStabilityFromStr(
63+
'database',
64+
process.env.OTEL_SEMCONV_STABILITY_OPT_IN
65+
);
5066
}
5167

5268
override setConfig(config: KnexInstrumentationConfig = {}) {
@@ -122,6 +138,7 @@ export class KnexInstrumentation extends InstrumentationBase<KnexInstrumentation
122138

123139
private createQueryWrapper(moduleVersion?: string) {
124140
const instrumentation = this;
141+
125142
return function wrapQuery(original: (...args: any[]) => any) {
126143
return function wrapped_logging_method(this: any, query: any) {
127144
const config = this.client.config;
@@ -134,24 +151,43 @@ export class KnexInstrumentation extends InstrumentationBase<KnexInstrumentation
134151
config?.connection?.filename || config?.connection?.database;
135152
const { maxQueryLength } = instrumentation.getConfig();
136153

137-
const attributes: api.SpanAttributes = {
154+
const attributes: api.Attributes = {
138155
'knex.version': moduleVersion,
139-
[SEMATTRS_DB_SYSTEM]: utils.mapSystem(config.client),
140-
[SEMATTRS_DB_SQL_TABLE]: table,
141-
[SEMATTRS_DB_OPERATION]: operation,
142-
[SEMATTRS_DB_USER]: config?.connection?.user,
143-
[SEMATTRS_DB_NAME]: name,
144-
[SEMATTRS_NET_PEER_NAME]: config?.connection?.host,
145-
[SEMATTRS_NET_PEER_PORT]: config?.connection?.port,
146-
[SEMATTRS_NET_TRANSPORT]:
147-
config?.connection?.filename === ':memory:' ? 'inproc' : undefined,
148156
};
157+
const transport =
158+
config?.connection?.filename === ':memory:' ? 'inproc' : undefined;
159+
160+
if (instrumentation._semconvStability & SemconvStability.OLD) {
161+
Object.assign(attributes, {
162+
[SEMATTRS_DB_SYSTEM]: utils.mapSystem(config.client),
163+
[SEMATTRS_DB_SQL_TABLE]: table,
164+
[SEMATTRS_DB_OPERATION]: operation,
165+
[SEMATTRS_DB_USER]: config?.connection?.user,
166+
[SEMATTRS_DB_NAME]: name,
167+
[SEMATTRS_NET_PEER_NAME]: config?.connection?.host,
168+
[SEMATTRS_NET_PEER_PORT]: config?.connection?.port,
169+
[SEMATTRS_NET_TRANSPORT]: transport,
170+
});
171+
}
172+
if (instrumentation._semconvStability & SemconvStability.STABLE) {
173+
Object.assign(attributes, {
174+
[ATTR_DB_SYSTEM_NAME]: utils.mapSystem(config.client),
175+
[ATTR_DB_COLLECTION_NAME]: table,
176+
[ATTR_DB_OPERATION_NAME]: operation,
177+
[ATTR_DB_NAMESPACE]: name,
178+
[ATTR_SERVER_ADDRESS]: config?.connection?.host,
179+
[ATTR_SERVER_PORT]: config?.connection?.port,
180+
});
181+
}
149182
if (maxQueryLength) {
150183
// filters both undefined and 0
151-
attributes[SEMATTRS_DB_STATEMENT] = utils.limitLength(
152-
query?.sql,
153-
maxQueryLength
154-
);
184+
const queryText = utils.limitLength(query?.sql, maxQueryLength);
185+
if (instrumentation._semconvStability & SemconvStability.STABLE) {
186+
attributes[ATTR_DB_QUERY_TEXT] = queryText;
187+
}
188+
if (instrumentation._semconvStability & SemconvStability.OLD) {
189+
attributes[SEMATTRS_DB_STATEMENT] = queryText;
190+
}
155191
}
156192

157193
const parentContext =
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
/*
18+
* This file contains a copy of unstable semantic convention definitions
19+
* used by this package.
20+
* @see https://github.com/open-telemetry/opentelemetry-js/tree/main/semantic-conventions#unstable-semconv
21+
*/
22+
23+
/**
24+
* Enum value "sqlite" for attribute {@link ATTR_DB_SYSTEM_NAME}.
25+
*/
26+
export const DB_SYSTEM_NAME_VALUE_SQLITE = 'sqlite' as const;

plugins/node/opentelemetry-instrumentation-knex/src/utils.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,8 @@
1515
*/
1616

1717
import { Exception } from '@opentelemetry/api';
18-
import {
19-
DBSYSTEMVALUES_SQLITE,
20-
DBSYSTEMVALUES_POSTGRESQL,
21-
} from '@opentelemetry/semantic-conventions';
18+
import { DB_SYSTEM_NAME_VALUE_POSTGRESQL } from '@opentelemetry/semantic-conventions';
19+
import { DB_SYSTEM_NAME_VALUE_SQLITE } from './semconv';
2220

2321
type KnexError = Error & {
2422
code?: string;
@@ -57,8 +55,8 @@ export function otelExceptionFromKnexError(
5755
}
5856

5957
const systemMap = new Map([
60-
['sqlite3', DBSYSTEMVALUES_SQLITE],
61-
['pg', DBSYSTEMVALUES_POSTGRESQL],
58+
['sqlite3', DB_SYSTEM_NAME_VALUE_SQLITE],
59+
['pg', DB_SYSTEM_NAME_VALUE_POSTGRESQL],
6260
]);
6361

6462
export const mapSystem = (knexSystem: string) => {

0 commit comments

Comments
 (0)