全部产品
Search
文档中心

Simple Log Service:Gunakan Aliyun Log Java Producer untuk menulis data log ke Simple Log Service

更新时间:Dec 24, 2025

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

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

image

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.

Catatan

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:

  1. Verifikasi bahwa versi paket JAR aliyun-log-producer, aliyun-log, dan protobuf-java dalam proyek Anda sesuai dengan yang ditentukan dalam dokumentasi instalasi. Tingkatkan versinya jika perlu.

  2. 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.

  3. Jika metode onCompletion dari antarmuka Callback tidak dipanggil, pastikan metode producer.close() dipanggil sebelum terminasi program. Karena transmisi data ditangani oleh thread backend, memanggil producer.close() memastikan tidak ada kehilangan data.

  4. 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.

  5. Jika masalah tetap berlanjut setelah Anda menyelesaikan langkah-langkah sebelumnya, kirim tiket.

Referensi