All Products
Search
Document Center

Simple Log Service:Panduan cepat untuk Android SDK

Last Updated:Jun 17, 2026

Gunakan Simple Log Service (SLS) Android SDK untuk mengumpulkan dan mengunggah log dari aplikasi Android Anda.

Prasyarat

Instal Android SDK.

Panduan cepat

Inisialisasi SDK dan panggil metode addLog untuk mengirimkan log.

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

  • Mengirimkan log ke SLS memerlukan AccessKey dari akun Alibaba Cloud atau pengguna Resource Access Management (RAM) untuk otentikasi dan proteksi anti-pemalsuan. Untuk menghindari risiko keamanan menyimpan AccessKey di aplikasi seluler Anda, kami menyarankan agar Anda menggunakan layanan unggah langsung log seluler untuk mengonfigurasi AccessKey. Untuk informasi selengkapnya, lihat Kumpulkan log - Bangun layanan unggah langsung log seluler.

// Kami menyarankan agar 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 melacak status keberhasilan atau kegagalan 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 selengkapnya, lihat Kode kesalahan.
                // reqId: ID permintaan. Parameter ini sudah tidak digunakan lagi.
                // 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 melacak status keberhasilan atau kegagalan pengiriman log, Anda harus meneruskan callback sebagai parameter kedua.
        client = new LogProducerClient(config, callback);
    } catch (LogProducerException e) {
        e.printStackTrace();
    }
}
// Meminta informasi AccessKey.
private void requestAccessKey() {
    // Kami menyarankan agar Anda menggunakan layanan unggah langsung log seluler untuk mengonfigurasi informasi AccessKey.
    // ...

    // Setelah Anda memperoleh informasi AccessKey, perbarui informasi tersebut.
    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 secara dinamis

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

  • Konfigurasi dinamis Endpoint, ProjectName, dan Logstore.

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

    Saat mengonfigurasi AccessKey secara dinamis, kami menyarankan agar Anda menggunakannya bersama LogProducerCallback.

    // Jika Anda telah menginisialisasi LogProducerCallback saat 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 selengkapnya, lihat Kode kesalahan.
            // reqId: ID permintaan. Parameter ini sudah tidak digunakan lagi.
            // 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 melacak status keberhasilan atau kegagalan pengiriman log, Anda harus meneruskan callback sebagai parameter kedua.
    client = new LogProducerClient(config, callback);
    
    // Meminta informasi AccessKey.
    private void requestAccessKey() {
        // Kami menyarankan agar Anda menggunakan layanan unggah langsung log seluler untuk mengonfigurasi informasi AccessKey.
        // ...
    
        // Setelah Anda memperoleh informasi AccessKey, perbarui informasi tersebut.
        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);
        }
    }
  • Konfigurasi dinamis source, topic, dan tag.

    Penting

    Anda tidak dapat mengatur source, topic, atau tag untuk tipe log tertentu. Parameter ini berlaku untuk semua log yang menunggu dikirim ke SLS. Jika Anda menggunakan source, topic, dan tag untuk melacak tipe log tertentu, hasilnya mungkin tidak akurat. Kami menyarankan agar Anda menambahkan bidang saat membuat log untuk mengidentifikasi tipe log tersebut.

    // Atur source 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 hanya dihapus setelah log berhasil dikirim, memastikan pengiriman setidaknya sekali (at-least-once delivery).

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

Penting
  • Saat Anda menginisialisasi beberapa instans LogProducerConfig, nilai setPersistentFilePath pada setiap instans harus diatur ke nilai yang unik.

  • Jika aplikasi Anda menggunakan beberapa proses dengan fitur unggah yang dapat dilanjutkan diaktifkan, inisialisasi SDK hanya di proses utama. Jika proses anak juga perlu mengumpulkan data, pastikan bahwa path file yang ditentukan dalam setPersistentFilePath unik untuk setiap proses. Jika tidak, data log mungkin hilang atau rusak.

  • Saat 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 menyarankan agar Anda mengatur parameter ini ke 10.
    config.setPersistentMaxFileCount(10);
    // Ukuran setiap file persistensi. Satuan: byte. Formatnya adalah N*1024*1024. Kami menyarankan agar Anda mengatur N ke nilai antara 1 hingga 10.
    config.setPersistentMaxFileSize(N*1024*1024);
    // Jumlah maksimum log yang dapat di-cache secara lokal. Kami menyarankan agar Anda tidak mengatur parameter ini lebih dari 1.048.576. Nilai default: 65.536.
    config.setPersistentMaxLogCount(65536);
}

