全部产品
Search
文档中心

Simple Log Service:Memulai Cepat untuk Android SDK

更新时间:Oct 30, 2025

Topik ini menjelaskan cara memulai dengan Simple Log Service (SLS) Android SDK untuk mengumpulkan log.

Prasyarat

Instal Android SDK.

Panduan Cepat

Contoh berikut menunjukkan cara menginisialisasi SDK dan memanggil metode addLog untuk mengirim log.

Penting
  • SDK mendukung inisialisasi beberapa instans. Setiap instans LogProducerConfig harus dipasangkan dengan instans LogProducerClient yang sesuai.

  • Saat Anda mengirim log ke SLS, Anda harus menggunakan AccessKey dari Akun Alibaba Cloud atau Pengguna Resource Access Management (RAM) untuk otentikasi dan proteksi anti-pemalsuan. Untuk mencegah risiko keamanan menyimpan AccessKey di aplikasi seluler Anda, kami sarankan Anda menggunakan layanan unggah log langsung seluler untuk mengonfigurasi AccessKey. Untuk informasi lebih lanjut, lihat Mengumpulkan log - Membangun layanan unggah log langsung seluler.

// Kami sarankan Anda menyimpan instans LogProducerConfig dan LogProducerClient secara global.
private LogProducerConfig config = null;
private LogProducerClient client = null;

/**
 * Inisialisasi SDK.
 */

private void initProducer() {
    try {
        // Titik akhir layanan SLS. Titik akhir harus dimulai dengan https:// atau http://.
        final String endpoint = "your endpoint";
        final String project = "your project";
        final String logstore = "your logstore";

        config = new LogProducerConfig(context, endpoint, project, logstore);
        // Atur topik log.
        config.setTopic("example_topic");
        // Atur informasi tag. Tag ini ditambahkan ke setiap log.
        config.addTag("example", "example_tag");

        // Menentukan apakah akan membuang log yang kedaluwarsa. 0: Jangan buang log. Waktu log diubah menjadi waktu saat ini. 1: Buang log. Nilai default: 1.
        config.setDropDelayLog(0);
        // Menentukan apakah akan membuang log yang gagal otentikasi. 0: Jangan buang log. 1: Buang log. Nilai default: 0.
        config.setDropUnauthorizedLog(0);

        // LogProducerCallback adalah konfigurasi opsional. Jika Anda tidak perlu mengikuti status sukses atau gagal pengiriman log, Anda tidak perlu mendaftarkan callback.
        // Untuk mengonfigurasi AccessKey secara dinamis, atur LogProducerCallback dan perbarui AccessKey saat metode onCall dipanggil.
        final LogProducerCallback callback = new LogProducerCallback() {
            @Override
            public void onCall(int resultCode, String reqId, String errorMessage, int logBytes, int compressedBytes) {
                // resultCode: kode status. Untuk informasi lebih lanjut, lihat Kode kesalahan.
                // reqId: ID permintaan. Parameter ini sudah tidak digunakan.
                // errorMessage: informasi kegagalan.
                // logBytes: ukuran log asli dalam byte.
                // compressedBytes: ukuran log terkompresi dalam byte.

                final LogProducerResult result = LogProducerResult.fromInt(resultCode);
                if (LogProducerResult.LOG_PRODUCER_SEND_UNAUTHORIZED == result || LogProducerResult.LOG_PRODUCER_PARAMETERS_INVALID == result) {
                    // Perbarui AccessKey atau parameter inisialisasi SDK.
                }
            }
        };
      
        // Untuk mengikuti status sukses atau gagal pengiriman log, Anda harus melewati callback sebagai parameter kedua.
        client = new LogProducerClient(config, callback);
    } catch (LogProducerException e) {
        e.printStackTrace();
    }
}
// Meminta informasi AccessKey.
private void requestAccessKey() {
    // Kami sarankan Anda menggunakan layanan unggah log langsung seluler untuk mengonfigurasi informasi AccessKey.
    // ...

    // Setelah Anda mendapatkan informasi AccessKey, perbarui itu.
    updateAccessKey(accessKeyId, accessKeySecret, securityToken);
}

