@sebspark/opentelemetry-instrumentation-opensearch 0.3.15 → 0.4.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/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # @sebspark/opentelemetry-instrumentation-opensearch
2
2
 
3
+ ## 0.4.0
4
+
5
+ ### Minor Changes
6
+
7
+ - ad1e80f: Upgraded to OpenTelemetry 3.0. Peer `@opentelemetry/api` is now `>=1.10.0 <1.11.0`.
8
+
3
9
  ## 0.3.15
4
10
 
5
11
  ### Patch Changes
package/dist/index.d.mts CHANGED
@@ -1,7 +1,6 @@
1
1
  import { ApiResponse, TransportRequestParams } from "@opensearch-project/opensearch/lib/Transport.js";
2
2
  import { InstrumentationBase, InstrumentationConfig } from "@opentelemetry/instrumentation";
3
3
  import { Span } from "@opentelemetry/api";
4
- //#region src/types.d.ts
5
4
  interface OpenSearchInstrumentationConfig extends InstrumentationConfig {
6
5
  dbStatementSerializer?: false | ((params: TransportRequestParams) => string);
7
6
  requestHook?: (span: Span, params: TransportRequestParams) => void;
@@ -9,8 +8,6 @@ interface OpenSearchInstrumentationConfig extends InstrumentationConfig {
9
8
  suppressInternalInstrumentation?: boolean;
10
9
  moduleVersionAttributeName?: string;
11
10
  }
12
- //#endregion
13
- //#region src/index.d.ts
14
11
  export declare class OpenSearchInstrumentation extends InstrumentationBase {
15
12
  private readonly osConfig;
16
13
  private _original;
@@ -19,6 +16,5 @@ export declare class OpenSearchInstrumentation extends InstrumentationBase {
19
16
  enable(): void;
20
17
  disable(): void;
21
18
  }
22
- //#endregion
23
19
  export type { OpenSearchInstrumentationConfig };
24
20
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;;UAOiB,wCAAwC;EACvD,kCAAkC,QAAQ;EAC1C,eAAe,MAAM,MAAM,QAAQ;EACnC,gBAAgB,MAAM,MAAM,UAAU;EACtC;EACA;;;;qBCGW,kCAAkC;mBAC5B;UACT;EAER,YAAY,SAAQ;YAQV;EAED;EAWA"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/types.ts","../src/index.ts"],"mappings":";;;UAOiB,wCAAwC;EACvD,kCAAkC,QAAQ;EAC1C,eAAe,MAAM,MAAM,QAAQ;EACnC,gBAAgB,MAAM,MAAM,UAAU;EACtC;EACA;;qBCGW,kCAAkC;mBAC5B;UACT;EAER,YAAY,SAAQ;YAQV;EAED;EAWA"}
package/dist/index.mjs CHANGED
@@ -4,11 +4,10 @@ import { InstrumentationBase } from "@opentelemetry/instrumentation";
4
4
  import { SpanKind, SpanStatusCode, context, trace } from "@opentelemetry/api";
5
5
  import { suppressTracing } from "@opentelemetry/core";
6
6
  import { ATTR_DB_COLLECTION_NAME, ATTR_DB_OPERATION_NAME, ATTR_DB_QUERY_TEXT, ATTR_DB_SYSTEM_NAME, ATTR_HTTP_RESPONSE_STATUS_CODE, ATTR_SERVER_ADDRESS, ATTR_SERVER_PORT } from "@opentelemetry/semantic-conventions";
7
- //#region package.json
7
+ // package.json
8
8
  var name = "@sebspark/opentelemetry-instrumentation-opensearch";
9
- var version = "0.3.15";
10
- //#endregion
11
- //#region src/parse-path.ts
9
+ var version = "0.4.0";
10
+ // src/parse-path.ts
12
11
  const METHOD_OPERATIONS = {
13
12
  PUT: "indices.create",
14
13
  DELETE: "indices.delete"
@@ -33,8 +32,7 @@ const parsePath = (path, method) => {
33
32
  }
34
33
  return {};
35
34
  };
36
- //#endregion
37
- //#region src/response-attributes.ts
35
+ // src/response-attributes.ts
38
36
  const ATTR_DB_OPENSEARCH_DURATION_MS = "db.opensearch.duration_ms";
39
37
  const extractResponseAttributes = (res) => {
40
38
  const attrs = {};
@@ -67,16 +65,14 @@ const extractResponseAttributes = (res) => {
67
65
  if (total != null && typeof total === "object") attrs["db.opensearch.hits.total"] = total.value;
68
66
  return attrs;
69
67
  };
70
- //#endregion
71
- //#region src/serialize-body.ts
68
+ // src/serialize-body.ts
72
69
  const serializeBody = (params, config) => {
73
70
  if (!params.body) return void 0;
74
71
  if (config.dbStatementSerializer === false) return void 0;
75
72
  if (typeof config.dbStatementSerializer === "function") return config.dbStatementSerializer(params);
76
73
  return typeof params.body === "string" ? params.body : JSON.stringify(params.body);
77
74
  };
78
- //#endregion
79
- //#region src/patch-request.ts
75
+ // src/patch-request.ts
80
76
  const createPatchedRequest = (getTracer, config = {}, original, clientVersion) => {
81
77
  function patchedRequest(params, options, callback) {
82
78
  const { index, operation } = parsePath(params.path, params.method);
@@ -125,8 +121,7 @@ const createPatchedRequest = (getTracer, config = {}, original, clientVersion) =
125
121
  }
126
122
  return patchedRequest;
127
123
  };
128
- //#endregion
129
- //#region src/index.ts
124
+ // src/index.ts
130
125
  const PACKAGE_NAME = name;
131
126
  const PACKAGE_VERSION = version;
132
127
  const OPENSEARCH_CLIENT_VERSION = opensearchPkg.version;
@@ -154,7 +149,6 @@ var OpenSearchInstrumentation = class extends InstrumentationBase {
154
149
  }
155
150
  }
