Copy as Markdown[Open in ChatGPT](https://chatgpt.com/?q=Read%20https%3A%2F%2Fdocs-docusaurus.kinsta.page%2Fuser-guides%2Fai%2Fotel-integration%2Fcode-examples%2Fjava-manual.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)[Open in Claude](https://claude.ai/new?q=Read%20https%3A%2F%2Fdocs-docusaurus.kinsta.page%2Fuser-guides%2Fai%2Fotel-integration%2Fcode-examples%2Fjava-manual.md%20and%20help%20me%20with%20my%20question%20about%20this%20Coralogix%20documentation%20page.)

# Java — manual instrumentation

No auto-instrumentation exists for OpenAI in Java. Manual spans with new semconv.

Before you start

These examples export to a local OpenTelemetry Collector over OTLP/gRPC. Deploy the collector first — see [Code examples → Deploy an OpenTelemetry Collector](https://docs-docusaurus.kinsta.page/user-guides/ai/otel-integration/code-examples/.md#prerequisites-deploy-an-opentelemetry-collector).

## Dependencies (`pom.xml`)[​](#dependencies-pomxml "Direct link to dependencies-pomxml")

```
<dependencies>

    <dependency>

        <groupId>com.openai</groupId>

        <artifactId>openai-java</artifactId>

        <version>4.35.0</version>

    </dependency>

    <dependency>

        <groupId>io.opentelemetry</groupId>

        <artifactId>opentelemetry-sdk</artifactId>

    </dependency>

    <dependency>

        <groupId>io.opentelemetry</groupId>

        <artifactId>opentelemetry-exporter-otlp</artifactId>

    </dependency>

</dependencies>

<dependencyManagement>

    <dependencies>

        <dependency>

            <groupId>io.opentelemetry</groupId>

            <artifactId>opentelemetry-bom</artifactId>

            <version>1.59.0</version>

            <type>pom</type>

            <scope>import</scope>

        </dependency>

    </dependencies>

</dependencyManagement>
```

## Environment variables[​](#environment-variables "Direct link to Environment variables")

```
export OPENAI_API_KEY="sk-..."

export CX_OTEL_ENDPOINT="http://<COLLECTOR_HOST>:4317"
```

## Script[​](#script "Direct link to Script")

```
package com.example;



import com.openai.client.OpenAIClient;

import com.openai.client.okhttp.OpenAIOkHttpClient;

import com.openai.models.*;

// --- OTel imports ---

import io.opentelemetry.api.common.*;

import io.opentelemetry.api.trace.*;

import io.opentelemetry.context.Scope;

import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;

import io.opentelemetry.sdk.OpenTelemetrySdk;

import io.opentelemetry.sdk.resources.Resource;

import io.opentelemetry.sdk.trace.SdkTracerProvider;

import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;



public class GenAiManualInstrumentation {

    public static void main(String[] args) {

        // --- OTel setup: configure OTLP exporter, resource, and tracer ---

        var cxEndpoint = System.getenv().getOrDefault("CX_OTEL_ENDPOINT",

                "http://<COLLECTOR_HOST>:4317");



        var exporter = OtlpGrpcSpanExporter.builder()

                .setEndpoint(cxEndpoint).build();

        var resource = Resource.getDefault().merge(Resource.create(

                Attributes.builder()

                    .put("service.name", "java-genai-demo")

                    .put("cx.application.name", "my-genai-app")

                    .put("cx.subsystem.name", "my-service").build()));

        var tracerProvider = SdkTracerProvider.builder()

                .addSpanProcessor(BatchSpanProcessor.builder(exporter).build())

                .setResource(resource).build();

        var otel = OpenTelemetrySdk.builder().setTracerProvider(tracerProvider).build();

        var tracer = otel.getTracer("genai-manual");



        // --- Your app logic ---

        var openAi = OpenAIOkHttpClient.fromEnv();

        var model = "gpt-4o-mini";

        var systemMsg = "You are a concise assistant.";

        var userMsg = "Explain distributed tracing in one sentence.";



        // --- OTel: build gen_ai.input.messages in new semconv format ---

        var inputJson = "[" +

            "{\"role\":\"system\",\"parts\":[{\"type\":\"text\",\"content\":\"" + systemMsg + "\"}]}," +

            "{\"role\":\"user\",\"parts\":[{\"type\":\"text\",\"content\":\"" + userMsg + "\"}]}]";



        // OTel: create a GenAI span with required attributes

        Span span = tracer.spanBuilder("chat " + model)

                .setSpanKind(SpanKind.CLIENT)

                .setAttribute("gen_ai.operation.name", "chat")

                .setAttribute("gen_ai.provider.name", "openai")

                .setAttribute("gen_ai.request.model", model)

                .setAttribute("gen_ai.input.messages", inputJson)

                .startSpan();



        try (Scope ignored = span.makeCurrent()) {

            var params = ChatCompletionCreateParams.builder()

                    .model(ChatModel.GPT_4O_MINI)

                    .maxCompletionTokens(100)

                    .addSystemMessage(systemMsg)

                    .addUserMessage(userMsg).build();

            var completion = openAi.chat().completions().create(params);

            var text = completion.choices().get(0).message().content().orElse("");



            span.setAttribute("gen_ai.response.model", completion.model());

            span.setAttribute("gen_ai.response.id", completion.id());

            span.setAttribute("gen_ai.usage.input_tokens",

                    completion.usage().map(u -> u.promptTokens()).orElse(0L));

            span.setAttribute("gen_ai.usage.output_tokens",

                    completion.usage().map(u -> u.completionTokens()).orElse(0L));

            span.setAttribute("gen_ai.output.messages",

                    "[{\"role\":\"assistant\",\"parts\":[{\"type\":\"text\",\"content\":\"" +

                    text.replace("\"", "\\\"") + "\"}]}]");

            System.out.println("Response: " + text);

        } catch (Exception e) {

            span.setStatus(StatusCode.ERROR, e.getMessage());

            span.recordException(e);

        } finally {

            span.end();

        }

        tracerProvider.forceFlush();

        tracerProvider.shutdown();

    }

}
```

## Next steps[​](#next-steps "Direct link to Next steps")

Look up which open-source library to use for your provider in [Compatibility matrix](https://docs-docusaurus.kinsta.page/user-guides/ai/otel-integration/providers/.md).