// Perbarui informasi AccessKey.
private void updateAccessKey(String accessKeyId, String accessKeySecret, String securityToken) {
    // AccessKey yang diperoleh dari Security Token Service (STS) berisi securityToken. Anda harus memperbarui AccessKey dengan cara berikut.
    if (null != securityToken && !"".equals(securityToken)) {
        config.resetSecurityToken(accessKeyId, accessKeySecret, securityToken);
    } else {
        // Jika AccessKey tidak diperoleh dari STS, perbarui AccessKey dengan cara berikut.
        config.setAccessKeyId(accessKeyId);
        config.setAccessKeySecret(accessKeySecret);
    }
}

/**
 * Laporkan log.
 */
public void addLog() {
    Log log = new Log();
    // Sesuaikan bidang yang akan dilaporkan sesuai kebutuhan.
    log.putContent("content_key_1", 123456);
    log.putContent("content_key_2", 23.34f);
    log.putContent("content_key_3", "Chinese️");
    log.putContent(null, "null");
    log.putContent("null", (String) null);
    client.addLog(log);
}

Fitur lanjutan

Konfigurasi Parameter Dinamis

Android SDK mendukung konfigurasi dinamis parameter seperti Endpoint, ProjectName, logstore, dan AccessKey.

  • Konfigurasikan Endpoint, ProjectName, dan logstore secara dinamis.

    // Konfigurasikan parameter seperti Endpoint, ProjectName, dan logstore bersama-sama atau terpisah.
    // Perbarui endpoint.
    config.setEndpoint("your new-endpoint");
    // Perbarui nama proyek.
    config.setProject("your new-project");
    // Perbarui nama logstore.
    config.setLogstore("your new-logstore");
  • Konfigurasikan AccessKey secara dinamis.

    Saat Anda mengonfigurasi AccessKey secara dinamis, kami sarankan Anda menggunakannya dengan LogProducerCallback.

    // Jika Anda telah menginisialisasi LogProducerCallback saat Anda menginisialisasi LogProducerClient, abaikan kode berikut.
    final LogProducerCallback callback = new LogProducerCallback() {
        @Override
        public void onCall(int resultCode, String reqId, String errorMessage, int logBytes, int compressedBytes) {
            // resultCode: kode status. Untuk informasi lebih lanjut, lihat Kode kesalahan.
            // reqId: ID permintaan. Parameter ini sudah tidak digunakan.
            // errorMessage: informasi kegagalan.
            // logBytes: ukuran log asli dalam byte.
            // compressedBytes: ukuran log terkompresi dalam byte.
    
            final LogProducerResult result = LogProducerResult.fromInt(resultCode);
            if (LogProducerResult.LOG_PRODUCER_SEND_UNAUTHORIZED == result || LogProducerResult.LOG_PRODUCER_PARAMETERS_INVALID == result) {
                // Anda perlu memperbarui AccessKey atau parameter inisialisasi SDK.
                requestAccessKey();
            }
        }
    };
    
    // Untuk mengikuti status sukses atau gagal pengiriman log, Anda harus melewati callback sebagai parameter kedua.
    client = new LogProducerClient(config, callback);
    
    // Meminta informasi AccessKey.
    private void requestAccessKey() {
        // Kami sarankan Anda menggunakan layanan unggah log langsung seluler untuk mengonfigurasi informasi AccessKey.
        // ...
    
        // Setelah Anda mendapatkan informasi AccessKey, perbarui itu.
        updateAccessKey(accessKeyId, accessKeySecret, securityToken);
    }
    
    // Perbarui informasi AccessKey.
    private void updateAccessKey(String accessKeyId, String accessKeySecret, String securityToken) {
        // AccessKey yang diperoleh dari STS berisi securityToken. Anda harus memperbarui AccessKey dengan cara berikut.
        if (null != securityToken && !"".equals(securityToken)) {
            config.resetSecurityToken(accessKeyId, accessKeySecret, securityToken);
        } else {
            // Jika AccessKey tidak diperoleh dari STS, perbarui AccessKey dengan cara berikut.
            config.setAccessKeyId(accessKeyId);
            config.setAccessKeySecret(accessKeySecret);
        }
    }
  • Konfigurasikan sumber, topik, dan tag secara dinamis.

    Penting

    Anda tidak dapat mengatur sumber, topik, atau tag untuk jenis log tertentu. Jika Anda mengatur parameter ini, mereka diterapkan ke semua log yang menunggu dikirim ke SLS. Ini berarti bahwa jika Anda menggunakan sumber, topik, dan tag untuk melacak jenis log tertentu, hasilnya mungkin tidak akurat. Kami sarankan Anda menambahkan bidang saat Anda membuat log untuk mengidentifikasi jenis log yang sesuai.

    // Atur sumber log.
    config.setSource("your new-source");
    // Atur topik log.
    config.setTopic("your new-topic");
    // Atur informasi tag. Tag ini ditambahkan ke setiap log.
    config.addTag("test", "your new-tag");