156
151
  };
157
- //#endregion
158
152
  export { OpenSearchInstrumentation };
159
153
 
160
154
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["pkg.name","pkg.version"],"sources":["../package.json","../src/parse-path.ts","../src/response-attributes.ts","../src/serialize-body.ts","../src/patch-request.ts","../src/index.ts"],"sourcesContent":["","const METHOD_OPERATIONS: Record<string, string> = {\n PUT: 'indices.create',\n DELETE: 'indices.delete',\n}\n\nconst OPERATION_ALIASES: Record<string, string> = {\n doc: 'index',\n}\n\nexport const parsePath = (\n path: string,\n method?: string\n): { index?: string; operation?: string } => {\n const decoded = decodeURIComponent(path)\n const match = decoded.match(/^\\/(?:([^/_][^/]*)\\/)?_([^/]+)/)\n if (match) {\n const operation = OPERATION_ALIASES[match[2]] ?? match[2]\n return { index: match[1], operation }\n }\n\n if (method) {\n const operation = METHOD_OPERATIONS[method.toUpperCase()]\n if (operation) {\n const index = decoded.replace(/^\\//, '') || undefined\n return { index, operation }\n }\n }\n\n return {}\n}\n","import type { Types } from '@opensearch-project/opensearch'\nimport type { ApiResponse } from '@opensearch-project/opensearch/lib/Transport.js'\nimport {\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions'\n\nexport const ATTR_DB_OPENSEARCH_DURATION_MS = 'db.opensearch.duration_ms'\n\nexport const extractResponseAttributes = (\n res: ApiResponse\n): Record<string, string | number | boolean> => {\n const attrs: Record<string, string | number | boolean> = {}\n\n const { hostname, port } = res.meta.connection.url\n attrs[ATTR_SERVER_ADDRESS] = hostname\n if (port) attrs[ATTR_SERVER_PORT] = Number(port)\n if (res.statusCode != null)\n attrs[ATTR_HTTP_RESPONSE_STATUS_CODE] = res.statusCode\n\n const body = res.body as Types.Core_Search.ResponseBody | null | undefined\n if (body == null) return attrs\n\n if (body.took != null) attrs['db.opensearch.took'] = body.took\n if (body.timed_out != null) attrs['db.opensearch.timed_out'] = body.timed_out\n if (body.terminated_early != null)\n attrs['db.opensearch.terminated_early'] = body.terminated_early\n\n const shards = body._shards\n if (shards != null) {\n attrs['db.opensearch.shards.total'] = shards.total\n attrs['db.opensearch.shards.successful'] = shards.successful\n attrs['db.opensearch.shards.failed'] = shards.failed\n if (shards.skipped != null)\n attrs['db.opensearch.shards.skipped'] = shards.skipped\n }\n\n const phaseTook = body.phase_took\n if (phaseTook != null) {\n attrs['db.opensearch.phase_took.can_match'] = phaseTook.can_match\n attrs['db.opensearch.phase_took.dfs_pre_query'] = phaseTook.dfs_pre_query\n attrs['db.opensearch.phase_took.dfs_query'] = phaseTook.dfs_query\n attrs['db.opensearch.phase_took.expand'] = phaseTook.expand\n attrs['db.opensearch.phase_took.fetch'] = phaseTook.fetch\n attrs['db.opensearch.phase_took.query'] = phaseTook.query\n }\n\n const total = body.hits?.total\n if (total != null && typeof total === 'object') {\n attrs['db.opensearch.hits.total'] = total.value\n }\n\n return attrs\n}\n","import type { TransportRequestParams } from '@opensearch-project/opensearch/lib/Transport.js'\nimport type { OpenSearchInstrumentationConfig } from './types'\n\nexport const serializeBody = (\n params: TransportRequestParams,\n config: Pick<OpenSearchInstrumentationConfig, 'dbStatementSerializer'>\n): string | undefined => {\n if (!params.body) return undefined\n if (config.dbStatementSerializer === false) return undefined\n if (typeof config.dbStatementSerializer === 'function') {\n return config.dbStatementSerializer(params)\n }\n return typeof params.body === 'string'\n ? params.body\n : JSON.stringify(params.body)\n}\n","import type Transport from '@opensearch-project/opensearch/lib/Transport.js'\nimport type {\n ApiError,\n ApiResponse,\n TransportRequestCallback,\n TransportRequestOptions,\n TransportRequestParams,\n TransportRequestPromise,\n} from '@opensearch-project/opensearch/lib/Transport.js'\nimport {\n context,\n SpanKind,\n SpanStatusCode,\n type Tracer,\n trace,\n} from '@opentelemetry/api'\nimport { suppressTracing } from '@opentelemetry/core'\nimport {\n ATTR_DB_COLLECTION_NAME,\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_SYSTEM_NAME,\n} from '@opentelemetry/semantic-conventions'\nimport { parsePath } from './parse-path'\nimport {\n ATTR_DB_OPENSEARCH_DURATION_MS,\n extractResponseAttributes,\n} from './response-attributes'\nimport { serializeBody } from './serialize-body'\nimport type { OpenSearchInstrumentationConfig } from './types'\n\nexport type OriginalRequest = (\n this: Transport,\n params: TransportRequestParams,\n options?: TransportRequestOptions\n) => TransportRequestPromise<ApiResponse>\n\ntype OriginalRequestWithCallback = (\n this: Transport,\n params: TransportRequestParams,\n options: TransportRequestOptions | undefined,\n callback: (err: ApiError, result: ApiResponse) => void\n) => TransportRequestCallback\n\nexport const createPatchedRequest = (\n getTracer: () => Tracer,\n config: OpenSearchInstrumentationConfig = {},\n original: OriginalRequest,\n clientVersion: string\n) => {\n function patchedRequest(\n params: TransportRequestParams,\n options?: TransportRequestOptions\n ): TransportRequestPromise<ApiResponse>\n function patchedRequest(\n params: TransportRequestParams,\n options: TransportRequestOptions | undefined,\n callback: (err: ApiError, result: ApiResponse) => void\n ): TransportRequestCallback\n function patchedRequest(\n this: Transport,\n params: TransportRequestParams,\n options?: TransportRequestOptions,\n callback?: (err: ApiError, result: ApiResponse) => void\n ): TransportRequestPromise<ApiResponse> | TransportRequestCallback {\n const { index, operation } = parsePath(params.path, params.method)\n const queryText = serializeBody(params, config)\n\n const span = getTracer().startSpan(\n [operation, index].filter(Boolean).join(' ') || params.path,\n {\n kind: SpanKind.CLIENT,\n attributes: {\n [ATTR_DB_SYSTEM_NAME]: 'opensearch',\n ...(operation && { [ATTR_DB_OPERATION_NAME]: operation }),\n ...(index && { [ATTR_DB_COLLECTION_NAME]: index }),\n ...(queryText && { [ATTR_DB_QUERY_TEXT]: queryText }),\n },\n }\n )\n config.requestHook?.(span, params)\n\n const startTime = Date.now()\n\n const onSuccess = (res: ApiResponse) => {\n span.setAttribute(ATTR_DB_OPENSEARCH_DURATION_MS, Date.now() - startTime)\n for (const [key, value] of Object.entries(\n extractResponseAttributes(res)\n )) {\n span.setAttribute(key, value)\n }\n if (config.moduleVersionAttributeName) {\n span.setAttribute(config.moduleVersionAttributeName, clientVersion)\n }\n config.responseHook?.(span, res)\n span.end()\n }\n\n const onError = (err: unknown) => {\n span.setAttribute(ATTR_DB_OPENSEARCH_DURATION_MS, Date.now() - startTime)\n if (err instanceof Error) span.recordException(err)\n span.setStatus({ code: SpanStatusCode.ERROR })\n span.end()\n }\n\n const callCtx = config.suppressInternalInstrumentation\n ? suppressTracing(context.active())\n : trace.setSpan(context.active(), span)\n\n if (typeof callback === 'function') {\n const originalWithCallback = (\n original as OriginalRequestWithCallback\n ).bind(this)\n return context.with(callCtx, () =>\n originalWithCallback(params, options, (err, res) => {\n err ? onError(err) : onSuccess(res)\n callback(err, res)\n })\n )\n }\n\n const result = context.with(callCtx, () =>\n original.call(this, params, options)\n )\n const settled = result.then(\n (res: ApiResponse) => {\n onSuccess(res)\n return res\n },\n (err: unknown) => {\n onError(err)\n throw err\n }\n )\n return Object.assign(settled, { abort: result.abort })\n }\n\n return patchedRequest\n}\n","import Transport from '@opensearch-project/opensearch/lib/Transport.js'\nimport opensearchPkg from '@opensearch-project/opensearch/package.json' with {\n type: 'json',\n}\nimport { InstrumentationBase } from '@opentelemetry/instrumentation'\nimport pkg from '../package.json' with { type: 'json' }\nimport { createPatchedRequest, type OriginalRequest } from './patch-request'\nimport type { OpenSearchInstrumentationConfig } from './types'\n\nexport type { OpenSearchInstrumentationConfig } from './types'\n\nconst PACKAGE_NAME: string = pkg.name\nconst PACKAGE_VERSION: string = pkg.version\nconst OPENSEARCH_CLIENT_VERSION: string = opensearchPkg.version\n\nexport class OpenSearchInstrumentation extends InstrumentationBase {\n private readonly osConfig: OpenSearchInstrumentationConfig\n private _original: OriginalRequest | undefined\n\n constructor(config: OpenSearchInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, { ...config, enabled: false })\n this.osConfig = config\n if (config.enabled !== false) {\n this.enable()\n }\n }\n\n protected init() {}\n\n override enable() {\n if (this._original) return\n this._original = Transport.prototype.request as OriginalRequest\n Transport.prototype.request = createPatchedRequest(\n () => this.tracer,\n this.osConfig,\n this._original,\n OPENSEARCH_CLIENT_VERSION\n )\n }\n\n override disable() {\n if (this._original) {\n Transport.prototype.request = this._original\n this._original = undefined\n }\n }\n}\n"],"mappings":";;;;;;;;;;;ACAA,MAAM,oBAA4C;CAChD,KAAK;CACL,QAAQ;AACV;AAEA,MAAM,oBAA4C,EAChD,KAAK,QACP;AAEA,MAAa,aACX,MACA,WAC2C;CAC3C,MAAM,UAAU,mBAAmB,IAAI;CACvC,MAAM,QAAQ,QAAQ,MAAM,gCAAgC;CAC5D,IAAI,OAAO;EACT,MAAM,YAAY,kBAAkB,MAAM,OAAO,MAAM;EACvD,OAAO;GAAE,OAAO,MAAM;GAAI;EAAU;CACtC;CAEA,IAAI,QAAQ;EACV,MAAM,YAAY,kBAAkB,OAAO,YAAY;EACvD,IAAI,WAEF,OAAO;GAAE,OADK,QAAQ,QAAQ,OAAO,EAAE,KAAK,KAAA;GAC5B;EAAU;CAE9B;CAEA,OAAO,CAAC;AACV;;;ACrBA,MAAa,iCAAiC;AAE9C,MAAa,6BACX,QAC8C;CAC9C,MAAM,QAAmD,CAAC;CAE1D,MAAM,EAAE,UAAU,SAAS,IAAI,KAAK,WAAW;CAC/C,MAAM,uBAAuB;CAC7B,IAAI,MAAM,MAAM,oBAAoB,OAAO,IAAI;CAC/C,IAAI,IAAI,cAAc,MACpB,MAAM,kCAAkC,IAAI;CAE9C,MAAM,OAAO,IAAI;CACjB,IAAI,QAAQ,MAAM,OAAO;CAEzB,IAAI,KAAK,QAAQ,MAAM,MAAM,wBAAwB,KAAK;CAC1D,IAAI,KAAK,aAAa,MAAM,MAAM,6BAA6B,KAAK;CACpE,IAAI,KAAK,oBAAoB,MAC3B,MAAM,oCAAoC,KAAK;CAEjD,MAAM,SAAS,KAAK;CACpB,IAAI,UAAU,MAAM;EAClB,MAAM,gCAAgC,OAAO;EAC7C,MAAM,qCAAqC,OAAO;EAClD,MAAM,iCAAiC,OAAO;EAC9C,IAAI,OAAO,WAAW,MACpB,MAAM,kCAAkC,OAAO;CACnD;CAEA,MAAM,YAAY,KAAK;CACvB,IAAI,aAAa,MAAM;EACrB,MAAM,wCAAwC,UAAU;EACxD,MAAM,4CAA4C,UAAU;EAC5D,MAAM,wCAAwC,UAAU;EACxD,MAAM,qCAAqC,UAAU;EACrD,MAAM,oCAAoC,UAAU;EACpD,MAAM,oCAAoC,UAAU;CACtD;CAEA,MAAM,QAAQ,KAAK,MAAM;CACzB,IAAI,SAAS,QAAQ,OAAO,UAAU,UACpC,MAAM,8BAA8B,MAAM;CAG5C,OAAO;AACT;;;ACnDA,MAAa,iBACX,QACA,WACuB;CACvB,IAAI,CAAC,OAAO,MAAM,OAAO,KAAA;CACzB,IAAI,OAAO,0BAA0B,OAAO,OAAO,KAAA;CACnD,IAAI,OAAO,OAAO,0BAA0B,YAC1C,OAAO,OAAO,sBAAsB,MAAM;CAE5C,OAAO,OAAO,OAAO,SAAS,WAC1B,OAAO,OACP,KAAK,UAAU,OAAO,IAAI;AAChC;;;AC6BA,MAAa,wBACX,WACA,SAA0C,CAAC,GAC3C,UACA,kBACG;CAUH,SAAS,eAEP,QACA,SACA,UACiE;EACjE,MAAM,EAAE,OAAO,cAAc,UAAU,OAAO,MAAM,OAAO,MAAM;EACjE,MAAM,YAAY,cAAc,QAAQ,MAAM;EAE9C,MAAM,OAAO,UAAU,CAAC,CAAC,UACvB,CAAC,WAAW,KAAK,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,OAAO,MACvD;GACE,MAAM,SAAS;GACf,YAAY;KACT,sBAAsB;IACvB,GAAI,aAAa,GAAG,yBAAyB,UAAU;IACvD,GAAI,SAAS,GAAG,0BAA0B,MAAM;IAChD,GAAI,aAAa,GAAG,qBAAqB,UAAU;GACrD;EACF,CACF;EACA,OAAO,cAAc,MAAM,MAAM;EAEjC,MAAM,YAAY,KAAK,IAAI;EAE3B,MAAM,aAAa,QAAqB;GACtC,KAAK,aAAa,gCAAgC,KAAK,IAAI,IAAI,SAAS;GACxE,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAChC,0BAA0B,GAAG,CAC/B,GACE,KAAK,aAAa,KAAK,KAAK;GAE9B,IAAI,OAAO,4BACT,KAAK,aAAa,OAAO,4BAA4B,aAAa;GAEpE,OAAO,eAAe,MAAM,GAAG;GAC/B,KAAK,IAAI;EACX;EAEA,MAAM,WAAW,QAAiB;GAChC,KAAK,aAAa,gCAAgC,KAAK,IAAI,IAAI,SAAS;GACxE,IAAI,eAAe,OAAO,KAAK,gBAAgB,GAAG;GAClD,KAAK,UAAU,EAAE,MAAM,eAAe,MAAM,CAAC;GAC7C,KAAK,IAAI;EACX;EAEA,MAAM,UAAU,OAAO,kCACnB,gBAAgB,QAAQ,OAAO,CAAC,IAChC,MAAM,QAAQ,QAAQ,OAAO,GAAG,IAAI;EAExC,IAAI,OAAO,aAAa,YAAY;GAClC,MAAM,uBACJ,SACA,KAAK,IAAI;GACX,OAAO,QAAQ,KAAK,eAClB,qBAAqB,QAAQ,UAAU,KAAK,QAAQ;IAClD,MAAM,QAAQ,GAAG,IAAI,UAAU,GAAG;IAClC,SAAS,KAAK,GAAG;GACnB,CAAC,CACH;EACF;EAEA,MAAM,SAAS,QAAQ,KAAK,eAC1B,SAAS,KAAK,MAAM,QAAQ,OAAO,CACrC;EACA,MAAM,UAAU,OAAO,MACpB,QAAqB;GACpB,UAAU,GAAG;GACb,OAAO;EACT,IACC,QAAiB;GAChB,QAAQ,GAAG;GACX,MAAM;EACR,CACF;EACA,OAAO,OAAO,OAAO,SAAS,EAAE,OAAO,OAAO,MAAM,CAAC;CACvD;CAEA,OAAO;AACT;;;AC/HA,MAAM,eAAuBA;AAC7B,MAAM,kBAA0BC;AAChC,MAAM,4BAAoC,cAAc;AAExD,IAAa,4BAAb,cAA+C,oBAAoB;CACjE;CACA;CAEA,YAAY,SAA0C,CAAC,GAAG;EACxD,MAAM,cAAc,iBAAiB;GAAE,GAAG;GAAQ,SAAS;EAAM,CAAC;EAClE,KAAK,WAAW;EAChB,IAAI,OAAO,YAAY,OACrB,KAAK,OAAO;CAEhB;CAEA,OAAiB,CAAC;CAElB,SAAkB;EAChB,IAAI,KAAK,WAAW;EACpB,KAAK,YAAY,UAAU,UAAU;EACrC,UAAU,UAAU,UAAU,2BACtB,KAAK,QACX,KAAK,UACL,KAAK,WACL,yBACF;CACF;CAEA,UAAmB;EACjB,IAAI,KAAK,WAAW;GAClB,UAAU,UAAU,UAAU,KAAK;GACnC,KAAK,YAAY,KAAA;EACnB;CACF;AACF"}
1
+ {"version":3,"file":"index.mjs","names":["pkg.name","pkg.version"],"sources":["../package.json","../src/parse-path.ts","../src/response-attributes.ts","../src/serialize-body.ts","../src/patch-request.ts","../src/index.ts"],"sourcesContent":["","const METHOD_OPERATIONS: Record<string, string> = {\n PUT: 'indices.create',\n DELETE: 'indices.delete',\n}\n\nconst OPERATION_ALIASES: Record<string, string> = {\n doc: 'index',\n}\n\nexport const parsePath = (\n path: string,\n method?: string\n): { index?: string; operation?: string } => {\n const decoded = decodeURIComponent(path)\n const match = decoded.match(/^\\/(?:([^/_][^/]*)\\/)?_([^/]+)/)\n if (match) {\n const operation = OPERATION_ALIASES[match[2]] ?? match[2]\n return { index: match[1], operation }\n }\n\n if (method) {\n const operation = METHOD_OPERATIONS[method.toUpperCase()]\n if (operation) {\n const index = decoded.replace(/^\\//, '') || undefined\n return { index, operation }\n }\n }\n\n return {}\n}\n","import type { Types } from '@opensearch-project/opensearch'\nimport type { ApiResponse } from '@opensearch-project/opensearch/lib/Transport.js'\nimport {\n ATTR_HTTP_RESPONSE_STATUS_CODE,\n ATTR_SERVER_ADDRESS,\n ATTR_SERVER_PORT,\n} from '@opentelemetry/semantic-conventions'\n\nexport const ATTR_DB_OPENSEARCH_DURATION_MS = 'db.opensearch.duration_ms'\n\nexport const extractResponseAttributes = (\n res: ApiResponse\n): Record<string, string | number | boolean> => {\n const attrs: Record<string, string | number | boolean> = {}\n\n const { hostname, port } = res.meta.connection.url\n attrs[ATTR_SERVER_ADDRESS] = hostname\n if (port) attrs[ATTR_SERVER_PORT] = Number(port)\n if (res.statusCode != null)\n attrs[ATTR_HTTP_RESPONSE_STATUS_CODE] = res.statusCode\n\n const body = res.body as Types.Core_Search.ResponseBody | null | undefined\n if (body == null) return attrs\n\n if (body.took != null) attrs['db.opensearch.took'] = body.took\n if (body.timed_out != null) attrs['db.opensearch.timed_out'] = body.timed_out\n if (body.terminated_early != null)\n attrs['db.opensearch.terminated_early'] = body.terminated_early\n\n const shards = body._shards\n if (shards != null) {\n attrs['db.opensearch.shards.total'] = shards.total\n attrs['db.opensearch.shards.successful'] = shards.successful\n attrs['db.opensearch.shards.failed'] = shards.failed\n if (shards.skipped != null)\n attrs['db.opensearch.shards.skipped'] = shards.skipped\n }\n\n const phaseTook = body.phase_took\n if (phaseTook != null) {\n attrs['db.opensearch.phase_took.can_match'] = phaseTook.can_match\n attrs['db.opensearch.phase_took.dfs_pre_query'] = phaseTook.dfs_pre_query\n attrs['db.opensearch.phase_took.dfs_query'] = phaseTook.dfs_query\n attrs['db.opensearch.phase_took.expand'] = phaseTook.expand\n attrs['db.opensearch.phase_took.fetch'] = phaseTook.fetch\n attrs['db.opensearch.phase_took.query'] = phaseTook.query\n }\n\n const total = body.hits?.total\n if (total != null && typeof total === 'object') {\n attrs['db.opensearch.hits.total'] = total.value\n }\n\n return attrs\n}\n","import type { TransportRequestParams } from '@opensearch-project/opensearch/lib/Transport.js'\nimport type { OpenSearchInstrumentationConfig } from './types'\n\nexport const serializeBody = (\n params: TransportRequestParams,\n config: Pick<OpenSearchInstrumentationConfig, 'dbStatementSerializer'>\n): string | undefined => {\n if (!params.body) return undefined\n if (config.dbStatementSerializer === false) return undefined\n if (typeof config.dbStatementSerializer === 'function') {\n return config.dbStatementSerializer(params)\n }\n return typeof params.body === 'string'\n ? params.body\n : JSON.stringify(params.body)\n}\n","import type Transport from '@opensearch-project/opensearch/lib/Transport.js'\nimport type {\n ApiError,\n ApiResponse,\n TransportRequestCallback,\n TransportRequestOptions,\n TransportRequestParams,\n TransportRequestPromise,\n} from '@opensearch-project/opensearch/lib/Transport.js'\nimport {\n context,\n SpanKind,\n SpanStatusCode,\n type Tracer,\n trace,\n} from '@opentelemetry/api'\nimport { suppressTracing } from '@opentelemetry/core'\nimport {\n ATTR_DB_COLLECTION_NAME,\n ATTR_DB_OPERATION_NAME,\n ATTR_DB_QUERY_TEXT,\n ATTR_DB_SYSTEM_NAME,\n} from '@opentelemetry/semantic-conventions'\nimport { parsePath } from './parse-path'\nimport {\n ATTR_DB_OPENSEARCH_DURATION_MS,\n extractResponseAttributes,\n} from './response-attributes'\nimport { serializeBody } from './serialize-body'\nimport type { OpenSearchInstrumentationConfig } from './types'\n\nexport type OriginalRequest = (\n this: Transport,\n params: TransportRequestParams,\n options?: TransportRequestOptions\n) => TransportRequestPromise<ApiResponse>\n\ntype OriginalRequestWithCallback = (\n this: Transport,\n params: TransportRequestParams,\n options: TransportRequestOptions | undefined,\n callback: (err: ApiError, result: ApiResponse) => void\n) => TransportRequestCallback\n\nexport const createPatchedRequest = (\n getTracer: () => Tracer,\n config: OpenSearchInstrumentationConfig = {},\n original: OriginalRequest,\n clientVersion: string\n) => {\n function patchedRequest(\n params: TransportRequestParams,\n options?: TransportRequestOptions\n ): TransportRequestPromise<ApiResponse>\n function patchedRequest(\n params: TransportRequestParams,\n options: TransportRequestOptions | undefined,\n callback: (err: ApiError, result: ApiResponse) => void\n ): TransportRequestCallback\n function patchedRequest(\n this: Transport,\n params: TransportRequestParams,\n options?: TransportRequestOptions,\n callback?: (err: ApiError, result: ApiResponse) => void\n ): TransportRequestPromise<ApiResponse> | TransportRequestCallback {\n const { index, operation } = parsePath(params.path, params.method)\n const queryText = serializeBody(params, config)\n\n const span = getTracer().startSpan(\n [operation, index].filter(Boolean).join(' ') || params.path,\n {\n kind: SpanKind.CLIENT,\n attributes: {\n [ATTR_DB_SYSTEM_NAME]: 'opensearch',\n ...(operation && { [ATTR_DB_OPERATION_NAME]: operation }),\n ...(index && { [ATTR_DB_COLLECTION_NAME]: index }),\n ...(queryText && { [ATTR_DB_QUERY_TEXT]: queryText }),\n },\n }\n )\n config.requestHook?.(span, params)\n\n const startTime = Date.now()\n\n const onSuccess = (res: ApiResponse) => {\n span.setAttribute(ATTR_DB_OPENSEARCH_DURATION_MS, Date.now() - startTime)\n for (const [key, value] of Object.entries(\n extractResponseAttributes(res)\n )) {\n span.setAttribute(key, value)\n }\n if (config.moduleVersionAttributeName) {\n span.setAttribute(config.moduleVersionAttributeName, clientVersion)\n }\n config.responseHook?.(span, res)\n span.end()\n }\n\n const onError = (err: unknown) => {\n span.setAttribute(ATTR_DB_OPENSEARCH_DURATION_MS, Date.now() - startTime)\n if (err instanceof Error) span.recordException(err)\n span.setStatus({ code: SpanStatusCode.ERROR })\n span.end()\n }\n\n const callCtx = config.suppressInternalInstrumentation\n ? suppressTracing(context.active())\n : trace.setSpan(context.active(), span)\n\n if (typeof callback === 'function') {\n const originalWithCallback = (\n original as OriginalRequestWithCallback\n ).bind(this)\n return context.with(callCtx, () =>\n originalWithCallback(params, options, (err, res) => {\n err ? onError(err) : onSuccess(res)\n callback(err, res)\n })\n )\n }\n\n const result = context.with(callCtx, () =>\n original.call(this, params, options)\n )\n const settled = result.then(\n (res: ApiResponse) => {\n onSuccess(res)\n return res\n },\n (err: unknown) => {\n onError(err)\n throw err\n }\n )\n return Object.assign(settled, { abort: result.abort })\n }\n\n return patchedRequest\n}\n","import Transport from '@opensearch-project/opensearch/lib/Transport.js'\nimport opensearchPkg from '@opensearch-project/opensearch/package.json' with {\n type: 'json',\n}\nimport { InstrumentationBase } from '@opentelemetry/instrumentation'\nimport pkg from '../package.json' with { type: 'json' }\nimport { createPatchedRequest, type OriginalRequest } from './patch-request'\nimport type { OpenSearchInstrumentationConfig } from './types'\n\nexport type { OpenSearchInstrumentationConfig } from './types'\n\nconst PACKAGE_NAME: string = pkg.name\nconst PACKAGE_VERSION: string = pkg.version\nconst OPENSEARCH_CLIENT_VERSION: string = opensearchPkg.version\n\nexport class OpenSearchInstrumentation extends InstrumentationBase {\n private readonly osConfig: OpenSearchInstrumentationConfig\n private _original: OriginalRequest | undefined\n\n constructor(config: OpenSearchInstrumentationConfig = {}) {\n super(PACKAGE_NAME, PACKAGE_VERSION, { ...config, enabled: false })\n this.osConfig = config\n if (config.enabled !== false) {\n this.enable()\n }\n }\n\n protected init() {}\n\n override enable() {\n if (this._original) return\n this._original = Transport.prototype.request as OriginalRequest\n Transport.prototype.request = createPatchedRequest(\n () => this.tracer,\n this.osConfig,\n this._original,\n OPENSEARCH_CLIENT_VERSION\n )\n }\n\n override disable() {\n if (this._original) {\n Transport.prototype.request = this._original\n this._original = undefined\n }\n }\n}\n"],"mappings":";;;;;;;;;;ACAA,MAAM,oBAA4C;CAChD,KAAK;CACL,QAAQ;AACV;AAEA,MAAM,oBAA4C,EAChD,KAAK,QACP;AAEA,MAAa,aACX,MACA,WAC2C;CAC3C,MAAM,UAAU,mBAAmB,IAAI;CACvC,MAAM,QAAQ,QAAQ,MAAM,gCAAgC;CAC5D,IAAI,OAAO;EACT,MAAM,YAAY,kBAAkB,MAAM,OAAO,MAAM;EACvD,OAAO;GAAE,OAAO,MAAM;GAAI;EAAU;CACtC;CAEA,IAAI,QAAQ;EACV,MAAM,YAAY,kBAAkB,OAAO,YAAY;EACvD,IAAI,WAEF,OAAO;GAAE,OADK,QAAQ,QAAQ,OAAO,EAAE,KAAK,KAAA;GAC5B;EAAU;CAE9B;CAEA,OAAO,CAAC;AACV;;ACrBA,MAAa,iCAAiC;AAE9C,MAAa,6BACX,QAC8C;CAC9C,MAAM,QAAmD,CAAC;CAE1D,MAAM,EAAE,UAAU,SAAS,IAAI,KAAK,WAAW;CAC/C,MAAM,uBAAuB;CAC7B,IAAI,MAAM,MAAM,oBAAoB,OAAO,IAAI;CAC/C,IAAI,IAAI,cAAc,MACpB,MAAM,kCAAkC,IAAI;CAE9C,MAAM,OAAO,IAAI;CACjB,IAAI,QAAQ,MAAM,OAAO;CAEzB,IAAI,KAAK,QAAQ,MAAM,MAAM,wBAAwB,KAAK;CAC1D,IAAI,KAAK,aAAa,MAAM,MAAM,6BAA6B,KAAK;CACpE,IAAI,KAAK,oBAAoB,MAC3B,MAAM,oCAAoC,KAAK;CAEjD,MAAM,SAAS,KAAK;CACpB,IAAI,UAAU,MAAM;EAClB,MAAM,gCAAgC,OAAO;EAC7C,MAAM,qCAAqC,OAAO;EAClD,MAAM,iCAAiC,OAAO;EAC9C,IAAI,OAAO,WAAW,MACpB,MAAM,kCAAkC,OAAO;CACnD;CAEA,MAAM,YAAY,KAAK;CACvB,IAAI,aAAa,MAAM;EACrB,MAAM,wCAAwC,UAAU;EACxD,MAAM,4CAA4C,UAAU;EAC5D,MAAM,wCAAwC,UAAU;EACxD,MAAM,qCAAqC,UAAU;EACrD,MAAM,oCAAoC,UAAU;EACpD,MAAM,oCAAoC,UAAU;CACtD;CAEA,MAAM,QAAQ,KAAK,MAAM;CACzB,IAAI,SAAS,QAAQ,OAAO,UAAU,UACpC,MAAM,8BAA8B,MAAM;CAG5C,OAAO;AACT;;ACnDA,MAAa,iBACX,QACA,WACuB;CACvB,IAAI,CAAC,OAAO,MAAM,OAAO,KAAA;CACzB,IAAI,OAAO,0BAA0B,OAAO,OAAO,KAAA;CACnD,IAAI,OAAO,OAAO,0BAA0B,YAC1C,OAAO,OAAO,sBAAsB,MAAM;CAE5C,OAAO,OAAO,OAAO,SAAS,WAC1B,OAAO,OACP,KAAK,UAAU,OAAO,IAAI;AAChC;;AC6BA,MAAa,wBACX,WACA,SAA0C,CAAC,GAC3C,UACA,kBACG;CAUH,SAAS,eAEP,QACA,SACA,UACiE;EACjE,MAAM,EAAE,OAAO,cAAc,UAAU,OAAO,MAAM,OAAO,MAAM;EACjE,MAAM,YAAY,cAAc,QAAQ,MAAM;EAE9C,MAAM,OAAO,UAAU,CAAC,CAAC,UACvB,CAAC,WAAW,KAAK,CAAC,CAAC,OAAO,OAAO,CAAC,CAAC,KAAK,GAAG,KAAK,OAAO,MACvD;GACE,MAAM,SAAS;GACf,YAAY;KACT,sBAAsB;IACvB,GAAI,aAAa,GAAG,yBAAyB,UAAU;IACvD,GAAI,SAAS,GAAG,0BAA0B,MAAM;IAChD,GAAI,aAAa,GAAG,qBAAqB,UAAU;GACrD;EACF,CACF;EACA,OAAO,cAAc,MAAM,MAAM;EAEjC,MAAM,YAAY,KAAK,IAAI;EAE3B,MAAM,aAAa,QAAqB;GACtC,KAAK,aAAa,gCAAgC,KAAK,IAAI,IAAI,SAAS;GACxE,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAChC,0BAA0B,GAAG,CAC/B,GACE,KAAK,aAAa,KAAK,KAAK;GAE9B,IAAI,OAAO,4BACT,KAAK,aAAa,OAAO,4BAA4B,aAAa;GAEpE,OAAO,eAAe,MAAM,GAAG;GAC/B,KAAK,IAAI;EACX;EAEA,MAAM,WAAW,QAAiB;GAChC,KAAK,aAAa,gCAAgC,KAAK,IAAI,IAAI,SAAS;GACxE,IAAI,eAAe,OAAO,KAAK,gBAAgB,GAAG;GAClD,KAAK,UAAU,EAAE,MAAM,eAAe,MAAM,CAAC;GAC7C,KAAK,IAAI;EACX;EAEA,MAAM,UAAU,OAAO,kCACnB,gBAAgB,QAAQ,OAAO,CAAC,IAChC,MAAM,QAAQ,QAAQ,OAAO,GAAG,IAAI;EAExC,IAAI,OAAO,aAAa,YAAY;GAClC,MAAM,uBACJ,SACA,KAAK,IAAI;GACX,OAAO,QAAQ,KAAK,eAClB,qBAAqB,QAAQ,UAAU,KAAK,QAAQ;IAClD,MAAM,QAAQ,GAAG,IAAI,UAAU,GAAG;IAClC,SAAS,KAAK,GAAG;GACnB,CAAC,CACH;EACF;EAEA,MAAM,SAAS,QAAQ,KAAK,eAC1B,SAAS,KAAK,MAAM,QAAQ,OAAO,CACrC;EACA,MAAM,UAAU,OAAO,MACpB,QAAqB;GACpB,UAAU,GAAG;GACb,OAAO;EACT,IACC,QAAiB;GAChB,QAAQ,GAAG;GACX,MAAM;EACR,CACF;EACA,OAAO,OAAO,OAAO,SAAS,EAAE,OAAO,OAAO,MAAM,CAAC;CACvD;CAEA,OAAO;AACT;;AC/HA,MAAM,eAAuBA;AAC7B,MAAM,kBAA0BC;AAChC,MAAM,4BAAoC,cAAc;AAExD,IAAa,4BAAb,cAA+C,oBAAoB;CACjE;CACA;CAEA,YAAY,SAA0C,CAAC,GAAG;EACxD,MAAM,cAAc,iBAAiB;GAAE,GAAG;GAAQ,SAAS;EAAM,CAAC;EAClE,KAAK,WAAW;EAChB,IAAI,OAAO,YAAY,OACrB,KAAK,OAAO;CAEhB;CAEA,OAAiB,CAAC;CAElB,SAAkB;EAChB,IAAI,KAAK,WAAW;EACpB,KAAK,YAAY,UAAU,UAAU;EACrC,UAAU,UAAU,UAAU,2BACtB,KAAK,QACX,KAAK,UACL,KAAK,WACL,yBACF;CACF;CAEA,UAAmB;EACjB,IAAI,KAAK,WAAW;GAClB,UAAU,UAAU,UAAU,KAAK;GACnC,KAAK,YAAY,KAAA;EACnB;CACF;AACF"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sebspark/opentelemetry-instrumentation-opensearch",
3
- "version": "0.3.15",
3
+ "version": "0.4.0",
4
4
  "license": "Apache-2.0",
5
5
  "type": "module",
6
6
  "main": "dist/index.mjs",
@@ -18,35 +18,32 @@
18
18
  "build": "spark-build src/index.ts",
19
19
  "dev": "tsc --watch --noEmit",
20
20
  "lint": "biome check .",
21
- "test": "vitest run --passWithNoTests --coverage",
22
- "test:e2e": "vitest --config vitest.config.e2e.ts --run",
21
+ "test": "vitest run --passWithNoTests --coverage --fsModuleCachePath node_modules/.vitest-cache",
22
+ "test:e2e": "vitest --config vitest.config.e2e.ts --run --fsModuleCachePath node_modules/.vitest-cache",
23
23
  "typecheck": "vitest --typecheck.only --passWithNoTests --run"
24
24
  },
