Skip to main content
Kotlin runs on the JVM, so the OpenTelemetry Java agent instruments it exactly as it does Java. Attach the agent at startup and it sends logs, metrics, and traces to Bronto with no code changes — instrumenting Spring, Ktor, Hibernate, JDBC, Kafka, and hundreds of other libraries, bridging your existing Logback or Log4j output into the OTLP logs pipeline, and collecting JVM metrics under one resource identity. The application exports to an OpenTelemetry Collector, which forwards to Bronto. If you don’t run a Collector, export directly to Bronto instead — only the endpoint and an API key header change.

Prerequisites

Attach the agent

Download the agent jar:
Configure it through environment variables and attach it with -javaagent:
That’s the whole setup. The agent exports all three signals over OTLP by default, and agent 2.x uses http/protobuf, appending the signal path (/v1/logs, /v1/metrics, /v1/traces) to the endpoint automatically. Two resource attributes determine how Bronto organises your data:
http://localhost:4318 is the standard OTLP/HTTP address for a Collector on the same host. Use the address reachable from your application if the Collector runs in another container, pod, or host. No authentication is needed between the application and the Collector — the Collector holds the Bronto API key.

Instrument your application

Existing SLF4J, Logback, and Log4j statements need no changes — the agent picks them up and attaches trace_id and span_id to any log emitted inside an active span, so you can jump from a log line to its trace in Bronto. For spans and metrics around your own business logic, add the API dependency — not the SDK, which the agent already supplies:
PaymentService.kt
Can’t use the agent? Where a javaagent isn’t an option — GraalVM native images, for example — build the SDK in process with opentelemetry-sdk-extension-autoconfigure, which reads the same OTEL_* variables, and add opentelemetry-logback-appender-1.0 plus OpenTelemetryAppender.install(openTelemetry) to bridge your logs. See Configure the SDK.

Verify

Run your application, then check each signal in Bronto, filtering by the service.name you set:
  • Logs — the Search page, in the dataset named after your service
  • Metrics — the Metric Explorer
  • Traces — the Explore Traces page
If nothing arrives:
  • Confirm the Collector is running and reachable at OTEL_EXPORTER_OTLP_ENDPOINT, and that its pipelines include an otlp receiver and the Bronto exporters.
  • Port 4318 is OTLP/HTTP and 4317 is OTLP/gRPC. If you point at 4317, also set OTEL_EXPORTER_OTLP_PROTOCOL=grpc.
  • Run with -Dotel.javaagent.debug=true to log what the agent instruments and exports at startup.
For signal-specific reference material, see Send Metrics to Bronto and Send Traces to Bronto.

Direct export to Bronto

Without a Collector, the agent exports straight to Bronto over OTLP/HTTP. Point the endpoint at your Bronto region and add your API key:
See API Keys for how to create a key with ingestion permissions.
Prefer the Collector for multi-service environments — it batches, filters, and enriches telemetry, and keeps the API key out of every application. Direct export suits single services and simple architectures.

GenAI semantic conventions

If your application calls an LLM, OpenTelemetry’s GenAI semantic conventions define gen_ai.* span attributes for model, token usage, and prompt and response content. The Java agent covers Kotlin applications too — there is no separate Kotlin package. See Java: GenAI semantic conventions for current auto-instrumentation coverage and the content-capture setting.

Manual spans

Where the agent doesn’t cover your provider, set the same attributes yourself:
See the GenAI span conventions for the full attribute list. For the recommended attribute set and Bronto search queries, see LLM Observability.