Untuk mesin komputasi data besar seperti Flink, Spark, dan Storm yang memerlukan kompresi log, pengunggahan batch ke Simple Log Service (SLS), serta pengurangan konsumsi sumber daya jaringan, API atau SDK standar mungkin tidak mencukupi. Aliyun Log Java Producer menyediakan solusi praktis dan efisien untuk mengunggah data ke SLS dalam skenario tersebut.
Prasyarat
Simple Log Service telah diaktifkan.
Simple Log Service SDK untuk Python telah diinisialisasi.
Apa itu Aliyun Log Java Producer
Aliyun Log Java Producer adalah pustaka kelas berkinerja tinggi yang dirancang untuk aplikasi Java di lingkungan data besar dan konkurensi tinggi. Pustaka ini menawarkan beberapa keunggulan dibandingkan API atau SDK standar, termasuk kinerja tinggi, pemisahan logika komputasi dan I/O, serta manajemen sumber daya. Pustaka ini memanfaatkan fitur penulisan sekuensial Alibaba Cloud SLS untuk memastikan pengunggahan log secara terurut.
SLS menyediakan contoh aplikasi yang menggunakan Aliyun Log Java Producer untuk mempermudah pemula. Untuk informasi lebih lanjut, lihat Aliyun Log Producer Sample Application.
Alur Kerja
Fitur
Keamanan thread: Semua metode yang diekspos oleh antarmuka Producer bersifat thread-safe.
Pengiriman asinkron: Memanggil antarmuka pengiriman Producer biasanya langsung mengembalikan respons. Producer secara internal melakukan cache dan menggabungkan data yang tertunda, lalu mengirimnya secara batch untuk meningkatkan throughput.
Retry otomatis: Producer melakukan retry berdasarkan jumlah maksimum retry dan waktu backoff yang dikonfigurasi.
Pelacakan perilaku: Melalui Callback atau Future, Anda dapat memperoleh informasi apakah data saat ini berhasil dikirim, beserta informasi setiap upaya pengiriman, yang membantu pelacakan masalah dan pengambilan keputusan.
Pemulihan konteks: Log yang dihasilkan oleh instans Producer yang sama berada dalam konteks yang sama, sehingga Anda dapat melihat log terkait sebelum dan sesudah log tertentu di sisi server.
Shutdown elegan: Metode close memastikan semua data yang di-cache oleh Producer diproses sebelum keluar, dan Anda akan menerima notifikasi yang sesuai.
Keunggulan
Keunggulan Producer dibandingkan API atau SDK asli adalah sebagai berikut:
Kinerja tinggi
Dengan data dalam jumlah besar dan sumber daya terbatas, mencapai throughput target pada ujung penulisan memerlukan logika kontrol yang kompleks, termasuk multithreading, strategi caching, pengiriman batch, serta pertimbangan menyeluruh terhadap skenario retry saat gagal. Producer mengimplementasikan fungsi-fungsi ini, menyederhanakan pengembangan program sekaligus memberikan keunggulan kinerja.
Asinkron non-blocking
Dengan memori yang tersedia cukup, Producer melakukan cache data yang dikirim ke logstore, sehingga metode send langsung mengembalikan hasil tanpa blocking, mencapai pemisahan logika komputasi dan I/O. Selanjutnya, hasil transmisi data dapat diperoleh melalui objek Future yang dikembalikan atau Callback yang disediakan.
Sumber daya terkendali
Kontrol ukuran memori yang digunakan Producer untuk menyimpan data tertunda melalui parameter, dan konfigurasikan jumlah thread yang digunakan untuk menjalankan tugas pengiriman data. Hal ini mencegah Producer mengonsumsi sumber daya tanpa batas dan memungkinkan Anda menyeimbangkan konsumsi sumber daya dan throughput penulisan berdasarkan kondisi aktual.
Lokasi masalah sederhana
Jika transmisi data log gagal, Producer tidak hanya mengembalikan kode status, tetapi juga pesan pengecualian bertipe String yang menjelaskan alasan kegagalan dan informasi detailnya. Misalnya, jika transmisi gagal karena timeout koneksi jaringan, pesan pengecualian yang dikembalikan mungkin berupa "connection timeout"; jika transmisi gagal karena server tidak merespons, pesan pengecualian yang dikembalikan mungkin berupa "server unresponsive".
Catatan Penggunaan
aliyun-log-producer secara mendasari memanggil operasi PutLogs untuk mengunggah log, dan terdapat batasan pada ukuran log mentah yang dapat ditulis setiap kali. Untuk informasi lebih lanjut, lihat Data read and write.
Sumber daya dasar SLS, termasuk jumlah project, logstore, shard, LogtailConfig, machine group, ukuran LogItem tunggal, panjang LogItem (Key), dan panjang LogItem (Value), semuanya dibatasi. Untuk informasi lebih lanjut, lihat Basic resource limits.
Setelah kode dijalankan pertama kali, aktifkan indexing logstore di Konsol SLS, tunggu satu menit, lalu lakukan kueri.
Saat melakukan kueri log di konsol, jika panjang nilai field tunggal melebihi panjang maksimum, bagian yang melebihi akan dipotong dan tidak dimasukkan dalam analisis. Untuk informasi lebih lanjut, lihat Create indexes.
Penagihan
Biaya yang dikeluarkan saat menggunakan SDK konsisten dengan biaya yang dikeluarkan saat menggunakan konsol. Untuk informasi lebih lanjut, lihat Billing overview.
Langkah 1: Instal Aliyun Log Java Producer
Untuk menggunakan Aliyun Log Java Producer dalam proyek Maven, tambahkan dependensi yang sesuai dalam file pom.xml. Kemudian, Maven akan secara otomatis mengunduh paket JAR terkait. Sebagai contoh, tambahkan berikut ini di dalam <dependencies>:
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>aliyun-log-producer</artifactId>
<version>0.3.22</version>
</dependency>
Setelah menambahkan dan memperbarui, jika terjadi konflik versi dengan dependensi Producer, tambahkan berikut ini di dalam <dependencies>:
<dependency>
<groupId>com.aliyun.openservices</groupId>
<artifactId>aliyun-log</artifactId>
<version>0.6.114</version>
<classifier>jar-with-dependencies</classifier>
</dependency>Langkah 2: Konfigurasi ProducerConfig
ProducerConfig digunakan untuk mengatur kebijakan pengiriman. Sesuaikan nilai parameter agar sesuai dengan kebutuhan bisnis yang berbeda. Parameter dijelaskan dalam tabel berikut:
Config producerConfig = new ProducerConfig();
producerConfig.setTotalSizeInBytes(104857600);Parameter | Tipe | Deskripsi |
totalSizeInBytes | Integer | Ukuran maksimum log yang dapat di-cache oleh satu instans producer. Nilai default: 100 MB. |
maxBlockMs | Integer | Waktu blocking maksimum saat metode send dipanggil tetapi ruang yang tersedia pada instans producer tidak mencukupi. Nilai default: 60 detik. Jika waktu blocking maksimum yang Anda tentukan telah habis dan ruang yang tersedia pada instans producer masih tidak mencukupi, metode send akan melemparkan error TimeoutException. Jika Anda mengatur parameter ini ke 0 dan ruang yang tersedia pada instans producer tidak mencukupi, metode send langsung melemparkan error TimeoutException. Jika Anda ingin memblokir metode send hingga ruang yang tersedia pada instans producer mencukupi, Anda harus mengatur parameter ini ke nilai negatif. |
ioThreadCount | Integer | Jumlah thread untuk tugas pengiriman log. Nilai default adalah jumlah prosesor yang tersedia. |
batchSizeThresholdInBytes | Integer | Ambang batas untuk mengirim batch log. Nilai default: 512 KB. Nilai maksimum: 5 MB. |
batchCountThreshold | Integer | Jumlah log dalam satu batch sebelum dikirim. Nilai default: 4096. Nilai maksimum: 40960. |
lingerMs | Integer | Penundaan sebelum batch dapat dikirim. Nilai default: 2 detik. Nilai minimum: 100 ms. |
retries | Integer | Jumlah upaya retry untuk satu batch setelah kegagalan awal. Nilai default: 10. Jika parameter ini diatur ke 0 atau kurang, batch langsung masuk ke antrian kegagalan setelah kegagalan pertama. |
maxReservedAttempts | Integer | Setiap upaya mengirim ProducerBatch berkorespondensi dengan satu attempt. Parameter ini mengontrol berapa banyak attempt yang dilaporkan kembali kepada pengguna, secara default hanya menyimpan 11 attempt terbaru. Meningkatkan parameter ini memungkinkan pelacakan yang lebih detail dengan imbalan konsumsi memori yang lebih tinggi. |
baseRetryBackoffMs | Integer | Waktu backoff awal untuk retry. Nilai default: 100 milidetik. Producer menggunakan algoritma exponential backoff, di mana waktu tunggu sebelum retry ke-N dihitung sebagai baseRetryBackoffMs × 2^(N-1). |
maxRetryBackoffMs | Integer | Waktu backoff maksimum untuk retry. Nilai default: 50 detik. |
adjustShardHash | Boolean | Menentukan apakah shardHash akan disesuaikan saat metode send dipanggil. Nilai default: true. |
buckets | Integer | Parameter ini berlaku ketika adjustShardHash bernilai true. Parameter ini mengelompokkan ulang shardHash ke jumlah bucket yang ditentukan. Nilai shardHash yang berbeda mencegah data digabung dan di-batch, sehingga membatasi throughput producer. Dengan mengelompokkan ulang shardHash, data dapat di-batch secara lebih efektif untuk transmisi. Nilai parameter ini harus merupakan pangkat bulat dari 2 dalam rentang [1, 256]. Nilai default: 64. |
Langkah 3: Buat producer
Producer mendukung konfigurasi dengan AK atau token STS. Untuk token STS, buat ProjectConfig baru secara berkala dan tambahkan ke ProjectConfigs.
LogProducer adalah kelas implementasi producer, dan memerlukan producerConfig yang unik. Setelah producerConfig disiapkan, buat instans producer sebagai berikut:
Producer producer = new LogProducer(producerConfig);Membuat producer akan memulai beberapa thread, suatu proses yang intensif sumber daya. Kami menyarankan Anda membagikan satu instans producer di seluruh aplikasi. Semua metode LogProducer bersifat thread-safe untuk penggunaan konkuren. Tabel berikut mencantumkan thread dalam satu instans producer, di mana N adalah nomor instans, dimulai dari 0.
Format nama thread | Jumlah | Deskripsi |
aliyun-log-producer-<N>-mover | 1 | Memindahkan batch yang siap dikirim ke kolam thread pengiriman. |
aliyun-log-producer-<N>-io-thread | ioThreadCount | Thread dalam IOThreadPool yang menjalankan tugas pengiriman data. |
aliyun-log-producer-<N>-success-batch-handler | 1 | Menangani batch yang berhasil dikirim. |
aliyun-log-producer-<N>-failure-batch-handler | 1 | Mengelola batch yang gagal dikirim. |
Langkah 4: Konfigurasi project log
ProjectConfig mencakup informasi endpoint project tujuan dan kredensial akses yang merepresentasikan identitas pemanggil. Setiap project log berkorespondensi dengan satu objek ProjectConfig.
Buat instans sebagai berikut:
ProjectConfig project1 = new ProjectConfig("your-project-1", "cn-hangzhou.log.aliyuncs.com", "accessKeyId", "accessKeySecret");
ProjectConfig project2 = new ProjectConfig("your-project-2", "cn-shanghai.log.aliyuncs.com", "accessKeyId", "accessKeySecret");
producer.putProject(project1);
producer.putProject(project2);Langkah 5: Kirim data
Buat Future atau Callback
Saat mengirim data log dengan Aliyun Log Java Producer, tentukan fungsi Callback untuk menangani proses pengiriman. Fungsi Callback ini dipanggil ketika transmisi data berhasil atau ketika terjadi pengecualian selama pengiriman yang gagal.
Jika pemrosesan pasca-hasil dalam aplikasi sederhana dan tidak memblokir producer, gunakan callback secara langsung. Jika tidak, gunakan ListenableFuture untuk menangani logika bisnis di thread atau kolam thread terpisah.
Parameter metode dijelaskan di bawah ini:
Parameter | Deskripsi |
project | Project tujuan untuk data yang akan dikirim. |
logstore | Logstore tujuan untuk data yang akan dikirim. |
logTem | Data yang akan dikirim. |
completed | Tipe atomik Java untuk memastikan semua log dikirim (baik berhasil maupun gagal). |
Kirim data
Antarmuka producer menawarkan beberapa metode pengiriman, masing-masing dengan parameter spesifik seperti dijelaskan di bawah ini.
Parameter | Deskripsi | Wajib |
project | Project tujuan. | Ya |
logStore | Logstore tujuan. | Ya |
logItem | Log yang akan dikirim. | Ya |
topic | Topik log. | Tidak Catatan Jika tidak ditentukan, parameter ini diberi nilai "". |
source | Sumber log. | Tidak Catatan Jika tidak ditentukan, parameter ini diberi alamat IP host tempat producer berada. |
shardHash | Nilai hash untuk log yang akan dikirim. Tentukan nilai hash sesuai kebutuhan, lalu log akan ditulis ke shard tertentu dalam logstore yang ditentukan berdasarkan nilai hash tersebut. | Tidak Catatan Jika tidak ditentukan, data ditulis ke shard acak dalam logstore tujuan. |
callback | Definisikan fungsi Callback yang dipanggil ketika pengiriman log berhasil, atau setelah log dibuang setelah beberapa kali retry gagal. | Tidak |
Pengecualian umum
Pengecualian | Deskripsi |
TimeoutException | TimeoutException dilemparkan ketika ukuran log yang di-cache oleh producer melebihi batas memori dan gagal memperoleh memori yang cukup setelah maxBlockMs milidetik. Jika maxBlockMs diatur ke -1, ini menunjukkan periode blocking tak terbatas, dan TimeoutException tidak terjadi. |
IllegalStateException | Jika producer berada dalam keadaan tertutup (metode close telah dipanggil), maka setiap panggilan berikutnya ke metode send akan menghasilkan IllegalStateException. |
Langkah 6: Dapatkan hasil pengiriman
Karena metode pengiriman producer bersifat asinkron, hasil pengiriman harus diperoleh melalui future yang dikembalikan atau callback yang disediakan.
Future
Metode send mengembalikan ListenableFuture, yang selain metode get standar juga memungkinkan pendaftaran callback setelah selesai. Contoh kode di bawah ini menunjukkan penggunaan ListenableFuture. Daftarkan FutureCallback untuk future dan jalankan di kolam thread EXECUTOR_SERVICE yang disediakan aplikasi. Untuk contoh lengkap, lihat SampleProducerWithFuture.java.
package com.aliyun.openservices.aliyun.log.producer.sample;
import com.aliyun.openservices.aliyun.log.producer.*;
import com.aliyun.openservices.aliyun.log.producer.errors.LogSizeTooLargeException;
import com.aliyun.openservices.aliyun.log.producer.errors.MaxBatchCountExceedException;
import com.aliyun.openservices.aliyun.log.producer.errors.ProducerException;
import com.aliyun.openservices.aliyun.log.producer.errors.ResultFailedException;
import com.aliyun.openservices.aliyun.log.producer.errors.TimeoutException;
import com.aliyun.openservices.log.common.LogItem;
import com.google.common.util.concurrent.FutureCallback;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;
import org.checkerframework.checker.nullness.qual.Nullable;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SampleProducerWithFuture {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleProducerWithFuture.class);
private static final ExecutorService EXECUTOR_SERVICE = Executors
.newFixedThreadPool(Math.max(Runtime.getRuntime().availableProcessors(), 1));
public static void main(String[] args) throws InterruptedException {
Producer producer = Utils.createProducer();
int n = 100;
int size = 20;
// Jumlah log yang telah selesai (baik berhasil dikirim maupun gagal)
final AtomicLong completed = new AtomicLong(0);
for (int i = 0; i < n; ++i) {
List<LogItem> logItems = Utils.generateLogItems(size);
try {
String project = System.getenv("PROJECT");
String logStore = System.getenv("LOG_STORE");
ListenableFuture<Result> f = producer.send(project, logStore, logItems);
Futures.addCallback(
f, new SampleFutureCallback(project, logStore, logItems, completed), EXECUTOR_SERVICE);
} catch (InterruptedException e) {
LOGGER.warn("Thread saat ini telah diinterupsi selama pengiriman log.");
} catch (Exception e) {
if (e instanceof MaxBatchCountExceedException) {
LOGGER.error("Log melebihi jumlah batch maksimum, e={}", e);
} else if (e instanceof LogSizeTooLargeException) {
LOGGER.error("Ukuran log lebih besar dari ukuran maksimum yang diizinkan, e={}", e);
} else if (e instanceof TimeoutException) {
LOGGER.error("Waktu yang dibutuhkan untuk mengalokasikan memori untuk log telah terlampaui., e={}", e);
} else {
LOGGER.error("Gagal mengirim log, e=", e);
}
}
}
Utils.doSomething();
try {
producer.close();
} catch (InterruptedException e) {
LOGGER.warn("Thread saat ini telah diinterupsi saat menutup.");
} catch (ProducerException e) {
LOGGER.info("Gagal menutup producer, e=", e);
}
EXECUTOR_SERVICE.shutdown();
while (!EXECUTOR_SERVICE.isTerminated()) {
EXECUTOR_SERVICE.awaitTermination(100, TimeUnit.MILLISECONDS);
}
LOGGER.info("Semua log selesai, completed={}", completed.get());
}
private static final class SampleFutureCallback implements FutureCallback<Result> {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleFutureCallback.class);
private final String project;
private final String logStore;
private final List<LogItem> logItems;
private final AtomicLong completed;
SampleFutureCallback(
String project, String logStore, List<LogItem> logItems, AtomicLong completed) {
this.project = project;
this.logStore = logStore;
this.logItems = logItems;
this.completed = completed;
}
@Override
public void onSuccess(@Nullable Result result) {
LOGGER.info("Berhasil mengirim log.");
completed.getAndIncrement();
}
@Override
public void onFailure(Throwable t) {
if (t instanceof ResultFailedException) {
Result result = ((ResultFailedException) t).getResult();
LOGGER.error(
"Gagal mengirim log, project={}, logStore={}, result={}", project, logStore, result);
} else {
LOGGER.error("Gagal mengirim log, e=", t);
}
completed.getAndIncrement();
}
}
}Callback
Callback dieksekusi oleh thread internal producer, dan ruang data hanya dilepaskan setelah selesai. Untuk mencegah pemblokiran producer dan penurunan throughput, hindari operasi yang memakan waktu lama di dalam callback. Selain itu, jangan panggil metode send untuk retry di dalam callback. Sebaliknya, tangani retry di callback ListenableFuture. Untuk contoh lengkap, lihat SampleProducerWithCallback.java.
package com.aliyun.openservices.aliyun.log.producer.sample;
import com.aliyun.openservices.aliyun.log.producer.Callback;
import com.aliyun.openservices.aliyun.log.producer.Producer;
import com.aliyun.openservices.aliyun.log.producer.Result;
import com.aliyun.openservices.aliyun.log.producer.errors.LogSizeTooLargeException;
import com.aliyun.openservices.aliyun.log.producer.errors.ProducerException;
import com.aliyun.openservices.aliyun.log.producer.errors.TimeoutException;
import com.aliyun.openservices.log.common.LogItem;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class SampleProducerWithCallback {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleProducerWithCallback.class);
private static final ExecutorService EXECUTOR_SERVICE = Executors.newFixedThreadPool(10);
public static void main(String[] args) throws InterruptedException {
final Producer producer = Utils.createProducer();
int nTask = 100;
// Nomor urut monotonik yang akan dimasukkan ke dalam data setiap log
final AtomicLong sequenceNumber = new AtomicLong(0);
// Jumlah log yang telah selesai (baik berhasil dikirim maupun gagal)
final AtomicLong completed = new AtomicLong(0);
final CountDownLatch latch = new CountDownLatch(nTask);
for (int i = 0; i < nTask; ++i) {
EXECUTOR_SERVICE.submit(
new Runnable() {
@Override
public void run() {
LogItem logItem = Utils.generateLogItem(sequenceNumber.getAndIncrement());
try {
String project = System.getenv("PROJECT");
String logStore = System.getenv("LOG_STORE");
producer.send(
project,
logStore,
Utils.getTopic(),
Utils.getSource(),
logItem,
new SampleCallback(project, logStore, logItem, completed));
} catch (InterruptedException e) {
LOGGER.warn("Thread saat ini telah diinterupsi selama pengiriman log.");
} catch (Exception e) {
if (e instanceof LogSizeTooLargeException) {
LOGGER.error(
"Ukuran log lebih besar dari ukuran maksimum yang diizinkan, e={}", e);
} else if (e instanceof TimeoutException) {
LOGGER.error(
"Waktu yang dibutuhkan untuk mengalokasikan memori untuk log telah terlampaui., e={}", e);
} else {
LOGGER.error("Gagal mengirim log, logItem={}, e=", logItem, e);
}
} finally {
latch.countDown();
}
}
});
}
latch.await();
EXECUTOR_SERVICE.shutdown();
Utils.doSomething();
try {
producer.close();
} catch (InterruptedException e) {
LOGGER.warn("Thread saat ini telah diinterupsi saat menutup.");
} catch (ProducerException e) {
LOGGER.info("Gagal menutup producer, e=", e);
}
LOGGER.info("Semua log selesai, completed={}", completed.get());
}
private static final class SampleCallback implements Callback {
private static final Logger LOGGER = LoggerFactory.getLogger(SampleCallback.class);
private final String project;
private final String logStore;
private final LogItem logItem;
private final AtomicLong completed;
SampleCallback(String project, String logStore, LogItem logItem, AtomicLong completed) {
this.project = project;
this.logStore = logStore;
this.logItem = logItem;
this.completed = completed;
}
@Override
public void onCompletion(Result result) {
try {
if (result.isSuccessful()) {
LOGGER.info("Berhasil mengirim log.");
} else {
LOGGER.error(
"Gagal mengirim log, project={}, logStore={}, logItem={}, result={}",
project,
logStore,
logItem.ToJsonString(),
result);
}
} finally {
completed.getAndIncrement();
}
}
}
}Langkah 7: Tutup producer
Saat producer tidak lagi diperlukan atau proses akan keluar, tutup producer untuk memastikan semua data yang di-cache diproses. Dua mode shutdown didukung: shutdown aman dan shutdown terbatas.
Shutdown aman
Shutdown aman direkomendasikan dalam sebagian besar kasus, menggunakan metode close(). Metode close() menunggu semua data yang di-cache diproses, thread dihentikan, callback dieksekusi, dan future diselesaikan sebelum mengembalikan hasil.
Meskipun metode ini menunggu semua data diproses, metode ini cepat mengembalikan hasil jika callback tidak diblokir, dan batch segera diproses tanpa retry setelah penutupan.
Shutdown terbatas
Untuk pengembalian cepat ketika callback mungkin memblokir, gunakan shutdown terbatas dengan metode close(long timeoutMs). Jika producer belum sepenuhnya ditutup setelah timeoutMs yang ditentukan, IllegalStateException akan dilemparkan, menunjukkan potensi kehilangan data dan callback yang tidak dieksekusi.
FAQ
Apakah ada batasan pada jumlah operasi penulisan data?
Jumlah dan ukuran operasi baca-tulis di SLS dibatasi. Untuk informasi lebih lanjut, lihat Data read and write.
Sumber daya dasar SLS, termasuk jumlah project, logstore, shard, LogtailConfig, machine group, ukuran LogItem tunggal, panjang LogItem (Key), dan panjang LogItem (Value), semuanya dibatasi. Untuk informasi lebih lanjut, lihat Basic resource limits.
Apa yang harus saya lakukan jika tidak ada data yang ditulis ke SLS?
Jika tidak ada data yang ditulis ke SLS, ikuti langkah troubleshooting berikut:
Verifikasi bahwa versi paket JAR
aliyun-log-producer,aliyun-log, danprotobuf-javadalam proyek Anda sesuai dengan yang ditentukan dalam dokumentasi instalasi. Tingkatkan versinya jika perlu.Metode send dari Aliyun Log Java Producer bersifat asinkron, sehingga data yang dikembalikan tidak langsung tersedia. Gunakan objek Callback atau Future untuk menentukan penyebab kegagalan pengiriman.
Jika metode onCompletion dari antarmuka Callback tidak dipanggil, pastikan metode
producer.close()dipanggil sebelum terminasi program. Karena transmisi data ditangani oleh thread backend, memanggilproducer.close()memastikan tidak ada kehilangan data.Aliyun Log Java Producer menggunakan framework logging SLF4J untuk mengembalikan perilaku runtime. Konfigurasikan framework logging dalam program Anda dan aktifkan logging level DEBUG untuk memeriksa log ERROR.
Jika masalah tetap berlanjut setelah Anda menyelesaikan langkah-langkah sebelumnya, kirim tiket.
Referensi
Jika panggilan API gagal, respons dari Simple Log Service mencakup kode kesalahan. Untuk informasi lebih lanjut, lihat Error codes.
Selain SDK native-nya, Simple Log Service juga mendukung SDK Alibaba Cloud umum. Untuk informasi lebih lanjut, lihat Simple Log Service_SDK Center_Alibaba Cloud OpenAPI Explorer.
Simple Log Service menyediakan command-line interface (CLI) untuk konfigurasi otomatis. Untuk informasi lebih lanjut, lihat Overview of Simple Log Service CLI.
Untuk contoh kode lebih lanjut, lihat Alibaba Cloud Simple Log Service SDK for Java di GitHub.