← Files HoneycombARCHIVED FILE

references/local-collector-debug-test.md

3.42 KB · Sep 30, 2026 · 22:51 UTC

↓ Download file

# Local OTel Collector for Migration Verification

Running a local OTel Collector during migration lets you verify that spans are being
produced and structured correctly without needing a live Honeycomb account or sending
data to a remote backend. Useful for the early phases of migration (SDK init, middleware,
context propagation) where you just need to confirm telemetry is flowing.

The skill ships a script at `${CLAUDE_PLUGIN_ROOT}/scripts/start-collector.sh` that starts
the collector via Docker with a pre-built config.

## Starting the Collector

**Without Honeycomb (local verification only):**

```bash
./scripts/start-collector.sh --no-honeycomb
```

No API key required. Spans are printed to stdout and written to `./otelcol-spans.ndjson`.

**With Honeycomb (verify locally and forward to backend):**

```bash
./scripts/start-collector.sh --api-key YOUR_API_KEY
# or
HONEYCOMB_API_KEY=YOUR_API_KEY ./scripts/start-collector.sh
```

**Custom log file location:**

```bash
./scripts/start-collector.sh --no-honeycomb --log-file /tmp/my-service-spans.ndjson
```

**Custom collector config (bypasses all default flags):**

```bash
./scripts/start-collector.sh --config ./my-collector-config.yaml
```

The collector listens on `localhost:4317` (gRPC) and `localhost:4318` (HTTP). Point your
SDK at either:

```bash
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4318  # HTTP
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:4317  # gRPC
```

## Reading the Debug Output

The `debug` exporter prints a human-readable block for each span to stdout as it arrives.
Key fields to check during migration:

```
ResourceSpans #0
Resource attributes:
     -> service.name: Str(my-service)        ← confirms SDK is setting service name
ScopeSpans #0
Span #0
    Trace ID       : 0af7651916cd43dd8448eb211c80319c
    Parent ID      : b7ad6b7169203331          ← non-empty = span is connected to a parent
    ID             : c5e2f3a1b4d67890
    Name           : GET /api/orders
    Kind           : Server
    Start time     : ...
    End time       : ...
    Status code    : Ok
Attributes:
     -> http.method: Str(GET)
     -> http.route:  Str(/api/orders)
     -> http.status_code: Int(200)
```

**What to look for:**

| Field | What it tells you |
| :--- | :--- |
| `service.name` present | SDK resource is configured correctly |
| `Parent ID` non-empty | Context is propagating; span is connected to a parent |
| `Parent ID` empty | Span is a root — expected for entry points, a bug for internal spans |
| `http.route` present | Framework middleware is installed and working |
| `Status code: Error` | `span.SetStatus` is being called on error paths |

## Reading the NDJSON Log File

Each line in `otelcol-spans.ndjson` is one batch of spans serialised as OTLP JSON. To
inspect individual spans, use `jq`:

```bash
# Pretty-print all spans
jq . otelcol-spans.ndjson

# List all span names received
jq -r '.resourceSpans[].scopeSpans[].spans[].name' otelcol-spans.ndjson

# Check for disconnected spans (missing parentSpanId)
jq '.resourceSpans[].scopeSpans[].spans[] | select(.parentSpanId == null or .parentSpanId == "") | .name' \
  otelcol-spans.ndjson

# List all attribute keys seen across all spans
jq -r '.resourceSpans[].scopeSpans[].spans[].attributes[].key' otelcol-spans.ndjson | sort -u
```

## Stopping the Collector

`Ctrl+C` — the script traps the signal, stops the container, and removes the temporary
config file. The NDJSON log file is kept so you can inspect it after shutdown.

SHA-256: 4cae1774c08d6cda796e64ea9f16a4e17998445257eb1b596766a6fd30d34d17