Unggah yang dapat dilanjutkan

Android SDK mendukung unggah yang dapat dilanjutkan. Setelah Anda mengaktifkan fitur ini, log yang ditambahkan menggunakan metode addLog disimpan ke file binlog lokal. Data lokal ini hanya dihapus setelah log berhasil dikirim. Ini memastikan bahwa log diunggah setidaknya sekali.

Tambahkan kode berikut selama inisialisasi SDK untuk mengaktifkan unggah yang dapat dilanjutkan.

Penting
  • Saat Anda menginisialisasi beberapa instans LogProducerConfig, metode setPersistentFilePath kelas LogProducerConfig harus diatur ke nilai unik untuk setiap instans.

  • Jika aplikasi Anda memiliki beberapa proses dan fitur unggah yang dapat dilanjutkan diaktifkan, Anda harus menginisialisasi SDK hanya di proses utama. Jika proses anak juga perlu mengumpulkan data, Anda harus memastikan bahwa jalur file yang ditentukan dalam metode setPersistentFilePath unik untuk setiap proses. Jika tidak, data log mungkin hilang atau rusak.

  • Saat Anda menggunakan SDK, hindari menginisialisasi ulang LogProducerConfig di beberapa thread.

private void initProducer() {
    // 1: mengaktifkan fitur unggah yang dapat dilanjutkan. 0: menonaktifkan fitur. Nilai default: 0.
    config.setPersistent(1);
    // Nama file persistensi. Pastikan folder tempat file berada telah dibuat.
    final String persistentFilePath = getFilesDir() + File.separator + "log_data";
    config.setPersistentFilePath(persistentFilePath);
    // Jumlah file persistensi bergulir. Kami sarankan Anda mengatur parameter ini ke 10.
    config.setPersistentMaxFileCount(10);
    // Ukuran setiap file persistensi. Unit: byte. Formatnya adalah N*1024*1024. Kami sarankan Anda mengatur N ke nilai dari 1 hingga 10.
    config.setPersistentMaxFileSize(N*1024*1024);
    // Jumlah maksimum log yang dapat disimpan secara lokal. Kami sarankan Anda tidak mengatur parameter ini ke nilai lebih besar dari 1.048.576. Nilai default: 65.536.
    config.setPersistentMaxLogCount(65536);
}

Aturan Pengaburan

-keep class com.aliyun.sls.android.producer.** { *; }
-keep interface com.aliyun.sls.android.producer.** { *; }

Izin Android

<uses-permission android:name="android.permission.INTERNET" />

Parameter konfigurasi

Semua parameter konfigurasi disediakan oleh kelas LogProducerConfig. Tabel berikut menjelaskan parameter tersebut.

Parameter

Tipe data

Deskripsi

setTopic

String

Mengatur nilai bidang topik. Nilai default adalah string kosong.

addTag

String

Mengatur tag. Formatnya adalah tag:xxxx. Nilai default adalah string kosong.

setSource

String

Mengatur nilai bidang sumber. Nilai default adalah Android.

setPacketLogBytes

Int

Ukuran maksimum setiap paket log yang di-cache. Jika ukuran melebihi batas, log dikirim segera.

Nilai valid: 1 hingga 5.242.880. Nilai default: 1024 × 1024. Unit: byte.

setPacketLogCount

Int

Jumlah maksimum log dalam setiap paket log yang di-cache. Jika jumlah melebihi batas, log dikirim segera.

