{"_id":"@okfetch/otel","_rev":"3-2d22978afcb91fc159674a0bd88a4e9d","name":"@okfetch/otel","dist-tags":{"latest":"0.6.1"},"versions":{"0.5.0":{"name":"@okfetch/otel","version":"0.5.0","keywords":["fetch","opentelemetry","otel","plugin","tracing","typescript"],"license":"MIT","_id":"@okfetch/otel@0.5.0","maintainers":[{"name":"aldotestino","email":"aldotestino4@gmail.com"}],"homepage":"https://github.com/aldotestino/okfetch#readme","bugs":{"url":"https://github.com/aldotestino/okfetch/issues"},"dist":{"shasum":"aa52f27a917adb86c306c690c8c0f81e701c651c","tarball":"https://registry.npmjs.org/@okfetch/otel/-/otel-0.5.0.tgz","fileCount":8,"integrity":"sha512-jr7L+LIYYT0Jc9BVaQ8EmS5n2Q9dtfdDNd1coSO3dRnyZf3JCEa3M8QlkGgxnWGZGeMktHDTeB2tVuoMn8qKwg==","signatures":[{"sig":"MEYCIQCNdT7M1jXxetdHIx+H4VxYk5v7JF09mkUNaBiKscZraQIhANH/1OCuw333ipTkDDkEcZgub81n+kDHKRddBKUoW4El","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":101001},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs","require":"./dist/index.cjs"}},"gitHead":"63360501f0b6d146da89416e549d2eaeb1d6c59e","_npmUser":{"name":"aldotestino","email":"aldotestino4@gmail.com"},"repository":{"url":"git+https://github.com/aldotestino/okfetch.git","type":"git"},"_npmVersion":"11.3.0","description":"An OpenTelemetry tracing plugin for okfetch request lifecycles.","directories":{},"sideEffects":false,"_nodeVersion":"24.2.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest","better-result":"^3.0.1","@okfetch/fetch":"^0.5.0","@opentelemetry/api":"^1.9.0","@opentelemetry/core":"^2.0.0","@opentelemetry/sdk-trace-base":"^2.0.0","@opentelemetry/context-async-hooks":"^2.0.0"},"peerDependencies":{"@okfetch/fetch":"^0.5.0","@opentelemetry/api":"^1.9.0"},"_npmOperationalInternal":{"tmp":"tmp/otel_0.5.0_1788422729953_0.47943921054461214","host":"s3://npm-registry-packages-npm-production"}},"0.6.0":{"name":"@okfetch/otel","version":"0.6.0","keywords":["fetch","opentelemetry","otel","plugin","tracing","typescript"],"license":"MIT","_id":"@okfetch/otel@0.6.0","maintainers":[{"name":"aldotestino","email":"aldotestino4@gmail.com"}],"homepage":"https://github.com/aldotestino/okfetch#readme","bugs":{"url":"https://github.com/aldotestino/okfetch/issues"},"dist":{"shasum":"aa02e48ffdf8b5e9dbf4005a99e241b2f6bd4205","tarball":"https://registry.npmjs.org/@okfetch/otel/-/otel-0.6.0.tgz","fileCount":8,"integrity":"sha512-ehjfLh8wqZsXRW+K/vBr6Ft0d+DqlMx5IbBiA8WpGIWkFb+3R7vnKBeUzvANcoGmaSt6HxV5WQH36GywEfUtOQ==","signatures":[{"sig":"MEQCIBZIb19Eqvn/aa7/6c43uhi2SMsb9jA8TH/kQnLxea2YAiA3X8F6NytmSNUC2XXLDkN5xZQhrAhqyp9IMt92uxSlaw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@okfetch%2fotel@0.6.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":101001},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs","require":"./dist/index.cjs"}},"gitHead":"843e04f26b3f3f9627af480f92dbe90fb2800adc","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:504a71e9-c51b-4d29-a7ff-4d9ab7aa4a65"}},"repository":{"url":"git+https://github.com/aldotestino/okfetch.git","type":"git"},"_npmVersion":"12.0.2","description":"An OpenTelemetry tracing plugin for okfetch request lifecycles.","directories":{},"sideEffects":false,"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest","better-result":"^3.0.1","@okfetch/fetch":"^0.6.0","@opentelemetry/api":"^1.9.0","@opentelemetry/core":"^2.0.0","@opentelemetry/sdk-trace-base":"^2.0.0","@opentelemetry/context-async-hooks":"^2.0.0"},"peerDependencies":{"@okfetch/fetch":"^0.6.0","@opentelemetry/api":"^1.9.0"},"_npmOperationalInternal":{"tmp":"tmp/otel_0.6.0_1788794389072_0.7077995879417183","host":"s3://npm-registry-packages-npm-production"}},"0.6.1":{"_id":"@okfetch/otel@0.6.1","bugs":{"url":"https://github.com/aldotestino/okfetch/issues"},"dist":{"shasum":"f34c24ccbd46689b62cedd8aeb625b0d43f3e4c4","tarball":"https://registry.npmjs.org/@okfetch/otel/-/otel-0.6.1.tgz","fileCount":8,"integrity":"sha512-SHxViXnCJqrOFizimDU6u6aloBe4tS4c68O1cbV2lAqCQtjNGpWFh6YsFbr6AhBbhMypCZJpTbMxmr8EQmSw8A==","signatures":[{"sig":"MEUCICmWHroJ+Edn1fRfeQkKrfzSPHrEL3RMwh8Tf/wTtztcAiEAwmAruvkp1kmxmOAfmjVnhTzToTnBRAyPOUEfdfhp0X0=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC2KjaZe4OIsTxQd/ZV8hK6rWghs/XI6tH3ULk4C520xgIhAJIe5wXtfcObIK+R5JvYbrgFGhcPp7DB85CPdF/ozhpU"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@okfetch%2fotel@0.6.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":101001},"main":"./dist/index.cjs","name":"@okfetch/otel","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.mts","import":"./dist/index.mjs","default":"./dist/index.mjs","require":"./dist/index.cjs"}},"gitHead":"e21d57170cb1600242c034dc72d4d2016410fe9a","license":"MIT","version":"0.6.1","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:504a71e9-c51b-4d29-a7ff-4d9ab7aa4a65"}},"homepage":"https://github.com/aldotestino/okfetch#readme","keywords":["fetch","opentelemetry","otel","plugin","tracing","typescript"],"repository":{"url":"git+https://github.com/aldotestino/okfetch.git","type":"git"},"_npmVersion":"12.0.2","description":"An OpenTelemetry tracing plugin for okfetch request lifecycles.","directories":{},"maintainers":[{"name":"aldotestino","email":"aldotestino4@gmail.com"}],"sideEffects":false,"_nodeVersion":"24.20.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest","better-result":"^3.0.1","@okfetch/fetch":"^0.6.1","@opentelemetry/api":"^1.9.0","@opentelemetry/core":"^2.0.0","@opentelemetry/sdk-trace-base":"^2.0.0","@opentelemetry/context-async-hooks":"^2.0.0"},"peerDependencies":{"@okfetch/fetch":"^0.6.1","@opentelemetry/api":"^1.9.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/otel_0.6.1_1790074088348_0.29882443635441613"}}},"time":{"created":"2026-09-03T08:05:29.738Z","modified":"2026-09-22T10:48:08.836Z","0.5.0":"2026-09-03T08:05:30.079Z","0.6.0":"2026-09-07T15:19:49.218Z","0.6.1":"2026-09-22T10:48:08.438Z"},"bugs":{"url":"https://github.com/aldotestino/okfetch/issues"},"license":"MIT","homepage":"https://github.com/aldotestino/okfetch#readme","keywords":["fetch","opentelemetry","otel","plugin","tracing","typescript"],"repository":{"url":"git+https://github.com/aldotestino/okfetch.git","type":"git"},"description":"An OpenTelemetry tracing plugin for okfetch request lifecycles.","maintainers":[{"name":"aldotestino","email":"aldotestino4@gmail.com"}],"readme":"# @okfetch/otel\n\n`@okfetch/otel` is an [OpenTelemetry](https://opentelemetry.io/) tracing plugin for okfetch request lifecycles.\n\nIt gives you a ready-made `OkfetchPlugin` that records **one `CLIENT` span per request**, covering every retry attempt, with:\n\n- the request method, URL, path, and query string\n- explicitly selected request and response headers, with sensitive values redacted\n- the response status code\n- optional request and response body sizes when they can be observed accurately\n- a `traceparent` header on the outgoing request so downstream services join the trace\n\nRequest and response bodies are never recorded.\n\n## Installation\n\n```bash\nbun add @okfetch/otel @okfetch/fetch @opentelemetry/api\n```\n\n```bash\nnpm install @okfetch/otel @okfetch/fetch @opentelemetry/api\n```\n\nYou also need an OpenTelemetry SDK registered as the global tracer provider (for example `@opentelemetry/sdk-node`). Without one, the plugin is a no-op.\n\n## Usage\n\n```ts\nimport { okfetch } from \"@okfetch/fetch\";\nimport { otel } from \"@okfetch/otel\";\n\nconst result = await okfetch(\"https://api.example.com/todos/:id\", {\n  params: { id: 1 },\n  plugins: [otel()],\n  query: { include: \"owner\" },\n});\n```\n\nPut `otel()` after plugins that add headers if you want those headers captured on the span. Header capture is opt-in, as required by the OpenTelemetry security guidance.\n\n## API\n\n`otel(options?)`\n\nOptions:\n\n- `tracer?: Tracer` - tracer used to start spans. Defaults to `trace.getTracer(\"@okfetch/otel\")` from the global provider.\n- `captureRequestHeaders?: boolean | readonly string[]` - request header names to record as `http.request.header.<name>`. Defaults to none. Pass `true` to explicitly capture every request header.\n- `captureResponseHeaders?: boolean | readonly string[]` - response header names to record as `http.response.header.<name>`. Defaults to none. Pass `true` to explicitly capture every response header.\n- `captureBodySizes?: boolean` - record payload body sizes when Fetch exposes enough information to do so accurately. Defaults to `false`.\n- `knownMethods?: readonly string[]` - case-sensitive methods known to the instrumentation. Replaces `DEFAULT_KNOWN_HTTP_METHODS` entirely.\n- `propagateTraceContext?: boolean` - inject W3C `traceparent` / `tracestate` headers into the request. Defaults to `true`.\n- `redact?: { headers?, queryParams?, values? }` - what to redact. `headers` and `queryParams` match names; `values` matches header and query values regardless of name. Each entry is either an array that **replaces** the defaults, or a function that **receives the defaults** and returns the list to use.\n\n```ts\notel({\n  captureRequestHeaders: [\"content-type\", \"x-tenant\"],\n  captureResponseHeaders: [\"content-type\", \"x-request-id\"],\n  redact: {\n    // extend the defaults\n    headers: (defaults) => [...defaults, \"x-tenant\", /^x-internal-/i],\n    // replace the defaults entirely\n    queryParams: [\"customer_id\"],\n    // also redact any value that looks like an internal ticket id\n    values: (defaults) => [...defaults, /^TKT-/],\n  },\n});\n```\n\nExports:\n\n- `DEFAULT_REDACTED_HEADERS` - `authorization`, `proxy-authorization`, `cookie`, `set-cookie`, `x-api-key`, `x-auth-token`, `api-key`, `x-amz-security-token`, `x-amz-credential`, `x-amz-signature`, plus `DEFAULT_REDACTED_NAME_PATTERN`\n- `DEFAULT_KNOWN_HTTP_METHODS` - the RFC 9110 methods plus `PATCH` and `QUERY`\n- `DEFAULT_REDACTED_QUERY_PARAMS` - common credential parameter names such as `token`, `access_token`, `api_key`, `password`, `secret`, `signature`, the OAuth grant parameters `code`, `code_verifier`, `client_assertion`, `assertion`, the AWS SigV4 presigned-URL fields `X-Amz-Credential`, `X-Amz-Security-Token`, `X-Amz-Signature`, plus `DEFAULT_REDACTED_NAME_PATTERN`\n- `DEFAULT_REDACTED_NAME_PATTERN` - a pattern included in both default lists; any name containing `auth`, `bearer`, `cred`, `jwt`, `otp`, `passw`, `private`, `secret`, `session`, `sig`, `token`, or `api-key` is redacted even when not listed explicitly. Replacing a list with an array drops it, so include it yourself if you still want it.\n- `DEFAULT_REDACTED_VALUE_PATTERNS` - patterns applied to every header and query value whatever its name: JWTs (`eyJ...` with three segments) and HTTP authentication credentials (`Bearer`, `Basic`, `Digest`, `Negotiate`, `Token`, `OAuth`, `AWS4-HMAC-SHA256` prefixes)\n- `RedactionMatcher`, `RedactionList`, `RedactionOption`, `ValuePatternList`, `ValuePatternOption` - the types behind the `redact` option\n- `HeaderCaptureOption` - the type accepted by the request and response header capture options\n- `REDACTED_VALUE` - the `REDACTED` placeholder written in place of redacted values\n\nName matching is case-insensitive for both headers and query parameters. Redaction errs on the side of hiding too much: a name such as `X-Session-Id` is redacted because it matches the default pattern, and a JWT sent under a harmless-looking name is redacted because of its value.\n\n## What It Records\n\nSpan name: `{method}`, or `{method} {path template}` when the request uses `params` (for example `GET /todos/:id`).\n\nAttributes follow the OpenTelemetry HTTP semantic conventions where one exists:\n\n| Attribute                      | Value                                                                        |\n| ------------------------------ | ---------------------------------------------------------------------------- |\n| `http.request.method`          | Known request method, or `_OTHER`                                            |\n| `http.request.method_original` | Original method when `http.request.method` is `_OTHER`                       |\n| `http.request.body.size`       | Request payload bytes, when enabled and accurately observable                |\n| `http.request.header.<name>`   | Explicitly selected request header values, with sensitive values redacted    |\n| `http.request.resend_count`    | Number of retries performed                                                  |\n| `http.response.body.size`      | Response payload bytes from `Content-Length`, when enabled and applicable    |\n| `http.response.header.<name>`  | Explicitly selected response header values, with sensitive values redacted   |\n| `http.response.status_code`    | Status code of the final response                                            |\n| `url.full`                     | Full URL with redacted query parameters and credentials, fragment dropped    |\n| `url.scheme`                   | URL scheme                                                                   |\n| `url.path`                     | URL path                                                                     |\n| `url.query`                    | Query string with redacted parameters (omitted when empty)                   |\n| `url.template`                 | Path template when `params` are used, without query, fragment or credentials |\n| `server.address`               | Hostname                                                                     |\n| `server.port`                  | Explicit or scheme-default server port                                       |\n| `error.type`                   | Status code for API errors, otherwise the okfetch error tag                  |\n| `okfetch.error.tag`            | okfetch error tag (`ApiError`, `FetchError`, ...)                            |\n| `okfetch.validation.issues`    | Formatted schema issues for validation failures                              |\n\nFailure handling:\n\n- `ApiError` (non-2xx): span status `ERROR`; `http.response.status_code` carries the reason, so no redundant status description is set\n- `FetchError`, `TimeoutError`, `ParseError`, `PluginError`: span status `ERROR` with the error message, plus an `exception` event via `span.recordException`\n- `ValidationError`: the same failure details, with formatted schema issues added to the status message, exception message and `okfetch.validation.issues`\n\nEvery retry adds an `okfetch.retry` event carrying the attempt number, the error tag, and the status code when a response was received.\n\n### HTTP registry coverage\n\nThe plugin emits every HTTP registry attribute that applies to a Fetch client and can be observed accurately. `http.connection.state` belongs to connection-pool metrics, and `http.route` belongs to server spans, so neither applies. Fetch does not expose protocol framing or total bytes on the wire, so `http.request.size` and `http.response.size` are intentionally omitted rather than estimated. Response body size is omitted for `HEAD`, `204`, and `304` responses and whenever no valid `Content-Length` is available. Deprecated HTTP attributes are never emitted.\n\n## Relationship To `@okfetch/fetch`\n\nThis package is just a plugin built on top of the public `OkfetchPlugin` interface from `@okfetch/fetch`. It only depends on `@opentelemetry/api`, so it works with any OpenTelemetry SDK setup.\n","readmeFilename":"README.md"}