> ## Documentation Index
> Fetch the complete documentation index at: https://langwatch.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Filtering Spans in TypeScript

> Filter which spans are exported to LangWatch using presets or explicit criteria.

You don’t need every span. Filter out the noise and ship the useful bits. LangWatch lets you keep AI and business spans while dropping framework chatter.

<Info>
  Introduced in `langwatch@0.8.0`.
</Info>

## Defaults

By default we exclude HTTP request spans.

<CodeGroup>
  ```typescript With setupObservability theme={null}
  import { setupObservability } from "langwatch/observability/node";
  import { LangWatchTraceExporter } from "langwatch";

  setupObservability({
    // We are specifying a custom trace exporter, so we need to disable default
    // integration to prevent double exporting
    langwatch: "disabled",
    traceExporter: new LangWatchTraceExporter(),
  });
  ```

  ```typescript Creating an exporter theme={null}
  import { LangWatchTraceExporter } from "langwatch";

  // Default: excludes HTTP request spans
  const exporter = new LangWatchTraceExporter();
  ```
</CodeGroup>

<Note>
  Default is equivalent to `{ filters: [{ preset: "excludeHttpRequests" }] }`. You can set `filters: null` or `filters: []` to send all spans.
</Note>

## Quick start

<CodeGroup>
  ```typescript Disable filtering theme={null}
  new LangWatchTraceExporter({ filters: [] });
  ```

  ```typescript Only Vercel AI spans theme={null}
  new LangWatchTraceExporter({ filters: [{ preset: "vercelAIOnly" }] });
  ```

  ```typescript Explicit default theme={null}
  new LangWatchTraceExporter({ filters: [{ preset: "excludeHttpRequests" }] });
  ```
</CodeGroup>

## Custom filters

Use `include` to keep matches; use `exclude` to drop matches. Criteria support:

* `instrumentationScopeName`
* `name`

```typescript theme={null}
// Keep only spans from the 'ai' scope
new LangWatchTraceExporter({
  filters: [{ include: { instrumentationScopeName: [{ equals: "ai" }] } }]
});

// Drop internal spans by name prefix
new LangWatchTraceExporter({
  filters: [{ exclude: { name: [{ startsWith: "internal." }] } }]
});
```

## Matching

Matchers are case-sensitive unless you set `ignoreCase: true`.

```typescript theme={null}
// equals (exact)
{ name: [{ equals: "chat.completion" }] }

// startsWith (prefix)
{ name: [{ startsWith: "chat." }] }

// matches (RegExp)
{ name: [{ matches: /^(GET|POST)\b/ }] }

// case-insensitive
{ name: [{ equals: "Chat.Completion", ignoreCase: true }] }
```

## Logic

* OR within a field: multiple matchers are alternatives
* AND across fields: all specified fields must match

```typescript theme={null}
// name starts with chat. OR llm.
{ include: { name: [{ startsWith: "chat." }, { startsWith: "llm." }] } }

// scope is ai AND name starts with chat.
{ include: { instrumentationScopeName: [{ equals: "ai" }], name: [{ startsWith: "chat." }] } }
```

## Pipelines (sequential AND)

Filters run in order; each step narrows the set.

```typescript theme={null}
new LangWatchTraceExporter({
  filters: [
    { include: { instrumentationScopeName: [{ equals: "ai" }] } },
    { preset: "excludeHttpRequests" },
    { exclude: { name: [{ matches: /test/ }] } }
  ]
});
```

## Integrate with setupObservability

```typescript theme={null}
import { setupObservability } from "langwatch/observability/node";
import { LangWatchTraceExporter } from "langwatch";

setupObservability({
  // We are specifying a custom trace exporter, so we need to disable default
  // integration to prevent double exporting
  langwatch: "disabled",
  traceExporter: new LangWatchTraceExporter({
    filters: [{ preset: "excludeHttpRequests" }]
  })
});
```

```typescript Via BatchSpanProcessor theme={null}
import { setupObservability } from "langwatch/observability/node";
import { BatchSpanProcessor } from "@opentelemetry/sdk-trace-base";
import { LangWatchTraceExporter } from "langwatch";

setupObservability({
  // We are specifying a custom trace exporter, so we need to disable default
  // integration to prevent double exporting
  langwatch: "disabled",
  spanProcessors: [
    new BatchSpanProcessor(
      new LangWatchTraceExporter({ filters: [{ preset: "vercelAIOnly" }] })
    ),
  ],
});
```

## Troubleshooting

* Nothing exported: try `filters: []`, then add rules back
* Too much noise: apply `excludeHttpRequests`, add specific `exclude` rules
* Case surprises: add `ignoreCase: true` where needed
* Check values: log `span.name` and `span.instrumentationScope.name` in dev

## Types

```typescript theme={null}
import type { TraceFilter, Criteria, Match } from "langwatch";
```

<Tip>
  Use simple matchers (`equals`, `startsWith`) where possible; regex is powerful but slower and harder to read.
</Tip>
