---
title: "@unikvs/tracing"
description: "Middleware that emits a trace span per operation."
---

## Overview [#overview]

`Tracing` emits a trace span for each read, write, and conversion operation and records success. `use`, `encode`, and `decode` spans measure hook-chain duration; stream spans run until the stream is fully consumed, fails, or is cancelled, and can include stream consumption or storage read time.Middleware

Use it for distributed tracing and performance analysis. Pass a structurally OpenTelemetry-compatible tracer.

- `name` is `Tracing`.
- `isOpen` is always `true`.
- Spans carry `key`, `action`, `success`, and `durationMs` as attributes.
- `encode` / `decode` and streams pass data through and only emit spans.

Install with:

```package-install
npm install @unikvs/tracing
```

## Usage [#usage]

Tracing implements IMiddleware. Pass it to UniKvs with use().

```ts
import { Tracing } from "@unikvs/tracing";
```

Constructor arguments:

| Prop | Type | Default | Description |
| - | - | - | - |
| `tracer?` | `[#tracing-options-tracer] TracerLike` | - | Tracer that emits spans. When omitted, nothing is recorded. |
| `spanNamePrefix?` | `[#tracing-options-span-name-prefix] string` | `"unikvs."` | Prefix prepended to span names. |

The following records operations with a custom tracer:

```ts
import { Memory } from "@unikvs/memory";
import { Tracing, type TracerLike } from "@unikvs/tracing";
import * as unikvs from "unikvs";

const tracer: TracerLike = {
  startSpan: (name) => ({
    setAttribute: () => {},
    setStatus: () => {},
    end: () => {},
  }),
};

const kvs = new unikvs.Builder<{ k1: unikvs.PlainValue<string> }>()
  .use(new Tracing({ tracer }))
  .persist(new Memory())
  .build();

await kvs.open();
await kvs.set("k1", "hello");
console.log(await kvs.get("k1")); // "hello"
await kvs.close();
```

### `Tracing` [#tracing]

Middleware that emits a trace span per operation. `use` emits one span per operation; `encode` / `decode` and streams emit one span per conversion.

### `TracingOptions` [#tracing-options]

Options accepted by the `Tracing` constructor. Specifies the tracer and the span-name prefix.

### `SpanStatusCode` [#span-status-code]

Span status code. One of `"unset"`, `"ok"`, or `"error"`.

### `SpanStatus` [#span-status]

Status set on a span.

| Prop | Type | Default | Description |
| - | - | - | - |
| `code` | `[#span-status-code-prop] SpanStatusCode` | - | Span status code. |
| `message?` | `[#span-status-message] string` | - | Message attached to the status. |

### `SpanAttributeValue` [#span-attribute-value]

Value type settable as a span attribute. One of `string`, `number`, or `boolean`.

### `SpanLike` [#span-like]

Minimal interface of spans issued by a tracer. Structurally compatible with OpenTelemetry Span.

### `TracerLike` [#tracer-like]

Minimal interface of tracers that emit spans. Structurally compatible with OpenTelemetry Tracer.

## Data types [#data-types]

| Method         | Input             | Output                         |
| -------------- | ----------------- | ------------------------------ |
| `encode`       | `unknown`         | `unknown` (passthrough)        |
| `decode`       | `unknown`         | `unknown` (passthrough)        |
| `encodeStream` | `unknown` (chunk) | `unknown` (chunk, passthrough) |
| `decodeStream` | `unknown` (chunk) | `unknown` (chunk, passthrough) |

- `use` wraps the downstream `use` hook chain in a `unikvs.use.<action>` span; storage I/O is not included. `encode` uses `unikvs.encode` and `decode` uses `unikvs.decode`.
- Streams are wrapped in `unikvs.encodeStream` / `unikvs.decodeStream` spans, ending on full read, error, or cancellation.
- Chunks pass through unchanged, preserving order and references.
- Success sets `success` to `true` with status `ok`; failure sets `success` to `false` with status `error` and a message.

## Errors [#errors]

This package has no package-specific errors.

Span emission itself never throws. When an operation fails, this middleware marks the status `error` and rethrows the original error. When no tracer is given, operations pass through with nothing recorded.