Aturan obfuskasi

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

Parameter

Tipe data

Deskripsi

setTopic

String

Mengatur nilai bidang topic. Nilai default adalah string kosong.

addTag

String

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

setSource

String

Mengatur nilai bidang source. Nilai default adalah Android.

setPacketLogBytes

Int

Ukuran maksimum setiap paket log yang di-cache. Log dikirim segera ketika batas ini terlampaui.

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

setPacketLogCount

Int

Jumlah maksimum log dalam setiap paket log yang di-cache. Log dikirim segera ketika batas ini terlampaui.

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

setPacketTimeout

Int

Periode timeout untuk log yang di-cache. Log dikirim segera ketika timeout ini berakhir.

Nilai default: 3.000. Satuan: milidetik.

setMaxBufferLimit

Int

Memori maksimum yang dapat digunakan oleh satu instans Producer Client. Saat batas ini terlampaui, antarmuka add_log langsung mengembalikan kegagalan.

Nilai default: 64 × 1024 × 1024.

setSendThreadCount

Int

Jumlah thread pengiriman. Jika unggah yang dapat dilanjutkan diaktifkan, parameter ini dipaksakan menjadi 1.

setPersistent

Int

Menentukan apakah akan mengaktifkan fitur unggah yang dapat dilanjutkan.

  • 1: Aktifkan.

  • 0 (default): Nonaktifkan.

setPersistentFilePath

String

Nama file persistensi. Pastikan folder induknya ada. Saat mengonfigurasi multiple instans LogProducerConfig, setiap nama harus unik.

Nilai default kosong.

setPersistentForceFlush

Int

Menentukan apakah akan melakukan flush log ke disk setiap kali AddLog dipanggil.

  • 1: Aktifkan. Ini memengaruhi performa. Aktifkan dengan hati-hati.

  • 0 (default): Nonaktifkan.

Aktifkan fitur ini dalam skenario dengan keandalan tinggi.

setPersistentMaxFileCount

Int

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

setPersistentMaxFileSize

Int

Ukuran setiap file persistensi. Satuan: byte. Formatnya adalah N × 1024 × 1024. Kami menyarankan agar Anda mengatur N ke nilai antara 1 hingga 10.

setPersistentMaxLogCount

Int

Jumlah maksimum log yang dapat di-cache secara lokal. Kami menyarankan agar Anda tidak mengatur parameter ini lebih dari 1.048.576. Nilai default: 65.536.

setConnectTimeoutSec

Int

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

setSendTimeoutSec

Int

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

setDestroyFlusherWaitSec

Int

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

setDestroySenderWaitSec

Int

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

setCompressType

Int

Jenis kompresi untuk pengunggahan data.

  • 0: Tidak ada kompresi.

  • 1 (default): Kompresi LZ4.

setNtpTimeOffset

Int

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

setMaxLogDelayTime

Int

Selisih antara waktu log dan waktu lokal. Jika selisih melebihi nilai ini, SDK menangani log berdasarkan pengaturan setDropDelayLog. Satuan: detik. Nilai default: 7.243.600 (7 hari).

setDropDelayLog

Int

Menentukan apakah akan membuang log kedaluwarsa yang 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.

setCallbackFromSenderThread

Boolean

Menentukan apakah akan melakukan callback dari thread pengirim.

  • true (default): Callback dari thread pengirim.

  • false: Callback dari thread utama.

Kode kesalahan

Semua kode kesalahan didefinisikan dalam enumerasi LogProducerResult.

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

Terjadi kesalahan penulisan data. Trafik penulisan proyek mungkin telah mencapai batas atas.

Sesuaikan batas atas trafik penulisan proyek. Untuk informasi selengkapnya, lihat Sesuaikan kuota sumber daya.

LOG_PRODUCER_DROP_ERROR

3

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

Sesuaikan nilai parameter maxBufferLimit, persistentMaxLogCount, dan persistentMaxFileSize, lalu coba lagi.

LOG_PRODUCER_SEND_NETWORK_ERROR

4

Terjadi kesalahan jaringan.

Periksa konfigurasi Endpoint, Project, dan logstore.

LOG_PRODUCER_SEND_QUOTA_ERROR