Nilai valid: 1 hingga 4.096. Nilai default: 1.024.

setPacketTimeout

Int

Periode timeout untuk mengirim log yang di-cache. Jika cache habis waktu, log dikirim segera.

Nilai default: 3.000. Unit: milidetik.

setMaxBufferLimit

Int

Memori maksimum yang dapat digunakan oleh satu instans Producer Client. Jika ukuran cache melebihi batas, antarmuka add_log segera mengembalikan kegagalan.

Nilai default: 64 × 1024 × 1024.

setSendThreadCount

Int

Jumlah thread pengiriman. Jika unggah yang dapat dilanjutkan diaktifkan, parameter ini dipaksa diatur ke 1.

setPersistent

Int

Menentukan apakah akan mengaktifkan fitur unggah yang dapat dilanjutkan.

  • 1: Aktifkan.

  • 0 (default): Nonaktifkan.

setPersistentFilePath

String

Nama file persistensi. Pastikan folder tempat file berada telah dibuat. Saat Anda mengonfigurasi beberapa instans LogProducerConfig, pastikan nama tersebut unik.

Nilai default adalah kosong.

setPersistentForceFlush

Int

Menentukan apakah akan mengaktifkan fitur memaksa flush log setiap kali AddLog dipanggil.

  • 1: Aktifkan. Ini mempengaruhi kinerja. Kami sarankan Anda mengaktifkan fitur ini dengan hati-hati.

  • 0 (default): Nonaktifkan.

Kami sarankan Anda mengaktifkan fitur ini dalam skenario keandalan tinggi.

setPersistentMaxFileCount

Int

Jumlah file persistensi bergulir. Kami sarankan Anda mengatur parameter ini ke 10. Nilai default: 0.

setPersistentMaxFileSize

Int

Ukuran setiap file persistensi. Unit: byte. Formatnya adalah N × 1024 × 1024. Kami sarankan Anda mengatur N ke nilai dari 1 hingga 10.

setPersistentMaxLogCount

Int

Jumlah maksimum log yang dapat disimpan secara lokal. Kami sarankan Anda tidak mengatur parameter ini ke nilai lebih besar dari 1.048.576. Nilai default: 65.536.

setConnectTimeoutSec

Int

Periode timeout koneksi jaringan. Nilai default: 10. Unit: detik.

setSendTimeoutSec

Int

Periode timeout pengiriman log. Nilai default: 15. Unit: detik.

setDestroyFlusherWaitSec

Int

Waktu tunggu maksimum untuk menghancurkan thread flusher. Nilai default: 1. Unit: detik.

setDestroySenderWaitSec

Int

Waktu tunggu maksimum untuk menghancurkan kolam thread pengirim. Nilai default: 1. Unit: detik.

setCompressType

Int

Tipe kompresi untuk pengunggahan data.

  • 0: Tanpa kompresi.

  • 1 (default): Kompresi LZ4.

setNtpTimeOffset

Int

Perbedaan antara waktu perangkat dan waktu standar. Nilainya adalah `Waktu Standar - Waktu Perangkat`. Perbedaan ini biasanya terjadi ketika waktu perangkat klien pengguna tidak disinkronkan. Nilai default: 0. Unit: detik.

setMaxLogDelayTime

Int

Perbedaan antara waktu log dan waktu lokal. Jika perbedaan melebihi nilai yang ditentukan, SDK memproses log berdasarkan opsi setDropDelayLog. Unit: detik. Nilai default: 7.243.600 (7 hari).

setDropDelayLog

Int

Menentukan apakah akan membuang log yang kedaluwarsa melebihi setMaxLogDelayTime.

  • 0 (default): Jangan buang log. Waktu log diubah menjadi waktu saat ini.

  • 1: Buang

setDropUnauthorizedLog

Int

Menentukan apakah akan membuang log yang gagal otentikasi.

  • 0 (default): Jangan buang log.

  • 1: Buang log.

setCallbackFromSenderThread

Boolean

Menentukan apakah akan memanggil balik dari thread pengirim.

  • true (default): Panggil balik dari thread pengirim.

  • false: Panggil balik dari thread utama.

Kode Kesalahan

