Managed Service for OpenTelemetry mengumpulkan data jejak dari aplikasi Java dan menyediakan topologi aplikasi, jejak, analisis transaksi abnormal dan lambat, serta analisis SQL. Tersedia tiga pendekatan instrumenasi, mulai dari penyiapan agen tanpa kode hingga kontrol penuh melalui SDK.
| Approach | Effort | When to use |
|---|---|---|
| OpenTelemetry Java agent (recommended) | Minimal — sambungkan JAR, tanpa perubahan kode | Sebagian besar aplikasi. Mulai dari sini. |
| OpenTelemetry SDK for Java | Moderate — tulis kode instrumenasi | Span kustom, atribut, atau framework yang tidak didukung |
| Agent + SDK combined | Moderate — agen menangani dasar-dasarnya, SDK menambahkan span kustom | Cakupan otomatis ditambah instrumenasi kustom terarah |
Kode contoh
Kloning atau telusuri proyek contoh sebagai referensi yang berfungsi:
git clone https://github.com/alibabacloud-observability/java-demo.git
cd java-demo/opentelemetry-demoMetode 1: Instrumen otomatis dengan OpenTelemetry Java agent
OpenTelemetry Java agent disambungkan ke JVM saat startup dan menginstrumenasi ratusan library dan framework tanpa perubahan kode apa pun. Ini merupakan titik awal yang direkomendasikan untuk sebagian besar aplikasi.
Langkah 1: Unduh agen
Unduh file JAR agen terbaru dari GitHub Releases:
# wget
wget -O opentelemetry-javaagent.jar \
https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jar
# atau curl
curl -Lo opentelemetry-javaagent.jar \
https://github.com/open-telemetry/opentelemetry-java-instrumentation/releases/latest/download/opentelemetry-javaagent.jarLangkah 2: Konfigurasikan parameter JVM dan jalankan aplikasi
Tambahkan flag -javaagent sebelum argumen -jar. Pilih salah satu protokol HTTP atau gRPC.
HTTP
java -javaagent:/path/to/opentelemetry-javaagent.jar \
-Dotel.resource.attributes=service.name=<your-service-name>,service.version=<your-version>,deployment.environment=<your-env> \
-Dotel.exporter.otlp.protocol=http/protobuf \
-Dotel.exporter.otlp.traces.endpoint=<traces-endpoint> \
-Dotel.exporter.otlp.metrics.endpoint=<metrics-endpoint> \
-Dotel.logs.exporter=none \
-jar /path/to/your/app.jarGanti placeholder dengan nilai aktual Anda:
| Placeholder | Description | Example |
|---|---|---|
<your-service-name> | Nama yang mengidentifikasi aplikasi Anda | order-service |
<your-version> | Versi aplikasi | 1.0.0 |
<your-env> | Lingkungan deployment | production |
<traces-endpoint> | Titik akhir jejak dari bagian Prasyarat | http://tracing-analysis-dc-hz-internal.aliyuncs.com/adapt_ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe****/api/otlp/traces |
<metrics-endpoint> | Titik akhir metrik dari bagian Prasyarat | http://tracing-analysis-dc-hz-internal.aliyuncs.com/adapt_ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe****/api/otlp/metrics |
Contoh:
java -javaagent:/path/to/opentelemetry-javaagent.jar \
-Dotel.resource.attributes=service.name=order-service,service.version=1.0.0,deployment.environment=production \
-Dotel.exporter.otlp.protocol=http/protobuf \
-Dotel.exporter.otlp.traces.endpoint=http://tracing-analysis-dc-hz-internal.aliyuncs.com/adapt_ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe****/api/otlp/traces \
-Dotel.exporter.otlp.metrics.endpoint=http://tracing-analysis-dc-hz-internal.aliyuncs.com/adapt_ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe****/api/otlp/metrics \
-Dotel.logs.exporter=none \
-jar /path/to/your/app.jargRPC
java -javaagent:/path/to/opentelemetry-javaagent.jar \
-Dotel.resource.attributes=service.name=<your-service-name>,service.version=<your-version>,deployment.environment=<your-env> \
-Dotel.exporter.otlp.protocol=grpc \
-Dotel.exporter.otlp.headers=Authentication=<token> \
-Dotel.exporter.otlp.endpoint=<endpoint> \
-Dotel.logs.exporter=none \
-jar /path/to/your/app.jarGanti placeholder dengan nilai aktual Anda:
| Placeholder | Description | Example |
|---|---|---|
<token> | Token otentikasi dari bagian Prasyarat | ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe**** |
<endpoint> | Titik akhir gRPC dari bagian Prasyarat | http://tracing-analysis-dc-hz-internal.aliyuncs.com:8090 |
Contoh:
java -javaagent:/path/to/opentelemetry-javaagent.jar \
-Dotel.resource.attributes=service.name=order-service,service.version=1.0.0,deployment.environment=production \
-Dotel.exporter.otlp.protocol=grpc \
-Dotel.exporter.otlp.headers=Authentication=ggxw4l****@7323a5caae3****_ggxw4l****@53df7ad2afe**** \
-Dotel.exporter.otlp.endpoint=http://tracing-analysis-dc-hz-internal.aliyuncs.com:8090 \
-Dotel.logs.exporter=none \
-jar /path/to/your/app.jarUntuk meneruskan data jejak melalui OpenTelemetry Collector, hapus-Dotel.exporter.otlp.headers=Authentication=<token>dan atur<endpoint>ke alamat Collector pada mesin on-premises Anda.
Langkah 3: Verifikasi data jejak
Pada halaman Applications, klik nama aplikasi Anda.
Konfirmasi bahwa jejak muncul pada halaman detail aplikasi.
Pemecahan masalah:
Jika tidak ada data yang muncul, verifikasi bahwa titik akhir dan token sudah benar.
Aktifkan logging debug untuk memeriksa perilaku agen:
-Dotel.javaagent.debug=trueNonaktifkan sementara agen tanpa menghapusnya dari perintah startup:
-Dotel.javaagent.enabled=false
Metode 2: Instrumen manual dengan OpenTelemetry SDK for Java
Gunakan OpenTelemetry SDK for Java ketika Anda memerlukan kontrol penuh atas operasi mana yang menghasilkan span, atribut apa yang dibawanya, atau ketika agen otomatis tidak mencakup framework Anda.
Langkah 1: Tambahkan dependensi Maven
Tambahkan berikut ini ke pom.xml Anda:
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-api</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-trace</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-exporter-otlp</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-semconv</artifactId>
<version>1.30.0-alpha</version>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-bom</artifactId>
<version>1.30.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>Langkah 2: Inisialisasi tracer
Buat kelas helper yang mengonfigurasi eksporter, atribut resource, dan tracer. Pilih protokol yang sesuai dengan lingkungan Anda.
HTTP
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
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;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
public class OpenTelemetrySupport {
static {
// Definisikan sumber daya yang mendeskripsikan layanan ini
Resource resource = Resource.getDefault()
.merge(Resource.create(Attributes.of(
ResourceAttributes.SERVICE_NAME, "<your-service-name>",
ResourceAttributes.SERVICE_VERSION, "<your-version>",
ResourceAttributes.DEPLOYMENT_ENVIRONMENT, "<your-env>",
ResourceAttributes.HOST_NAME, "<your-host-name>"
)));
// Buat penyedia jejak dengan exporter OTLP gRPC
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
.addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder()
.setEndpoint("<endpoint>") // Titik akhir gRPC dari bagian Prasyarat
.addHeader("Authentication", "<token>") // Token autentikasi dari bagian Prasyarat
.build()).build())
.setResource(resource)
.build();
// Daftarkan SDK secara global
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal();
tracer = openTelemetry.getTracer("OpenTelemetry Tracer", "1.0.0");
}
private static Tracer tracer;
public static Tracer getTracer() {
return tracer;
}
}gRPC
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
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;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
public class OpenTelemetrySupport {
static {
// Definisikan resource yang menggambarkan layanan ini
Resource resource = Resource.getDefault()
.merge(Resource.create(Attributes.of(
ResourceAttributes.SERVICE_NAME, "<your-service-name>",
ResourceAttributes.SERVICE_VERSION, "<your-version>",
ResourceAttributes.DEPLOYMENT_ENVIRONMENT, "<your-env>",
ResourceAttributes.HOST_NAME, "<your-host-name>"
)));
// Bangun penyedia tracer dengan eksporter OTLP gRPC
SdkTracerProvider sdkTracerProvider = SdkTracerProvider.builder()
.addSpanProcessor(BatchSpanProcessor.builder(OtlpGrpcSpanExporter.builder()
.setEndpoint("<endpoint>") // Titik akhir gRPC dari bagian Prasyarat
.addHeader("Authentication", "<token>") // Token otentikasi dari bagian Prasyarat
.build()).build())
.setResource(resource)
.build();
// Daftarkan SDK secara global
OpenTelemetry openTelemetry = OpenTelemetrySdk.builder()
.setTracerProvider(sdkTracerProvider)
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.buildAndRegisterGlobal();
tracer = openTelemetry.getTracer("OpenTelemetry Tracer", "1.0.0");
}
private static Tracer tracer;
public static Tracer getTracer() {
return tracer;
}
}Langkah 3: Buat span
Gunakan tracer untuk membuat span induk dan anak. Setiap span merekam satu unit pekerjaan, beserta atribut dan status error-nya.
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.context.Scope;
public class Main {
public static void parentMethod() {
// Mulai span induk
Span span = OpenTelemetrySupport.getTracer().spanBuilder("parent span").startSpan();
try (Scope scope = span.makeCurrent()) {
span.setAttribute("good", "job");
childMethod();
} catch (Throwable t) {
span.setStatus(StatusCode.ERROR, "handle parent span error");
} finally {
span.end();
}
}
public static void childMethod() {
// Mulai span anak — secara otomatis terhubung ke induk melalui Context
Span span = OpenTelemetrySupport.getTracer().spanBuilder("child span").startSpan();
try (Scope scope = span.makeCurrent()) {
span.setAttribute("hello", "world");
} catch (Throwable t) {
span.setStatus(StatusCode.ERROR, "handle child span error");
} finally {
span.end();
}
}
public static void main(String[] args) {
parentMethod();
}
}Langkah 4: Jalankan aplikasi dan verifikasi
Jalankan aplikasi, lalu buka Konsol Managed Service for OpenTelemetry. Pada halaman Applications, klik nama aplikasi Anda dan konfirmasi bahwa jejak muncul.
Metode 3: Gabungkan Java agent dengan SDK
Gunakan agen untuk cakupan otomatis yang luas dan SDK untuk span kustom yang terarah. Agen secara otomatis mengonfigurasi SDK saat startup melalui dependensi opentelemetry-sdk-extension-autoconfigure, sehingga Anda tidak perlu kelas helper OpenTelemetrySupport dari Metode 2.
Langkah 1: Unduh agen
Unduh OpenTelemetry Java agent seperti yang dijelaskan di Metode 1, Langkah 1.
Langkah 2: Tambahkan dependensi Maven
Selain dependensi di Metode 2, Langkah 1, tambahkan berikut ini:
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-extension-annotations</artifactId>
</dependency>
<dependency>
<groupId>io.opentelemetry</groupId>
<artifactId>opentelemetry-sdk-extension-autoconfigure</artifactId>
<version>1.23.0-alpha</version>
</dependency>Dependensi opentelemetry-sdk-extension-autoconfigure mentransfer pengaturan agen ke SDK secara otomatis, sehingga Anda tidak perlu mengonfigurasi eksporter atau atribut resource dalam kode.Langkah 3: Dapatkan tracer
Karena agen menangani inisialisasi SDK, dapatkan tracer global secara langsung:
OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
Tracer tracer = openTelemetry.getTracer("instrumentation-library-name", "1.0.0");Langkah 4: Tambahkan instrumen kustom
Tiga teknik untuk menambahkan instrumenasi di atas agen:
Teknik 1: Tambahkan atribut ke span yang dibuat otomatis
Panggil Span.current() di dalam metode yang sudah diinstrumenasi untuk melampirkan atribut bisnis:
@RequestMapping("/async")
public String async() {
Span span = Span.current();
span.setAttribute("user.id", "123456");
userService.async();
child("vip");
return "async";
}Teknik 2: Gunakan @WithSpan untuk instrumen berbasis anotasi
Anotasikan metode dengan @WithSpan untuk membuat span secara otomatis. Gunakan @SpanAttribute untuk merekam parameter:
@WithSpan
private void child(@SpanAttribute("user.type") String userType) {
System.out.println(userType);
biz();
}Teknik 3: Buat span secara manual dengan tracer
Untuk kontrol penuh, bangun span dengan API tracer. Contoh ini juga menyebarkan konteks ke thread asinkron:
private void biz() {
Tracer tracer = GlobalOpenTelemetry.get().getTracer("tracer");
Span span = tracer.spanBuilder("biz (manual)")
.setParent(Context.current().with(Span.current())) // opsional — diatur secara otomatis
.startSpan();
try (Scope scope = span.makeCurrent()) {
span.setAttribute("biz-id", "111");
// Sebarkan konteks ke tugas asinkron
es.submit(() -> {
Span asyncSpan = tracer.spanBuilder("async")
.setParent(Context.current().with(span))
.startSpan();
try {
Thread.sleep(1000L); // simulasi pekerjaan asinkron
} catch (Throwable e) {
// tangani error
}
asyncSpan.end();
});
Thread.sleep(1000); // simulasi logika bisnis
} catch (Throwable t) {
span.setStatus(StatusCode.ERROR, "handle biz error");
} finally {
span.end();
}
}Kode controller dan service lengkap
Controller (com.alibaba.arms.brightroar.console.controller):
package com.alibaba.arms.brightroar.console.controller;
import com.alibaba.arms.brightroar.console.service.UserService;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.StatusCode;
import io.opentelemetry.api.trace.Tracer;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.extension.annotations.SpanAttribute;
import io.opentelemetry.extension.annotations.WithSpan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
private ExecutorService es = Executors.newFixedThreadPool(5);
// Teknik 1: Tambahkan atribut ke span yang dibuat otomatis
@RequestMapping("/async")
public String async() {
System.out.println("UserController.async -- " + Thread.currentThread().getId());
Span span = Span.current();
span.setAttribute("user.id", "123456");
userService.async();
child("vip");
return "async";
}
// Teknik 2: Instrumen berbasis anotasi
@WithSpan
private void child(@SpanAttribute("user.type") String userType) {
System.out.println(userType);
biz();
}
// Teknik 3: Pembuatan span manual
private void biz() {
Tracer tracer = GlobalOpenTelemetry.get().getTracer("tracer");
Span span = tracer.spanBuilder("biz (manual)")
.setParent(Context.current().with(Span.current()))
.startSpan();
try (Scope scope = span.makeCurrent()) {
span.setAttribute("biz-id", "111");
es.submit(new Runnable() {
@Override
public void run() {
Span asyncSpan = tracer.spanBuilder("async")
.setParent(Context.current().with(span))
.startSpan();
try {
Thread.sleep(1000L); // simulasi pekerjaan asinkron
} catch (Throwable e) {
}
asyncSpan.end();
}
});
Thread.sleep(1000); // simulasi logika bisnis
System.out.println("biz done");
OpenTelemetry openTelemetry = GlobalOpenTelemetry.get();
openTelemetry.getPropagators();
} catch (Throwable t) {
span.setStatus(StatusCode.ERROR, "handle biz error");
} finally {
span.end();
}
}
}Service (com.alibaba.arms.brightroar.console.service):
package com.alibaba.arms.brightroar.console.service;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Async
public void async() {
System.out.println("UserService.async -- " + Thread.currentThread().getId());
System.out.println("my name is async");
System.out.println("UserService.async -- ");
}
}Langkah 5: Konfigurasikan parameter JVM dan jalankan aplikasi
java -javaagent:/path/to/opentelemetry-javaagent.jar \
-Dotel.resource.attributes=service.name=<your-service-name> \
-Dotel.exporter.otlp.headers=Authentication=<token> \
-Dotel.exporter.otlp.endpoint=<endpoint> \
-jar /path/to/your/app.jarContoh:
java -javaagent:/path/to/opentelemetry-javaagent.jar \
-Dotel.resource.attributes=service.name=ot-java-agent-sample \
-Dotel.exporter.otlp.headers=Authentication=b590xxxxuqs@3a75d95xxxxx9b_b59xxxxguqs@53dxxxx2afe8301 \
-Dotel.exporter.otlp.endpoint=http://tracing-analysis-dc-bj:8090 \
-jar /path/to/your/app.jarUntuk meneruskan data jejak melalui OpenTelemetry Collector, hapus-Dotel.exporter.otlp.headers=Authentication=<token>dan atur<endpoint>ke alamat Collector pada mesin on-premises Anda.
Buka Konsol Managed Service for OpenTelemetry. Pada halaman Applications, klik nama aplikasi Anda dan konfirmasi bahwa jejak muncul.
Framework Java yang didukung
OpenTelemetry Java agent secara otomatis menginstrumenasi framework berikut. Untuk daftar lengkap dan terbaru, lihat Library, framework, server aplikasi, dan JVM yang didukung.