25
25
  "peerDependencies": {
26
26
  "@opensearch-project/opensearch": ">=2",
27
- "@opentelemetry/api": ">=1.9.0"
27
+ "@opentelemetry/api": ">=1.10.0 <1.11.0"
28
28
  },
29
29
  "dependencies": {
30
- "@opentelemetry/core": "2.11.0",
31
- "@opentelemetry/instrumentation": "0.222.0",
30
+ "@opentelemetry/core": "3.0.0",
31
+ "@opentelemetry/instrumentation": "0.300.0",
32
32
  "@opentelemetry/semantic-conventions": "1.43.0"
33
33
  },
34
34
  "devDependencies": {
35
- "@biomejs/biome": "2.5.14",
36
- "@opensearch-project/opensearch": "3.6.0",
37
- "@opentelemetry/api": "1.9.1",
38
- "@opentelemetry/instrumentation-http": "0.222.0",
39
- "@opentelemetry/instrumentation-undici": "0.32.0",
40
- "@opentelemetry/sdk-trace-base": "2.11.0",
41
- "@opentelemetry/sdk-trace-node": "2.11.0",
42
- "@sebspark/tsconfig": "*",
43
- "@testcontainers/opensearch": "12.1.0",
35
+ "@biomejs/biome": "2.6.3",
36
+ "@opensearch-project/opensearch": "3.9.0",
37
+ "@opentelemetry/api": "1.10.0",
38
+ "@opentelemetry/context-async-hooks": "3.0.0",
39
+ "@opentelemetry/instrumentation-http": "0.300.0",
40
+ "@opentelemetry/instrumentation-undici": "0.34.0",
41
+ "@opentelemetry/sdk-trace": "3.0.0",
42
+ "@sebspark/tsconfig": "3.0.26",
43
+ "@testcontainers/opensearch": "12.2.1",
44
44
  "typescript": "7.0.2",
45
- "vite": "8.3.0",
46
- "vitest": "5.0.1"
47
- },
48
- "resolutions": {
49
- "protobufjs": "8.8.0"
45
+ "vite": "8.3.5",
46
+ "vitest": "5.0.5"
50
47
  },
51
48
  "repository": {
52
49
  "type": "git",