Semua kode kesalahan didefinisikan dalam enumerasi LogProducerResult. Tabel berikut menjelaskan kode kesalahan tersebut.

Kode Kesalahan

Nilai

Deskripsi

Solusi

LOG_PRODUCER_OK

0

Berhasil.

Tidak berlaku.

LOG_PRODUCER_INVALID

1

SDK dihancurkan atau tidak valid.

  1. Periksa apakah SDK diinisialisasi dengan benar.

  2. Periksa apakah metode destroy() dipanggil.

LOG_PRODUCER_WRITE_ERROR

2

Kesalahan penulisan data terjadi. Penyebab yang mungkin adalah lalu lintas tulis proyek telah mencapai batas atas.

Atur ulang batas atas lalu lintas tulis proyek. Untuk informasi lebih lanjut, lihat Sesuaikan kuota sumber daya.

LOG_PRODUCER_DROP_ERROR

3

Cache disk atau memori penuh, dan log tidak dapat ditulis.

Atur ulang nilai parameter maxBufferLimit, persistentMaxLogCount, dan persistentMaxFileSize dan coba lagi.

LOG_PRODUCER_SEND_NETWORK_ERROR

4

Kesalahan jaringan terjadi.

Periksa konfigurasi Endpoint, Project, dan logstore.

LOG_PRODUCER_SEND_QUOTA_ERROR

5

Lalu lintas tulis proyek telah mencapai batas atas.

Atur ulang batas atas lalu lintas tulis proyek. Untuk informasi lebih lanjut, lihat Sesuaikan kuota sumber daya.

LOG_PRODUCER_SEND_UNAUTHORIZED

6

AccessKey telah kedaluwarsa atau tidak valid, atau kebijakan akses AccessKey dikonfigurasikan secara salah.

Periksa AccessKey.

Pengguna RAM harus memiliki izin untuk mengoperasikan sumber daya SLS. Untuk informasi lebih lanjut, lihat Berikan izin kepada Pengguna RAM.

LOG_PRODUCER_SEND_SERVER_ERROR

7

Kesalahan layanan terjadi.

Kirim tiket untuk menghubungi dukungan teknis.

LOG_PRODUCER_SEND_DISCARD_ERROR

8

Data dibuang. Ini biasanya karena waktu perangkat tidak disinkronkan dengan waktu server.

SDK secara otomatis mengirim ulang data tersebut.

LOG_PRODUCER_SEND_TIME_ERROR

9

Waktu tidak disinkronkan dengan waktu server.

SDK secara otomatis memperbaiki masalah ini.

LOG_PRODUCER_SEND_EXIT_BUFFERED

10

Saat SDK dihancurkan, data yang di-cache belum dilaporkan.

Kami sarankan Anda mengaktifkan fitur unggah yang dapat dilanjutkan untuk mencegah kehilangan data.

LOG_PRODUCER_PARAMETERS_INVALID

11

Parameter inisialisasi SDK tidak valid.

Periksa konfigurasi parameter seperti AccessKey, Endpoint, Project, dan logstore.

LOG_PRODUCER_PERSISTENT_ERROR

99

Gagal menulis data yang di-cache ke disk.

1. Periksa apakah jalur file cache dikonfigurasi dengan benar.

2. Periksa apakah file cache penuh.

3. Periksa apakah ruang disk sistem mencukupi.

FAQ

Mengapa ada log duplikat?

Android SDK mengirim log secara asinkron. Tergantung pada kondisi jaringan, sebuah log mungkin gagal dikirim dan akan dikirim ulang. SDK hanya menganggap operasi pengiriman berhasil ketika kode status 200 dikembalikan. Oleh karena itu, beberapa log mungkin diduplikasi. Kami sarankan Anda menggunakan kueri SQL dan pernyataan analisis untuk menghapus duplikat log.

