Native OpenTelemetry ingest is available in Hydrolix version 6.3 and later.
An OpenTelemetry SDK exports telemetry directly from an application to the Hydrolix gRPC endpoint on port 4317, without a Collector in between.
This guide covers configuring the Python, Java, Go, and Node.js SDKs to send OpenTelemetry logs, metrics, and traces to Hydrolix tables. Each example uses the same endpoint, routing headers, and TLS through the SDK's OTLP gRPC exporter. Hydrolix also accepts OTLP over HTTP. To send over HTTP instead, use the SDK's OTLP/HTTP exporter with the endpoints listed under Protocol.
For an overview of how Hydrolix ingests OpenTelemetry data, see OpenTelemetry ingest.
To forward telemetry from many applications through a shared pipeline, see the Collector setup guide.
Exporting directly from an application is the quickest path to get telemetry into Hydrolix. It works well for a single application, local development, and early testing.
For production deployments with many applications, a Collector adds batching, retries, filtering, and a shared egress path. See the Collector setup guide.
Enable native ingest. Native OpenTelemetry ingest is off by default. See Enable OpenTelemetry ingest. A Hydrolix-managed deployment has this handled for you.
Find your endpoint. The endpoint is the hostname you use to reach Hydrolix, on port 4317. The examples use hostname.hydrolix.live:4317 as a placeholder.
Create a service account token. The endpoint requires a bearer token. Create a service account token and make it available to the examples as the HDX_TOKEN environment variable.
Create a table and transform for each signal. Each target table and its transform must exist before the SDK sends data. Name each table in project.table format; see Projects and tables. A transform maps the OpenTelemetry fields to columns; see Reference transforms for the standard logs, metrics, and traces schemas.
The logs signal is the least mature part of the OpenTelemetry SDKs. The Go and Node.js logs packages are still pre-1.0 and their APIs can change between releases, so pin the versions you test against.
Every exporter points at the same gRPC endpoint on port 4317 and carries routing headers that identify the target table and transform. Define the endpoint, token, and resource once. The resource identifies the service that emits the telemetry.
Some examples end with a flush or shutdown call, such as Python's force_flush or Go's Shutdown, to send buffered telemetry before a short program exits. A long-running application instead relies on the batch processor's periodic export.
The service.name resource attribute maps to the service_name column in the reference transforms. Write the header keys in lowercase, such as authorization, to match the gRPC metadata format.
The endpoint requires TLS. Java connects over the https scheme; Python, Go, and Node.js use a bare host:port and connect over TLS by default.
Hydrolix schemas are user-defined. Each request must carry a metadata header to identify the target table, and can carry a header specifying a non-default transform.
Header
Required
Description
x-hdx-table
Yes
Target table in project.table format
x-hdx-transform
No
Transform to apply. Uses the table's default transform if omitted.
These headers travel as gRPC metadata. Most SDKs set them through a headers or addHeader option on the exporter. The OpenTelemetry JavaScript gRPC exporter ignores the headers option and reads a metadata object built with @grpc/grpc-js instead.
Send log records through a logger provider with an OTLP log exporter.
Log records require a timestamp
The native endpoint silently drops log records whose time_unix_nano is unset. Logging bridges set it for you, including Log4j, Logback, and the Python LoggingHandler in these examples. If you emit records directly, set the timestamp explicitly: .setTimestamp(Instant.now()) in Java, timestamp= on a Python LogRecord, record.SetTimestamp(time.Now()) in Go, or the timestamp field on the record passed to logger.emit() in Node.js.
The OpenTelemetry logs API for Python is in the opentelemetry.sdk._logs module.
In Java, applications usually emit logs through a Log4j or Logback bridge rather than calling the logs API directly. The SdkLoggerProvider is the export pipeline behind that bridge.
The requests counter arrives as an OTLP sum metric. Sum is the metric type, not part of the name, so the metric is still called requests.
Different metric types carry their values in different fields, and the reference metrics transform maps those fields to table columns. For example, a sum's total maps to the value column, and a histogram's per-bucket counts map to the bucket_counts column.
The OpenTelemetry SDKs read exporter settings from OTEL_EXPORTER_OTLP_* environment variables. Set these variables to configure the endpoint and headers outside application code, then create the exporter with no arguments.
OTEL_EXPORTER_OTLP_HEADERS applies to every signal. To send different signals to different tables, set the signal-specific variables instead:
OTEL_EXPORTER_OTLP_LOGS_HEADERS
OTEL_EXPORTER_OTLP_METRICS_HEADERS
OTEL_EXPORTER_OTLP_TRACES_HEADERS
Support for these variables differs by SDK:
Python and Go read them directly through the OTLP gRPC exporter.
Java reads them only when the application adds the opentelemetry-sdk-extension-autoconfigure module.
Node.js honors the endpoint and TLS variables, but the gRPC exporter doesn't reliably apply OTEL_EXPORTER_OTLP_HEADERS. Set routing headers with the metadata option instead.
After running an example, query the target table to confirm the records arrived. Run the query through any Hydrolix query interface, such as the Hydrolix UI or the HTTP query API.
Both endpoints require a bearer token, which can be a service account token. Pass the token in the authorization header on each exporter, or through the OTEL_EXPORTER_OTLP_HEADERS environment variable.