5

Trafik penulisan proyek telah mencapai batas atas.

Sesuaikan batas atas trafik penulisan proyek. Untuk informasi selengkapnya, lihat Sesuaikan kuota sumber daya.

LOG_PRODUCER_SEND_UNAUTHORIZED

6

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

Periksa AccessKey.

Pengguna RAM harus memiliki izin untuk mengoperasikan resource SLS. Untuk informasi selengkapnya, lihat Berikan izin kepada pengguna RAM.

LOG_PRODUCER_SEND_SERVER_ERROR

7

Terjadi kesalahan layanan.

Kirimkan tiket untuk menghubungi dukungan teknis.

LOG_PRODUCER_SEND_DISCARD_ERROR

8

Data dibuang. Hal ini biasanya karena waktu perangkat tidak tersinkronisasi dengan waktu server.

SDK secara otomatis mengirim ulang data.

LOG_PRODUCER_SEND_TIME_ERROR

9

Waktu tidak tersinkronisasi 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 menyarankan agar 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 path file cache dikonfigurasi dengan benar.

2. Periksa apakah file cache penuh.

3. Periksa apakah disk space sistem cukup.

FAQ

Mengapa ada log duplikat?

Android SDK mengirimkan log secara asinkron. Karena kondisi jaringan, log mungkin gagal dikirim dan dikirim ulang. SDK hanya menganggap operasi pengiriman berhasil ketika kode status 200 dikembalikan, sehingga beberapa log mungkin diduplikasi. Kami menyarankan agar Anda menggunakan kueri SQL dan pernyataan analisis untuk menghapus duplikat log.

Jika laju duplikasi log tinggi, periksa masalah pada inisialisasi SDK. Penyebab umum dan solusinya:

  • Konfigurasi unggah yang dapat dilanjutkan salah

    Jika konfigurasi unggah yang dapat dilanjutkan salah, pastikan bahwa path file yang diteruskan ke metode setPersistentFilePath bersifat unik secara global.

  • Inisialisasi SDK berulang

    • Penyebab umum adalah implementasi pola singleton yang salah untuk inisialisasi SDK. Kami menyarankan pendekatan berikut.

      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 adalah penggunaan beberapa proses. Inisialisasi SDK hanya di proses utama. Jika Anda menginisialisasi SDK di proses yang berbeda, atur nilai unik untuk setPersistentFilePath di setiap proses.

  • Optimasi konfigurasi untuk lingkungan jaringan lemah

    Jika aplikasi Anda berjalan di lingkungan jaringan lemah, optimalkan parameter konfigurasi SDK seperti pada contoh berikut.

    // Inisialisasi SDK.
    private void initProducer() {
        // Sesuaikan periode timeout koneksi dan pengiriman HTTP untuk mengurangi laju 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?

Pengiriman log bersifat asinkron. Jika aplikasi ditutup sebelum log dikirim, log yang belum terkirim mungkin hilang. Kami menyarankan agar Anda mengaktifkan fitur unggah yang dapat dilanjutkan. Untuk informasi selengkapnya, lihat Unggah yang dapat dilanjutkan.

Apa yang harus saya lakukan jika pelaporan log tertunda?

SDK mengirimkan log secara asinkron. Log mungkin tidak dikirim segera karena kondisi jaringan atau skenario aplikasi tertentu. Penundaan pada sejumlah kecil perangkat adalah hal yang normal. Jika penundaan tersebar luas, 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 dikonfigurasi dengan benar.

LOG_PRODUCER_SEND_QUOTA_ERROR

Trafik penulisan proyek telah mencapai batas atas. Untuk informasi selengkapnya, lihat Sesuaikan kuota sumber daya.

Apakah Android SDK mendukung kebijakan pre-parsing DNS dan cache?

Gunakan Android SDK, HTTPDNS SDK, dan OkHttp untuk mengimplementasikan kebijakan pre-resolution DNS dan cache.

  1. Implementasikan antarmuka DNS kustom.

    /**
      * Implementasikan layanan parsing DNS kustom berdasarkan antarmuka Dns OkHttp sebagai 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 selengkapnya, 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 SDK SLS berdasarkan OkHttp sebagai 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 menyarankan agar Anda terlebih dahulu memanggil implementasi asli SDK, lalu laporkan log menggunakan OkHttp ketika 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 atau tidak, 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.
        // ...
      }
    }