Jika tingkat duplikasi log tinggi, Anda harus terlebih dahulu memeriksa masalah dalam inisialisasi SDK. Penyebab utama dan solusinya adalah sebagai berikut:

  • Konfigurasi unggah yang dapat dilanjutkan salah

    Jika fitur unggah yang dapat dilanjutkan dikonfigurasi secara salah, pastikan bahwa jalur file yang dilewatkan ke metode setPersistentFilePath bersifat unik secara global.

  • Inisialisasi SDK Berulang

    • Penyebab umum dari inisialisasi SDK berulang adalah implementasi pola singleton yang salah untuk inisialisasi SDK. Kami sarankan Anda menggunakan metode berikut untuk menginisialisasi SDK.

      public class AliyunLogHelper {
          private LogProducerConfig config;
          private LogProducerClient client;
      
          private static class Holder {
              private static final AliyunLogHelper INSTANCE = new AliyunLogHelper();
          }
      
          public static AliyunLogHelper getInstance() {
              return Holder.INSTANCE;
          }
      
          private AliyunLogHelper() {
              initProducer();
          }
      
          private void initProducer() {
              // Ganti kode berikut dengan kode inisialisasi Anda.
              try {
                  config = new LogProducerConfig();
                  client = new LogProducerClient(config);
              } catch (LogProducerException e) {
                  e.printStackTrace();
              }
          }
      
          public void addLog(Log log) {
              if (null == client) {
                  return;
              }
      
              client.addLog(log);
          }
      }
    • Penyebab lain dari inisialisasi SDK berulang adalah penggunaan proses multipel. Kami sarankan Anda menginisialisasi SDK hanya di proses utama. Sebagai alternatif, jika Anda menginisialisasi SDK di proses yang berbeda, Anda harus mengatur nilai unik untuk setPersistentFilePath di setiap proses.

  • Optimasi Konfigurasi untuk Lingkungan Jaringan Lemah

    Jika aplikasi Anda berjalan di lingkungan jaringan lemah, kami sarankan Anda mengoptimalkan parameter konfigurasi SDK seperti yang ditunjukkan dalam contoh berikut.

    // Inisialisasi SDK.
    private void initProducer() {
        // Sesuaikan periode timeout koneksi HTTP dan pengiriman untuk mengurangi tingkat duplikasi log.
        // Sesuaikan periode timeout spesifik sesuai kebutuhan.
        config.setConnectTimeoutSec(20);
        config.setSendTimeoutSec(20);
      
        // Parameter inisialisasi lainnya.
        // ...
    }

Apa yang harus saya lakukan jika log hilang?

Proses pengiriman log bersifat asinkron. Jika aplikasi ditutup sebelum log dikirim, log yang belum dikirim mungkin hilang. Kami sarankan Anda mengaktifkan fitur unggah yang dapat dilanjutkan. Untuk informasi lebih lanjut, lihat Unggah yang Dapat Dilanjutkan.

Apa yang harus saya lakukan jika pelaporan log tertunda?

SDK mengirim log secara asinkron. Log mungkin tidak dikirim segera karena kondisi jaringan atau skenario aplikasi tertentu. Penundaan pada sejumlah kecil perangkat adalah normal. Jika penundaan meluas, periksa kode kesalahan berikut.

Kode Kesalahan

Deskripsi

LOG_PRODUCER_SEND_NETWORK_ERROR

Periksa apakah konfigurasi Endpoint, Project, dan logstore benar.

LOG_PRODUCER_SEND_UNAUTHORIZED

Periksa apakah AccessKey telah kedaluwarsa atau tidak valid, atau apakah kebijakan akses AccessKey dikonfigurasikan dengan benar.

LOG_PRODUCER_SEND_QUOTA_ERROR

Lalu lintas tulis proyek telah mencapai batas atas. Untuk informasi lebih lanjut, lihat Sesuaikan kuota sumber daya.

Apakah Android SDK mendukung pra-penyelesaian DNS dan kebijakan cache?

