Skip to main content
This page covers instrumenting a Node.js application with the OpenTelemetry SDK to send logs and traces to Bronto over OTLP/HTTP via a local OTel Collector. Both signals are co-equal: logs are bridged via a Winston or Pino transport — no log statement changes needed — and traces are emitted via a tracer provider.
If you don’t have a Collector and want to export directly from your application to Bronto, see Direct export to Bronto at the bottom of this page.

Prerequisites

Install dependencies

Configure the OTel logger provider

Set up a LoggerProvider with an OTLP exporter. This is the same regardless of which logger you use.
otel-logging.js

Configure the log bridge

Set resource attributes

Resource attributes are attached to every log record exported from this process. Two attributes drive how Bronto organises incoming logs: These are set via the Resource constructor in the provider setup above.

Complete example

app.js

Verify delivery

After running your application, check both signals in Bronto:
  • Logs: open the Search page and filter by the dataset name you set in service.name — your log records should appear within a few seconds.
  • Traces: open the Explore Traces page and filter by the same service.name — your spans should appear within a few seconds.
If no logs appear, check:
  • The OTel Collector is running and reachable at the configured endpoint.
  • The Collector’s pipeline includes a logs pipeline with an otlp receiver and the Bronto exporter — see Connect Open Telemetry to Bronto.
  • otel-logging.js is required before any logger is created — the OpenTelemetryTransportV3 picks up the global LoggerProvider on instantiation.
  • BatchLogRecordProcessor exports on a background timer — for short-lived scripts, call loggerProvider.shutdown() before exit to flush pending records.

Traces

For Express, HTTP, gRPC, database drivers, and other popular libraries, use @opentelemetry/auto-instrumentations-node — it instruments all supported libraries automatically at startup with no code changes. Run node -r @opentelemetry/auto-instrumentations-node/register app.js or require it at the top of your entry point. See Node.js auto-instrumentation for setup details.

Install tracing dependencies

Configure the tracer provider

otel-tracing.js
Pass the same resource object used for logging so both signals share service.name and service.namespace.

Creating spans

Any log emitted inside an active span will automatically have trace_id and span_id attached via the OpenTelemetryTransportV3.

Complete example

app.js

GenAI semantic conventions

If your application calls an LLM (OpenAI, Anthropic, Amazon Bedrock, etc.), OpenTelemetry defines a dedicated set of GenAI semantic conventionsgen_ai.* attributes for model, token usage, and prompt/response content.
This page was verified on July 17, 2026. GenAI libraries and semantic conventions are evolving rapidly, so package configuration and emitted attributes can change between releases. Keep your instrumentation current and verify the fields emitted by the version you deploy.

Auto-instrumentation

Contrib packages instrument popular provider SDKs automatically. For OpenAI:
Register it alongside your other instrumentations:
For Amazon Bedrock, no extra package is needed beyond the AWS SDK instrumentation you likely already have: @opentelemetry/instrumentation-aws-sdk implements the GenAI semantic conventions for Bedrock Runtime calls (Converse, InvokeModel), and is bundled in @opentelemetry/auto-instrumentations-node.
Need broader provider or framework coverage? See OpenLLMetry for supported packages, setup, schema guidance, and content-capture controls.

Experimental: capturing prompt and response content

For the contrib instrumentations, content capture is off by default and controlled by:
(The OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental opt-in used by the Python instrumentations is not read by the JS contrib packages.)
With content capture enabled, prompt/response content is emitted as log records (OTel log events) — it flows through the logs pipeline, correlated to the span by trace_id, rather than landing on the span itself, so it is not queryable in Bronto’s traces dataset.To shape it for search, emit the content as a structured log record with explicit attributes, using the log bridge configured above. See LLM Observability for the recommended attribute names, a worked logging example, and Bronto search queries.

Manual spans

Where no auto-instrumentation package exists for your provider, set the gen_ai.* attributes yourself:
See LLM Observability for the full recommended attribute set, including gen_ai.input.messages / gen_ai.output.messages, and how to search and aggregate GenAI fields in Bronto.

Direct export to Bronto

If you are not using an OTel Collector, export directly to Bronto by replacing the exporter configurations with the Bronto OTLP endpoints and your API key:
See API Keys for how to create a key with ingestion permissions. No other changes to the rest of the setup are required.