@opentelemetry/instrumentation-tedious 0.27.0 → 0.29.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +20 -10
- package/build/src/instrumentation.d.ts +3 -0
- package/build/src/instrumentation.js +45 -11
- package/build/src/instrumentation.js.map +1 -1
- package/build/src/version.d.ts +1 -1
- package/build/src/version.js +1 -1
- package/build/src/version.js.map +1 -1
- package/package.json +6 -13
package/README.md
CHANGED
|
@@ -42,19 +42,29 @@ registerInstrumentations({
|
|
|
42
42
|
|
|
43
43
|
## Semantic Conventions
|
|
44
44
|
|
|
45
|
-
This
|
|
45
|
+
This instrumentation implements Semantic Conventions (semconv) v1.7.0. Since then, networking (in semconv v1.23.1) and database (in semconv v1.33.0) semantic conventions were stabilized. As of `@opentelemetry/instrumentation-tedious@0.28.0` support has been added for migrating to the stable semantic conventions using the `OTEL_SEMCONV_STABILITY_OPT_IN` environment variable as follows:
|
|
46
|
+
|
|
47
|
+
1. Upgrade to the latest version of this instrumentation package.
|
|
48
|
+
2. Set `OTEL_SEMCONV_STABILITY_OPT_IN=http/dup,database/dup` to emit both old and stable semantic conventions. (The `http` token is used to control the `net.*` attributes, the `database` token to control to `db.*` attributes.)
|
|
49
|
+
3. Modify alerts, dashboards, metrics, and other processes in your Observability system to use the stable semantic conventions.
|
|
50
|
+
4. Set `OTEL_SEMCONV_STABILITY_OPT_IN=http,database` to emit only the stable semantic conventions.
|
|
51
|
+
|
|
52
|
+
By default, if `OTEL_SEMCONV_STABILITY_OPT_IN` includes neither of the above tokens, the old v1.7.0 semconv is used.
|
|
53
|
+
The intent is to provide an approximate 6 month time window for users of this instrumentation to migrate to the new database and networking semconv, after which a new minor version will use the new semconv by default and drop support for the old semconv.
|
|
54
|
+
See [the HTTP migration guide](https://opentelemetry.io/docs/specs/semconv/non-normative/http-migration/) and the [database migration guide](https://opentelemetry.io/docs/specs/semconv/non-normative/db-migration/) for details.
|
|
46
55
|
|
|
47
56
|
Attributes collected:
|
|
48
57
|
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
| `db.
|
|
52
|
-
| `db.
|
|
53
|
-
| `db.
|
|
54
|
-
| `db.
|
|
55
|
-
| `db.
|
|
56
|
-
| `
|
|
57
|
-
| `net.peer.
|
|
58
|
+
| Old semconv | Stable semconv | Description |
|
|
59
|
+
| --------------- | -------------------- | ---------------------------------- |
|
|
60
|
+
| `db.system` | `db.system.name` | 'mssql' (old), 'microsoft.sql_server' (stable) |
|
|
61
|
+
| `db.statement` | `db.query.text` | The database query being executed. |
|
|
62
|
+
| `db.user` | Removed | Username for accessing the database. |
|
|
63
|
+
| `db.name` | Removed | Integrated into new `db.namespace`. |
|
|
64
|
+
| (not included) | `db.namespace` | The database associated with the connection, qualified by the instance name. |
|
|
65
|
+
| `db.sql.table` | `db.collection.name` | The name of a collection (table, container) within the database. |
|
|
66
|
+
| `net.peer.name` | `server.address` | Remote hostname or similar. |
|
|
67
|
+
| `net.peer.port` | `server.port` | Remote port number. |
|
|
58
68
|
|
|
59
69
|
### Trace Context Propagation
|
|
60
70
|
|
|
@@ -3,7 +3,10 @@ import { TediousInstrumentationConfig } from './types';
|
|
|
3
3
|
export declare const INJECTED_CTX: unique symbol;
|
|
4
4
|
export declare class TediousInstrumentation extends InstrumentationBase<TediousInstrumentationConfig> {
|
|
5
5
|
static readonly COMPONENT = "tedious";
|
|
6
|
+
private _netSemconvStability;
|
|
7
|
+
private _dbSemconvStability;
|
|
6
8
|
constructor(config?: TediousInstrumentationConfig);
|
|
9
|
+
private _setSemconvStabilityFromEnv;
|
|
7
10
|
protected init(): InstrumentationNodeModuleDefinition[];
|
|
8
11
|
private _patchConnect;
|
|
9
12
|
private _buildTraceparent;
|
|
@@ -19,6 +19,7 @@ exports.TediousInstrumentation = exports.INJECTED_CTX = void 0;
|
|
|
19
19
|
const api = require("@opentelemetry/api");
|
|
20
20
|
const events_1 = require("events");
|
|
21
21
|
const instrumentation_1 = require("@opentelemetry/instrumentation");
|
|
22
|
+
const semantic_conventions_1 = require("@opentelemetry/semantic-conventions");
|
|
22
23
|
const semconv_1 = require("./semconv");
|
|
23
24
|
const utils_1 = require("./utils");
|
|
24
25
|
/** @knipignore */
|
|
@@ -41,8 +42,16 @@ function setDatabase(databaseName) {
|
|
|
41
42
|
}
|
|
42
43
|
class TediousInstrumentation extends instrumentation_1.InstrumentationBase {
|
|
43
44
|
static COMPONENT = 'tedious';
|
|
45
|
+
_netSemconvStability;
|
|
46
|
+
_dbSemconvStability;
|
|
44
47
|
constructor(config = {}) {
|
|
45
48
|
super(version_1.PACKAGE_NAME, version_1.PACKAGE_VERSION, config);
|
|
49
|
+
this._setSemconvStabilityFromEnv();
|
|
50
|
+
}
|
|
51
|
+
// Used for testing.
|
|
52
|
+
_setSemconvStabilityFromEnv() {
|
|
53
|
+
this._netSemconvStability = (0, instrumentation_1.semconvStabilityFromStr)('http', process.env.OTEL_SEMCONV_STABILITY_OPT_IN);
|
|
54
|
+
this._dbSemconvStability = (0, instrumentation_1.semconvStabilityFromStr)('database', process.env.OTEL_SEMCONV_STABILITY_OPT_IN);
|
|
46
55
|
}
|
|
47
56
|
init() {
|
|
48
57
|
return [
|
|
@@ -138,19 +147,43 @@ class TediousInstrumentation extends instrumentation_1.InstrumentationBase {
|
|
|
138
147
|
}
|
|
139
148
|
return request.sqlTextOrProcedure;
|
|
140
149
|
})(request);
|
|
150
|
+
const attributes = {};
|
|
151
|
+
if (thisPlugin._dbSemconvStability & instrumentation_1.SemconvStability.OLD) {
|
|
152
|
+
attributes[semconv_1.ATTR_DB_SYSTEM] = semconv_1.DB_SYSTEM_VALUE_MSSQL;
|
|
153
|
+
attributes[semconv_1.ATTR_DB_NAME] = databaseName;
|
|
154
|
+
// >=4 uses `authentication` object; older versions just userName and password pair
|
|
155
|
+
attributes[semconv_1.ATTR_DB_USER] =
|
|
156
|
+
this.config?.userName ??
|
|
157
|
+
this.config?.authentication?.options?.userName;
|
|
158
|
+
attributes[semconv_1.ATTR_DB_STATEMENT] = sql;
|
|
159
|
+
attributes[semconv_1.ATTR_DB_SQL_TABLE] = request.table;
|
|
160
|
+
}
|
|
161
|
+
if (thisPlugin._dbSemconvStability & instrumentation_1.SemconvStability.STABLE) {
|
|
162
|
+
// The OTel spec for "db.namespace" discusses handling for connection
|
|
163
|
+
// to MSSQL "named instances". This isn't currently supported.
|
|
164
|
+
// https://opentelemetry.io/docs/specs/semconv/database/sql-server/#:~:text=%5B1%5D%20db%2Enamespace
|
|
165
|
+
attributes[semantic_conventions_1.ATTR_DB_NAMESPACE] = databaseName;
|
|
166
|
+
attributes[semantic_conventions_1.ATTR_DB_SYSTEM_NAME] =
|
|
167
|
+
semantic_conventions_1.DB_SYSTEM_NAME_VALUE_MICROSOFT_SQL_SERVER;
|
|
168
|
+
attributes[semantic_conventions_1.ATTR_DB_QUERY_TEXT] = sql;
|
|
169
|
+
attributes[semantic_conventions_1.ATTR_DB_COLLECTION_NAME] = request.table;
|
|
170
|
+
// See https://opentelemetry.io/docs/specs/semconv/database/sql-server/#spans
|
|
171
|
+
// TODO(3290): can `db.response.status_code` be added?
|
|
172
|
+
// TODO(3290): is `operation` correct for `db.operation.name`
|
|
173
|
+
// TODO(3290): can `db.query.summary` reliably be calculated?
|
|
174
|
+
// TODO(3290): `db.stored_procedure.name`
|
|
175
|
+
}
|
|
176
|
+
if (thisPlugin._netSemconvStability & instrumentation_1.SemconvStability.OLD) {
|
|
177
|
+
attributes[semconv_1.ATTR_NET_PEER_NAME] = this.config?.server;
|
|
178
|
+
attributes[semconv_1.ATTR_NET_PEER_PORT] = this.config?.options?.port;
|
|
179
|
+
}
|
|
180
|
+
if (thisPlugin._netSemconvStability & instrumentation_1.SemconvStability.STABLE) {
|
|
181
|
+
attributes[semantic_conventions_1.ATTR_SERVER_ADDRESS] = this.config?.server;
|
|
182
|
+
attributes[semantic_conventions_1.ATTR_SERVER_PORT] = this.config?.options?.port;
|
|
183
|
+
}
|
|
141
184
|
const span = thisPlugin.tracer.startSpan((0, utils_1.getSpanName)(operation, databaseName, sql, request.table), {
|
|
142
185
|
kind: api.SpanKind.CLIENT,
|
|
143
|
-
attributes
|
|
144
|
-
[semconv_1.ATTR_DB_SYSTEM]: semconv_1.DB_SYSTEM_VALUE_MSSQL,
|
|
145
|
-
[semconv_1.ATTR_DB_NAME]: databaseName,
|
|
146
|
-
[semconv_1.ATTR_NET_PEER_PORT]: this.config?.options?.port,
|
|
147
|
-
[semconv_1.ATTR_NET_PEER_NAME]: this.config?.server,
|
|
148
|
-
// >=4 uses `authentication` object, older versions just userName and password pair
|
|
149
|
-
[semconv_1.ATTR_DB_USER]: this.config?.userName ??
|
|
150
|
-
this.config?.authentication?.options?.userName,
|
|
151
|
-
[semconv_1.ATTR_DB_STATEMENT]: sql,
|
|
152
|
-
[semconv_1.ATTR_DB_SQL_TABLE]: request.table,
|
|
153
|
-
},
|
|
186
|
+
attributes,
|
|
154
187
|
});
|
|
155
188
|
const endSpan = (0, utils_1.once)((err) => {
|
|
156
189
|
request.removeListener('done', incrementStatementCount);
|
|
@@ -165,6 +198,7 @@ class TediousInstrumentation extends instrumentation_1.InstrumentationBase {
|
|
|
165
198
|
code: api.SpanStatusCode.ERROR,
|
|
166
199
|
message: err.message,
|
|
167
200
|
});
|
|
201
|
+
// TODO(3290): set `error.type` attribute?
|
|
168
202
|
}
|
|
169
203
|
span.end();
|
|
170
204
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../src/instrumentation.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH,0CAA0C;AAC1C,mCAAsC;AACtC,oEAIwC;AACxC,uCASmB;AAGnB,mCAA4C;AAC5C,kBAAkB;AAClB,uCAA0D;AAE1D,MAAM,gBAAgB,GAAG,MAAM,CAC7B,wDAAwD,CACzD,CAAC;AAEW,QAAA,YAAY,GAAG,MAAM,CAChC,6DAA6D,CAC9D,CAAC;AAEF,MAAM,eAAe,GAAG;IACtB,eAAe;IACf,SAAS;IACT,cAAc;IACd,cAAc;IACd,SAAS;IACT,SAAS;CACV,CAAC;AAcF,SAAS,WAAW,CAAyB,YAAoB;IAC/D,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,gBAAgB,EAAE;QAC5C,KAAK,EAAE,YAAY;QACnB,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;AACL,CAAC;AAED,MAAa,sBAAuB,SAAQ,qCAAiD;IAC3F,MAAM,CAAU,SAAS,GAAG,SAAS,CAAC;IAEtC,YAAY,SAAuC,EAAE;QACnD,KAAK,CAAC,sBAAY,EAAE,yBAAe,EAAE,MAAM,CAAC,CAAC;IAC/C,CAAC;IAES,IAAI;QACZ,OAAO;YACL,IAAI,qDAAmC,CACrC,sBAAsB,CAAC,SAAS,EAChC,CAAC,cAAc,CAAC,EAChB,CAAC,aAA6B,EAAE,EAAE;gBAChC,MAAM,mBAAmB,GAAQ,aAAa,CAAC,UAAU,CAAC,SAAS,CAAC;gBACpE,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE;oBACpC,IAAI,IAAA,2BAAS,EAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC,EAAE;wBAC1C,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;qBAC3C;oBACD,IAAI,CAAC,KAAK,CACR,mBAAmB,EACnB,MAAM,EACN,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,aAAa,CAAQ,CAC/C,CAAC;iBACH;gBAED,IAAI,IAAA,2BAAS,EAAC,mBAAmB,CAAC,OAAO,CAAC,EAAE;oBAC1C,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;iBAC9C;gBACD,IAAI,CAAC,KAAK,CAAC,mBAAmB,EAAE,SAAS,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;gBAE/D,OAAO,aAAa,CAAC;YACvB,CAAC,EACD,CAAC,aAA6B,EAAE,EAAE;gBAChC,IAAI,aAAa,KAAK,SAAS;oBAAE,OAAO;gBACxC,MAAM,mBAAmB,GAAQ,aAAa,CAAC,UAAU,CAAC,SAAS,CAAC;gBACpE,KAAK,MAAM,MAAM,IAAI,eAAe,EAAE;oBACpC,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,MAAM,CAAC,CAAC;iBAC3C;gBACD,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,SAAS,CAAC,CAAC;YAC/C,CAAC,CACF;SACF,CAAC;IACJ,CAAC;IAEO,aAAa,CAAC,QAAyB;QAC7C,OAAO,SAAS,cAAc;YAC5B,WAAW,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,QAAQ,CAAC,CAAC;YAEvD,uDAAuD;YACvD,IAAI,CAAC,cAAc,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YACnD,IAAI,CAAC,EAAE,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YAEvC,IAAI,CAAC,IAAI,CAAC,KAAK,EAAE,GAAG,EAAE;gBACpB,IAAI,CAAC,cAAc,CAAC,gBAAgB,EAAE,WAAW,CAAC,CAAC;YACrD,CAAC,CAAC,CAAC;YACH,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,SAA6B,CAAC,CAAC;QAC7D,CAAC,CAAC;IACJ,CAAC;IAEO,iBAAiB,CAAC,IAAc;QACtC,MAAM,EAAE,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC;QAC9B,OAAO,MAAM,EAAE,CAAC,OAAO,IAAI,EAAE,CAAC,MAAM,KAAK,MAAM,CAAC,EAAE,CAAC,UAAU,IAAI,GAAG,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,CAAC;IACvG,CAAC;IAED;;;OAGG;IACK,kBAAkB,CACxB,UAAe,EACf,aAA6B,EAC7B,WAAmB;QAEnB,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;YAC3B,IAAI;gBACF,MAAM,GAAG,GAAG,6CAA6C,CAAC;gBAC1D,MAAM,GAAG,GAAG,IAAI,aAAa,CAAC,OAAO,CAAC,GAAG,EAAE,CAAC,IAAS,EAAE,EAAE;oBACvD,OAAO,EAAE,CAAC;gBACZ,CAAC,CAAC,CAAC;gBACH,MAAM,CAAC,cAAc,CAAC,GAAG,EAAE,oBAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC1D,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;gBAC7C,GAAG,CAAC,YAAY,CACd,2BAA2B,EAC1B,aAAqB,CAAC,KAAK,CAAC,SAAS,EACtC,GAAG,EACH,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,CACvB,CAAC;gBAEF,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;aACzB;YAAC,MAAM;gBACN,OAAO,EAAE,CAAC;aACX;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,gBAAgB,CAAC,SAAiB;QACxC,OAAO,CACL,SAAS,KAAK,SAAS;YACvB,SAAS,KAAK,cAAc;YAC5B,SAAS,KAAK,eAAe;YAC7B,SAAS,KAAK,SAAS,CACxB,CAAC;IACJ,CAAC;IAEO,WAAW,CAAC,SAAiB,EAAE,aAA6B;QAClE,OAAO,CAAC,cAA+B,EAAmB,EAAE;YAC1D,MAAM,UAAU,GAAG,IAAI,CAAC;YAExB,SAAS,aAAa,CAAyB,OAAsB;gBACnE,gCAAgC;gBAChC,IAAK,OAAe,EAAE,CAAC,oBAAY,CAAC,EAAE;oBACpC,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,SAA6B,CAAC,CAAC;iBAClE;gBAED,IAAI,CAAC,CAAC,OAAO,YAAY,qBAAY,CAAC,EAAE;oBACtC,UAAU,CAAC,KAAK,CAAC,IAAI,CACnB,oCAAoC,SAAS,4BAA4B,CAC1E,CAAC;oBACF,OAAO,cAAc,CAAC,KAAK,CAAC,IAAI,EAAE,SAA6B,CAAC,CAAC;iBAClE;gBACD,IAAI,SAAS,GAAG,CAAC,CAAC;gBAClB,IAAI,cAAc,GAAG,CAAC,CAAC;gBACvB,MAAM,uBAAuB,GAAG,GAAG,EAAE,CAAC,cAAc,EAAE,CAAC;gBACvD,MAAM,kBAAkB,GAAG,GAAG,EAAE,CAAC,SAAS,EAAE,CAAC;gBAC7C,MAAM,YAAY,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC;gBAC5C,MAAM,GAAG,GAAG,CAAC,OAAO,CAAC,EAAE;oBACrB,uBAAuB;oBACvB,IACE,OAAO,CAAC,kBAAkB,KAAK,YAAY;wBAC3C,OAAO,CAAC,gBAAgB,EAAE,IAAI,EAAE,KAAK,EACrC;wBACA,OAAO,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,KAAK,CAAC;qBAC5C;oBACD,OAAO,OAAO,CAAC,kBAAkB,CAAC;gBACpC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;gBAEZ,MAAM,IAAI,GAAG,UAAU,CAAC,MAAM,CAAC,SAAS,CACtC,IAAA,mBAAW,EAAC,SAAS,EAAE,YAAY,EAAE,GAAG,EAAE,OAAO,CAAC,KAAK,CAAC,EACxD;oBACE,IAAI,EAAE,GAAG,CAAC,QAAQ,CAAC,MAAM;oBACzB,UAAU,EAAE;wBACV,CAAC,wBAAc,CAAC,EAAE,+BAAqB;wBACvC,CAAC,sBAAY,CAAC,EAAE,YAAY;wBAC5B,CAAC,4BAAkB,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI;wBAChD,CAAC,4BAAkB,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,MAAM;wBACzC,mFAAmF;wBACnF,CAAC,sBAAY,CAAC,EACZ,IAAI,CAAC,MAAM,EAAE,QAAQ;4BACrB,IAAI,CAAC,MAAM,EAAE,cAAc,EAAE,OAAO,EAAE,QAAQ;wBAChD,CAAC,2BAAiB,CAAC,EAAE,GAAG;wBACxB,CAAC,2BAAiB,CAAC,EAAE,OAAO,CAAC,KAAK;qBACnC;iBACF,CACF,CAAC;gBAEF,MAAM,OAAO,GAAG,IAAA,YAAI,EAAC,CAAC,GAAS,EAAE,EAAE;oBACjC,OAAO,CAAC,cAAc,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;oBACxD,OAAO,CAAC,cAAc,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC;oBAC9D,OAAO,CAAC,cAAc,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;oBACvD,OAAO,CAAC,cAAc,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;oBACzC,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;oBAEpC,IAAI,CAAC,YAAY,CAAC,yBAAyB,EAAE,SAAS,CAAC,CAAC;oBACxD,IAAI,CAAC,YAAY,CAAC,yBAAyB,EAAE,cAAc,CAAC,CAAC;oBAC7D,IAAI,GAAG,EAAE;wBACP,IAAI,CAAC,SAAS,CAAC;4BACb,IAAI,EAAE,GAAG,CAAC,cAAc,CAAC,KAAK;4BAC9B,OAAO,EAAE,GAAG,CAAC,OAAO;yBACrB,CAAC,CAAC;qBACJ;oBACD,IAAI,CAAC,GAAG,EAAE,CAAC;gBACb,CAAC,CAAC,CAAC;gBAEH,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,uBAAuB,CAAC,CAAC;gBAC5C,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,uBAAuB,CAAC,CAAC;gBAClD,OAAO,CAAC,EAAE,CAAC,UAAU,EAAE,kBAAkB,CAAC,CAAC;gBAC3C,OAAO,CAAC,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC;gBAC/B,IAAI,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;gBAExB,IAAI,OAAO,OAAO,CAAC,QAAQ,KAAK,UAAU,EAAE;oBAC1C,UAAU,CAAC,KAAK,CACd,OAAO,EACP,UAAU,EACV,UAAU,CAAC,mBAAmB,CAAC,OAAO,CAAC,CACxC,CAAC;iBACH;qBAAM;oBACL,UAAU,CAAC,KAAK,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC;iBACtE;gBAED,MAAM,cAAc,GAAG,GAAG,EAAE;oBAC1B,OAAO,GAAG,CAAC,OAAO,CAAC,IAAI,CACrB,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,EAC7C,cAAc,EACd,IAAI,EACJ,GAAG,SAAS,CACb,CAAC;gBACJ,CAAC,CAAC;gBAEF,MAAM,GAAG,GAAG,UAAU,CAAC,SAAS,EAAE,CAAC;gBACnC,MAAM,YAAY,GAChB,GAAG,CAAC,6BAA6B;oBACjC,UAAU,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;gBAEzC,IAAI,CAAC,YAAY;oBAAE,OAAO,cAAc,EAAE,CAAC;gBAE3C,MAAM,WAAW,GAAG,UAAU,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC;gBAEvD,KAAK,UAAU;qBACZ,kBAAkB,CAAC,IAAI,EAAE,aAAa,EAAE,WAAW,CAAC;qBACpD,OAAO,CAAC,cAAc,CAAC,CAAC;YAC7B,CAAC;YAED,MAAM,CAAC,cAAc,CAAC,aAAa,EAAE,QAAQ,EAAE;gBAC7C,KAAK,EAAE,cAAc,CAAC,MAAM;gBAC5B,QAAQ,EAAE,KAAK;aAChB,CAAC,CAAC;YAEH,OAAO,aAAa,CAAC;QACvB,CAAC,CAAC;IACJ,CAAC;IAEO,mBAAmB,CAAC,OAAiB;QAC3C,OAAO,CAAC,gBAA0B,EAAE,EAAE;YACpC,OAAO,UAEL,GAA6B,EAC7B,QAAiB,EACjB,IAAU;gBAEV,OAAO,CAAC,GAAG,CAAC,CAAC;gBACb,OAAO,gBAAgB,CAAC,KAAK,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;YACjD,CAAC,CAAC;QACJ,CAAC,CAAC;IACJ,CAAC;;AAzOU,wDAAsB","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as api from '@opentelemetry/api';\nimport { EventEmitter } from 'events';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n isWrapped,\n} from '@opentelemetry/instrumentation';\nimport {\n DB_SYSTEM_VALUE_MSSQL,\n ATTR_DB_NAME,\n ATTR_DB_SQL_TABLE,\n ATTR_DB_STATEMENT,\n ATTR_DB_SYSTEM,\n ATTR_DB_USER,\n ATTR_NET_PEER_NAME,\n ATTR_NET_PEER_PORT,\n} from './semconv';\nimport type * as tedious from 'tedious';\nimport { TediousInstrumentationConfig } from './types';\nimport { getSpanName, once } from './utils';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\n\nconst CURRENT_DATABASE = Symbol(\n 'opentelemetry.instrumentation-tedious.current-database'\n);\n\nexport const INJECTED_CTX = Symbol(\n 'opentelemetry.instrumentation-tedious.context-info-injected'\n);\n\nconst PATCHED_METHODS = [\n 'callProcedure',\n 'execSql',\n 'execSqlBatch',\n 'execBulkLoad',\n 'prepare',\n 'execute',\n];\n\ntype UnknownFunction = (...args: any[]) => any;\ntype ApproxConnection = EventEmitter & {\n [CURRENT_DATABASE]: string;\n config: any;\n};\ntype ApproxRequest = EventEmitter & {\n sqlTextOrProcedure: string | undefined;\n callback: any;\n table: string | undefined;\n parametersByName: any;\n};\n\nfunction setDatabase(this: ApproxConnection, databaseName: string) {\n Object.defineProperty(this, CURRENT_DATABASE, {\n value: databaseName,\n writable: true,\n });\n}\n\nexport class TediousInstrumentation extends InstrumentationBase<TediousInstrumentationConfig> {\n static readonly COMPONENT = 'tedious';\n\n constructor(config: TediousInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n }\n\n protected init() {\n return [\n new InstrumentationNodeModuleDefinition(\n TediousInstrumentation.COMPONENT,\n ['>=1.11.0 <20'],\n (moduleExports: typeof tedious) => {\n const ConnectionPrototype: any = moduleExports.Connection.prototype;\n for (const method of PATCHED_METHODS) {\n if (isWrapped(ConnectionPrototype[method])) {\n this._unwrap(ConnectionPrototype, method);\n }\n this._wrap(\n ConnectionPrototype,\n method,\n this._patchQuery(method, moduleExports) as any\n );\n }\n\n if (isWrapped(ConnectionPrototype.connect)) {\n this._unwrap(ConnectionPrototype, 'connect');\n }\n this._wrap(ConnectionPrototype, 'connect', this._patchConnect);\n\n return moduleExports;\n },\n (moduleExports: typeof tedious) => {\n if (moduleExports === undefined) return;\n const ConnectionPrototype: any = moduleExports.Connection.prototype;\n for (const method of PATCHED_METHODS) {\n this._unwrap(ConnectionPrototype, method);\n }\n this._unwrap(ConnectionPrototype, 'connect');\n }\n ),\n ];\n }\n\n private _patchConnect(original: UnknownFunction): UnknownFunction {\n return function patchedConnect(this: ApproxConnection) {\n setDatabase.call(this, this.config?.options?.database);\n\n // remove the listener first in case it's already added\n this.removeListener('databaseChange', setDatabase);\n this.on('databaseChange', setDatabase);\n\n this.once('end', () => {\n this.removeListener('databaseChange', setDatabase);\n });\n return original.apply(this, arguments as unknown as any[]);\n };\n }\n\n private _buildTraceparent(span: api.Span): string {\n const sc = span.spanContext();\n return `00-${sc.traceId}-${sc.spanId}-0${Number(sc.traceFlags || api.TraceFlags.NONE).toString(16)}`;\n }\n\n /**\n * Fire a one-off `SET CONTEXT_INFO @opentelemetry_traceparent` on the same\n * connection. Marks the request with INJECTED_CTX so our patch skips it.\n */\n private _injectContextInfo(\n connection: any,\n tediousModule: typeof tedious,\n traceparent: string\n ): Promise<void> {\n return new Promise(resolve => {\n try {\n const sql = 'set context_info @opentelemetry_traceparent';\n const req = new tediousModule.Request(sql, (_err: any) => {\n resolve();\n });\n Object.defineProperty(req, INJECTED_CTX, { value: true });\n const buf = Buffer.from(traceparent, 'utf8');\n req.addParameter(\n 'opentelemetry_traceparent',\n (tediousModule as any).TYPES.VarBinary,\n buf,\n { length: buf.length }\n );\n\n connection.execSql(req);\n } catch {\n resolve();\n }\n });\n }\n\n private _shouldInjectFor(operation: string): boolean {\n return (\n operation === 'execSql' ||\n operation === 'execSqlBatch' ||\n operation === 'callProcedure' ||\n operation === 'execute'\n );\n }\n\n private _patchQuery(operation: string, tediousModule: typeof tedious) {\n return (originalMethod: UnknownFunction): UnknownFunction => {\n const thisPlugin = this;\n\n function patchedMethod(this: ApproxConnection, request: ApproxRequest) {\n // Skip our own injected request\n if ((request as any)?.[INJECTED_CTX]) {\n return originalMethod.apply(this, arguments as unknown as any[]);\n }\n\n if (!(request instanceof EventEmitter)) {\n thisPlugin._diag.warn(\n `Unexpected invocation of patched ${operation} method. Span not recorded`\n );\n return originalMethod.apply(this, arguments as unknown as any[]);\n }\n let procCount = 0;\n let statementCount = 0;\n const incrementStatementCount = () => statementCount++;\n const incrementProcCount = () => procCount++;\n const databaseName = this[CURRENT_DATABASE];\n const sql = (request => {\n // Required for <11.0.9\n if (\n request.sqlTextOrProcedure === 'sp_prepare' &&\n request.parametersByName?.stmt?.value\n ) {\n return request.parametersByName.stmt.value;\n }\n return request.sqlTextOrProcedure;\n })(request);\n\n const span = thisPlugin.tracer.startSpan(\n getSpanName(operation, databaseName, sql, request.table),\n {\n kind: api.SpanKind.CLIENT,\n attributes: {\n [ATTR_DB_SYSTEM]: DB_SYSTEM_VALUE_MSSQL,\n [ATTR_DB_NAME]: databaseName,\n [ATTR_NET_PEER_PORT]: this.config?.options?.port,\n [ATTR_NET_PEER_NAME]: this.config?.server,\n // >=4 uses `authentication` object, older versions just userName and password pair\n [ATTR_DB_USER]:\n this.config?.userName ??\n this.config?.authentication?.options?.userName,\n [ATTR_DB_STATEMENT]: sql,\n [ATTR_DB_SQL_TABLE]: request.table,\n },\n }\n );\n\n const endSpan = once((err?: any) => {\n request.removeListener('done', incrementStatementCount);\n request.removeListener('doneInProc', incrementStatementCount);\n request.removeListener('doneProc', incrementProcCount);\n request.removeListener('error', endSpan);\n this.removeListener('end', endSpan);\n\n span.setAttribute('tedious.procedure_count', procCount);\n span.setAttribute('tedious.statement_count', statementCount);\n if (err) {\n span.setStatus({\n code: api.SpanStatusCode.ERROR,\n message: err.message,\n });\n }\n span.end();\n });\n\n request.on('done', incrementStatementCount);\n request.on('doneInProc', incrementStatementCount);\n request.on('doneProc', incrementProcCount);\n request.once('error', endSpan);\n this.on('end', endSpan);\n\n if (typeof request.callback === 'function') {\n thisPlugin._wrap(\n request,\n 'callback',\n thisPlugin._patchCallbackQuery(endSpan)\n );\n } else {\n thisPlugin._diag.error('Expected request.callback to be a function');\n }\n\n const runUserRequest = () => {\n return api.context.with(\n api.trace.setSpan(api.context.active(), span),\n originalMethod,\n this,\n ...arguments\n );\n };\n\n const cfg = thisPlugin.getConfig();\n const shouldInject =\n cfg.enableTraceContextPropagation &&\n thisPlugin._shouldInjectFor(operation);\n\n if (!shouldInject) return runUserRequest();\n\n const traceparent = thisPlugin._buildTraceparent(span);\n \n void thisPlugin\n ._injectContextInfo(this, tediousModule, traceparent)\n .finally(runUserRequest);\n }\n\n Object.defineProperty(patchedMethod, 'length', {\n value: originalMethod.length,\n writable: false,\n });\n\n return patchedMethod;\n };\n }\n\n private _patchCallbackQuery(endSpan: Function) {\n return (originalCallback: Function) => {\n return function (\n this: any,\n err: Error | undefined | null,\n rowCount?: number,\n rows?: any\n ) {\n endSpan(err);\n return originalCallback.apply(this, arguments);\n };\n };\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"instrumentation.js","sourceRoot":"","sources":["../../src/instrumentation.ts"],"names":[],"mappings":"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","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport * as api from '@opentelemetry/api';\nimport { EventEmitter } from 'events';\nimport {\n InstrumentationBase,\n InstrumentationNodeModuleDefinition,\n isWrapped,\n SemconvStability,\n semconvStabilityFromStr,\n} from '@opentelemetry/instrumentation';\nimport {\n ATTR_DB_COLLECTION_NAME,\n ATTR_DB_NAMESPACE,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_SYSTEM_NAME,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n DB_SYSTEM_NAME_VALUE_MICROSOFT_SQL_SERVER,\n} from '@opentelemetry/semantic-conventions';\nimport {\n DB_SYSTEM_VALUE_MSSQL,\n ATTR_DB_NAME,\n ATTR_DB_SQL_TABLE,\n ATTR_DB_STATEMENT,\n ATTR_DB_SYSTEM,\n ATTR_DB_USER,\n ATTR_NET_PEER_NAME,\n ATTR_NET_PEER_PORT,\n} from './semconv';\nimport type * as tedious from 'tedious';\nimport { TediousInstrumentationConfig } from './types';\nimport { getSpanName, once } from './utils';\n/** @knipignore */\nimport { PACKAGE_NAME, PACKAGE_VERSION } from './version';\n\nconst CURRENT_DATABASE = Symbol(\n 'opentelemetry.instrumentation-tedious.current-database'\n);\n\nexport const INJECTED_CTX = Symbol(\n 'opentelemetry.instrumentation-tedious.context-info-injected'\n);\n\nconst PATCHED_METHODS = [\n 'callProcedure',\n 'execSql',\n 'execSqlBatch',\n 'execBulkLoad',\n 'prepare',\n 'execute',\n];\n\ntype UnknownFunction = (...args: any[]) => any;\ntype ApproxConnection = EventEmitter & {\n [CURRENT_DATABASE]: string;\n config: any;\n};\ntype ApproxRequest = EventEmitter & {\n sqlTextOrProcedure: string | undefined;\n callback: any;\n table: string | undefined;\n parametersByName: any;\n};\n\nfunction setDatabase(this: ApproxConnection, databaseName: string) {\n Object.defineProperty(this, CURRENT_DATABASE, {\n value: databaseName,\n writable: true,\n });\n}\n\nexport class TediousInstrumentation extends InstrumentationBase<TediousInstrumentationConfig> {\n static readonly COMPONENT = 'tedious';\n private _netSemconvStability!: SemconvStability;\n private _dbSemconvStability!: SemconvStability;\n\n constructor(config: TediousInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, config);\n this._setSemconvStabilityFromEnv();\n }\n\n // Used for testing.\n private _setSemconvStabilityFromEnv() {\n this._netSemconvStability = semconvStabilityFromStr(\n 'http',\n process.env.OTEL_SEMCONV_STABILITY_OPT_IN\n );\n this._dbSemconvStability = semconvStabilityFromStr(\n 'database',\n process.env.OTEL_SEMCONV_STABILITY_OPT_IN\n );\n }\n\n protected init() {\n return [\n new InstrumentationNodeModuleDefinition(\n TediousInstrumentation.COMPONENT,\n ['>=1.11.0 <20'],\n (moduleExports: typeof tedious) => {\n const ConnectionPrototype: any = moduleExports.Connection.prototype;\n for (const method of PATCHED_METHODS) {\n if (isWrapped(ConnectionPrototype[method])) {\n this._unwrap(ConnectionPrototype, method);\n }\n this._wrap(\n ConnectionPrototype,\n method,\n this._patchQuery(method, moduleExports) as any\n );\n }\n\n if (isWrapped(ConnectionPrototype.connect)) {\n this._unwrap(ConnectionPrototype, 'connect');\n }\n this._wrap(ConnectionPrototype, 'connect', this._patchConnect);\n\n return moduleExports;\n },\n (moduleExports: typeof tedious) => {\n if (moduleExports === undefined) return;\n const ConnectionPrototype: any = moduleExports.Connection.prototype;\n for (const method of PATCHED_METHODS) {\n this._unwrap(ConnectionPrototype, method);\n }\n this._unwrap(ConnectionPrototype, 'connect');\n }\n ),\n ];\n }\n\n private _patchConnect(original: UnknownFunction): UnknownFunction {\n return function patchedConnect(this: ApproxConnection) {\n setDatabase.call(this, this.config?.options?.database);\n\n // remove the listener first in case it's already added\n this.removeListener('databaseChange', setDatabase);\n this.on('databaseChange', setDatabase);\n\n this.once('end', () => {\n this.removeListener('databaseChange', setDatabase);\n });\n return original.apply(this, arguments as unknown as any[]);\n };\n }\n\n private _buildTraceparent(span: api.Span): string {\n const sc = span.spanContext();\n return `00-${sc.traceId}-${sc.spanId}-0${Number(sc.traceFlags || api.TraceFlags.NONE).toString(16)}`;\n }\n\n /**\n * Fire a one-off `SET CONTEXT_INFO @opentelemetry_traceparent` on the same\n * connection. Marks the request with INJECTED_CTX so our patch skips it.\n */\n private _injectContextInfo(\n connection: any,\n tediousModule: typeof tedious,\n traceparent: string\n ): Promise<void> {\n return new Promise(resolve => {\n try {\n const sql = 'set context_info @opentelemetry_traceparent';\n const req = new tediousModule.Request(sql, (_err: any) => {\n resolve();\n });\n Object.defineProperty(req, INJECTED_CTX, { value: true });\n const buf = Buffer.from(traceparent, 'utf8');\n req.addParameter(\n 'opentelemetry_traceparent',\n (tediousModule as any).TYPES.VarBinary,\n buf,\n { length: buf.length }\n );\n\n connection.execSql(req);\n } catch {\n resolve();\n }\n });\n }\n\n private _shouldInjectFor(operation: string): boolean {\n return (\n operation === 'execSql' ||\n operation === 'execSqlBatch' ||\n operation === 'callProcedure' ||\n operation === 'execute'\n );\n }\n\n private _patchQuery(operation: string, tediousModule: typeof tedious) {\n return (originalMethod: UnknownFunction): UnknownFunction => {\n const thisPlugin = this;\n\n function patchedMethod(this: ApproxConnection, request: ApproxRequest) {\n // Skip our own injected request\n if ((request as any)?.[INJECTED_CTX]) {\n return originalMethod.apply(this, arguments as unknown as any[]);\n }\n\n if (!(request instanceof EventEmitter)) {\n thisPlugin._diag.warn(\n `Unexpected invocation of patched ${operation} method. Span not recorded`\n );\n return originalMethod.apply(this, arguments as unknown as any[]);\n }\n let procCount = 0;\n let statementCount = 0;\n const incrementStatementCount = () => statementCount++;\n const incrementProcCount = () => procCount++;\n const databaseName = this[CURRENT_DATABASE];\n const sql = (request => {\n // Required for <11.0.9\n if (\n request.sqlTextOrProcedure === 'sp_prepare' &&\n request.parametersByName?.stmt?.value\n ) {\n return request.parametersByName.stmt.value;\n }\n return request.sqlTextOrProcedure;\n })(request);\n\n const attributes: api.Attributes = {};\n if (thisPlugin._dbSemconvStability & SemconvStability.OLD) {\n attributes[ATTR_DB_SYSTEM] = DB_SYSTEM_VALUE_MSSQL;\n attributes[ATTR_DB_NAME] = databaseName;\n // >=4 uses `authentication` object; older versions just userName and password pair\n attributes[ATTR_DB_USER] =\n this.config?.userName ??\n this.config?.authentication?.options?.userName;\n attributes[ATTR_DB_STATEMENT] = sql;\n attributes[ATTR_DB_SQL_TABLE] = request.table;\n }\n if (thisPlugin._dbSemconvStability & SemconvStability.STABLE) {\n // The OTel spec for \"db.namespace\" discusses handling for connection\n // to MSSQL \"named instances\". This isn't currently supported.\n // https://opentelemetry.io/docs/specs/semconv/database/sql-server/#:~:text=%5B1%5D%20db%2Enamespace\n attributes[ATTR_DB_NAMESPACE] = databaseName;\n attributes[ATTR_DB_SYSTEM_NAME] =\n DB_SYSTEM_NAME_VALUE_MICROSOFT_SQL_SERVER;\n attributes[ATTR_DB_QUERY_TEXT] = sql;\n attributes[ATTR_DB_COLLECTION_NAME] = request.table;\n // See https://opentelemetry.io/docs/specs/semconv/database/sql-server/#spans\n // TODO(3290): can `db.response.status_code` be added?\n // TODO(3290): is `operation` correct for `db.operation.name`\n // TODO(3290): can `db.query.summary` reliably be calculated?\n // TODO(3290): `db.stored_procedure.name`\n }\n if (thisPlugin._netSemconvStability & SemconvStability.OLD) {\n attributes[ATTR_NET_PEER_NAME] = this.config?.server;\n attributes[ATTR_NET_PEER_PORT] = this.config?.options?.port;\n }\n if (thisPlugin._netSemconvStability & SemconvStability.STABLE) {\n attributes[ATTR_SERVER_ADDRESS] = this.config?.server;\n attributes[ATTR_SERVER_PORT] = this.config?.options?.port;\n }\n const span = thisPlugin.tracer.startSpan(\n getSpanName(operation, databaseName, sql, request.table),\n {\n kind: api.SpanKind.CLIENT,\n attributes,\n }\n );\n\n const endSpan = once((err?: any) => {\n request.removeListener('done', incrementStatementCount);\n request.removeListener('doneInProc', incrementStatementCount);\n request.removeListener('doneProc', incrementProcCount);\n request.removeListener('error', endSpan);\n this.removeListener('end', endSpan);\n\n span.setAttribute('tedious.procedure_count', procCount);\n span.setAttribute('tedious.statement_count', statementCount);\n if (err) {\n span.setStatus({\n code: api.SpanStatusCode.ERROR,\n message: err.message,\n });\n // TODO(3290): set `error.type` attribute?\n }\n span.end();\n });\n\n request.on('done', incrementStatementCount);\n request.on('doneInProc', incrementStatementCount);\n request.on('doneProc', incrementProcCount);\n request.once('error', endSpan);\n this.on('end', endSpan);\n\n if (typeof request.callback === 'function') {\n thisPlugin._wrap(\n request,\n 'callback',\n thisPlugin._patchCallbackQuery(endSpan)\n );\n } else {\n thisPlugin._diag.error('Expected request.callback to be a function');\n }\n\n const runUserRequest = () => {\n return api.context.with(\n api.trace.setSpan(api.context.active(), span),\n originalMethod,\n this,\n ...arguments\n );\n };\n\n const cfg = thisPlugin.getConfig();\n const shouldInject =\n cfg.enableTraceContextPropagation &&\n thisPlugin._shouldInjectFor(operation);\n\n if (!shouldInject) return runUserRequest();\n\n const traceparent = thisPlugin._buildTraceparent(span);\n\n void thisPlugin\n ._injectContextInfo(this, tediousModule, traceparent)\n .finally(runUserRequest);\n }\n\n Object.defineProperty(patchedMethod, 'length', {\n value: originalMethod.length,\n writable: false,\n });\n\n return patchedMethod;\n };\n }\n\n private _patchCallbackQuery(endSpan: Function) {\n return (originalCallback: Function) => {\n return function (\n this: any,\n err: Error | undefined | null,\n rowCount?: number,\n rows?: any\n ) {\n endSpan(err);\n return originalCallback.apply(this, arguments);\n };\n };\n }\n}\n"]}
|
package/build/src/version.d.ts
CHANGED
package/build/src/version.js
CHANGED
|
@@ -17,6 +17,6 @@
|
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
18
|
exports.PACKAGE_NAME = exports.PACKAGE_VERSION = void 0;
|
|
19
19
|
// this is autogenerated file, see scripts/version-update.js
|
|
20
|
-
exports.PACKAGE_VERSION = '0.
|
|
20
|
+
exports.PACKAGE_VERSION = '0.29.0';
|
|
21
21
|
exports.PACKAGE_NAME = '@opentelemetry/instrumentation-tedious';
|
|
22
22
|
//# sourceMappingURL=version.js.map
|
package/build/src/version.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH,4DAA4D;AAC/C,QAAA,eAAe,GAAG,QAAQ,CAAC;AAC3B,QAAA,YAAY,GAAG,wCAAwC,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// this is autogenerated file, see scripts/version-update.js\nexport const PACKAGE_VERSION = '0.
|
|
1
|
+
{"version":3,"file":"version.js","sourceRoot":"","sources":["../../src/version.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;;AAEH,4DAA4D;AAC/C,QAAA,eAAe,GAAG,QAAQ,CAAC;AAC3B,QAAA,YAAY,GAAG,wCAAwC,CAAC","sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * https://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n// this is autogenerated file, see scripts/version-update.js\nexport const PACKAGE_VERSION = '0.29.0';\nexport const PACKAGE_NAME = '@opentelemetry/instrumentation-tedious';\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@opentelemetry/instrumentation-tedious",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.29.0",
|
|
4
4
|
"description": "OpenTelemetry instrumentation for `tedious` database client for Microsoft SQL Server",
|
|
5
5
|
"main": "build/src/index.js",
|
|
6
6
|
"types": "build/src/index.d.ts",
|
|
@@ -54,22 +54,15 @@
|
|
|
54
54
|
"devDependencies": {
|
|
55
55
|
"@opentelemetry/api": "^1.3.0",
|
|
56
56
|
"@opentelemetry/context-async-hooks": "^2.0.0",
|
|
57
|
-
"@opentelemetry/contrib-test-utils": "^0.
|
|
57
|
+
"@opentelemetry/contrib-test-utils": "^0.57.0",
|
|
58
58
|
"@opentelemetry/sdk-trace-base": "^2.0.0",
|
|
59
|
-
"
|
|
60
|
-
"@types/node": "18.18.14",
|
|
61
|
-
"cross-env": "7.0.3",
|
|
62
|
-
"nyc": "17.1.0",
|
|
63
|
-
"rimraf": "5.0.10",
|
|
64
|
-
"semver": "7.7.3",
|
|
65
|
-
"tedious": "17.0.0",
|
|
66
|
-
"test-all-versions": "6.1.0",
|
|
67
|
-
"typescript": "5.0.4"
|
|
59
|
+
"tedious": "17.0.0"
|
|
68
60
|
},
|
|
69
61
|
"dependencies": {
|
|
70
|
-
"@opentelemetry/instrumentation": "^0.
|
|
62
|
+
"@opentelemetry/instrumentation": "^0.210.0",
|
|
63
|
+
"@opentelemetry/semantic-conventions": "^1.33.0",
|
|
71
64
|
"@types/tedious": "^4.0.14"
|
|
72
65
|
},
|
|
73
66
|
"homepage": "https://github.com/open-telemetry/opentelemetry-js-contrib/tree/main/packages/instrumentation-tedious#readme",
|
|
74
|
-
"gitHead": "
|
|
67
|
+
"gitHead": "c84212cca7f010b80747cccb9942474e0459df6e"
|
|
75
68
|
}
|