Contoh berikut menunjukkan cara menggunakan Android SDK, HTTPDNS SDK, dan OkHttp untuk mengimplementasikan pra-resolusi DNS dan kebijakan cache.

  1. Implementasikan antarmuka DNS kustom.

    /**
      * Implementasikan layanan penyelesaian DNS kustom berdasarkan antarmuka Dns OkHttp untuk referensi Anda.
      */
    public class OkHttpDns implements Dns {
      private Context mContext;
    
      public OkHttpDns(Context context) {
        mContext = context;
      }
    
      @Override
      public List<InetAddress> lookup(String host) throws UnknownHostException {
        // !!Catatan!! 
        // Ganti accountId dengan nilai yang Anda peroleh dari layanan HTTPDNS. Untuk informasi lebih lanjut, lihat dokumentasi HTTPDNS.
        HTTPDNSResult httpdnsResult = HttpDns.getService(mContext, accountId)
          .getHttpDnsResultForHostSync(host, RequestIpType.both);
        List<InetAddress> inetAddresses = new ArrayList<>();
        InetAddress address;
        try {
          if (httpdnsResult.getIps() != null) {
            // Proses alamat IPv4.
            for (String ipv4 : httpdnsResult.getIps()) {
              address = InetAddress.getByName(ipv4);
              inetAddresses.add(address);
            }
          }
    
          if (httpdnsResult.getIpv6s() != null) {
            // Proses alamat IPv6.
            for (String ipv6 : httpdnsResult.getIpv6s()) {
              address = InetAddress.getByName(ipv6);
              inetAddresses.add(address);
            }
          }
        } catch (UnknownHostException e) {
    
        }
    
        if (!inetAddresses.isEmpty()) {
          return inetAddresses;
        }
    
        return okhttp3.Dns.SYSTEM.lookup(host);
      }
    }
  2. Implementasikan NetworkInterface kustom.

    /**
       * Implementasikan NetworkInterface dari SDK SLS berdasarkan OkHttp untuk referensi Anda.
       */
    private static class OkHttpNetworkInterface implements LogProducerHttpTool.NetworkInterface {
    
      private OkHttpClient client;
    
      public OkHttpNetworkInterface(Context context) {
        client = new OkHttpClient.Builder()
          .connectTimeout(30, TimeUnit.SECONDS)
          .readTimeout(30, TimeUnit.SECONDS)
          .writeTimeout(30, TimeUnit.SECONDS)
          .dns(new OkHttpDns(context))
          .build();
      }
    
      @Override
      public NetworkResponse send(String urlString, String method, String[] header, byte[] body) {
        // Kami sarankan Anda pertama-tama memanggil implementasi asli SDK dan kemudian melaporkan log menggunakan OkHttp saat pelaporan log gagal.
        LogHttpResponse logHttpResponse = LogProducerHttpTool.android_http_post(urlString, method, header, body);
        if (logHttpResponse.getStatusCode() != -1) {
          NetworkResponse response = new NetworkResponse();
          response.statusCode = logHttpResponse.getStatusCode();
          response.errorMessage = logHttpResponse.getErrorMessage();
          return response;
        }
    
        // Laporkan log menggunakan OkHttp.
        Request.Builder builder = new Request.Builder();
        builder.url(urlString);
        builder.post(RequestBody.create(body));
    
        for (int i = 0; i < header.length; i += 2) {
          builder.addHeader(header[i], header[i + 1]);
        }
    
        // Terlepas dari apakah permintaan berhasil, Anda harus mengembalikan NetworkResponse. Jika tidak, SDK mungkin tidak berjalan seperti yang diharapkan.
        try (okhttp3.Response response = client.newCall(builder.build()).execute()) {
          NetworkResponse httpResponse = new NetworkResponse();
          httpResponse.statusCode = response.code();
          httpResponse.headers = response.headers().toMultimap();
          httpResponse.errorMessage = response.message();
    
          return httpResponse;
        } catch (IOException e) {
          NetworkResponse httpResponse = new NetworkResponse();
          httpResponse.statusCode = -1;
          httpResponse.headers = null;
          httpResponse.errorMessage = e.getLocalizedMessage();
    
          return httpResponse;
        }
      }
    
    }
    
  3. Inisialisasi SDK SLS.

    public class AliyunSLS {
      private void initSLS(Context context) {
        // Atur NetworkInterface kustom untuk SDK SLS.
        // !!!Catatan!!!
        // Pengaturan ini berlaku untuk semua instans SDK SLS.
        LogProducerHttpTool.setNetworkInterface(new OkHttpNetworkInterface(context));
    
        // Inisialisasi SDK SLS.
        initProducer();
      }
    
      private void initProducer() {
        // Implementasikan inisialisasi LogProducerConfig dan LogProducerClient di sini.
        // ...
      }
    }