All Products
Search
Document Center

ApsaraVideo VOD:Sistem Logging

Last Updated:Sep 10, 2026

Topik ini memperkenalkan konsep inti, fitur, dan penggunaan sistem logging AliPlayerKit, yaitu LogHub.

Konsep

Apa itu LogHub?

LogHub adalah titik masuk terpadu untuk seluruh output log dalam framework PlayerKit. Ini merupakan kelas utilitas statis yang menyediakan fungsionalitas logging yang konsisten.

LogHub membungkus API Log native Android, mempertahankan semua kemampuan aslinya sekaligus menambahkan fitur inti berikut:

Kemampuan

Deskripsi

Log toggle

Mengontrol apakah log di-output atau tidak.

Console toggle

Mengontrol apakah log di-output ke Logcat.

Level filtering

Hanya meng-output log pada level yang ditentukan atau lebih tinggi.

Listener mechanism

Mendukung pendengar eksternal untuk penanganan log kustom, seperti menulis ke file.

Apa itu log listener?

LogHubListener adalah antarmuka callback yang menerima log dari LogHub. Implementasikan antarmuka ini untuk menyesuaikan cara penanganan log, misalnya:

  • Menulis log ke file untuk dibagikan kepada dukungan teknis saat troubleshooting.

  • Mengunggah log ke server jarak jauh untuk pengumpulan terpusat.

  • Menampilkan log di UI untuk panel debugging.

Fitur

Masalah yang diselesaikan

  • Log tersebar di seluruh basis kode, sehingga sulit dikelola dan difilter.

  • Build rilis perlu menonaktifkan log debug, tetapi tidak tersedia toggle terpadu.

  • Tidak ada dukungan log file bawaan untuk troubleshooting.

  • Log SDK player dan log bisnis terpisah, sehingga analisis asosiasi menjadi sulit.

Nilai inti

Penggunaan

Deskripsi

Keuntungan

Basic usage

Gunakan LogHub secara langsung untuk meng-output log.

Tidak perlu konfigurasi. Berfungsi langsung tanpa pengaturan tambahan.

Level control

Atur filter level log.

Log detail untuk pengembangan. Log minimal untuk produksi.

Listener extension

Daftarkan pendengar untuk menangani log.

Memungkinkan persistensi log dan pelaporan jarak jauh.

Keunggulan arsitektural:

  • Unified entry: Semua log mengalir melalui LogHub, menyederhanakan manajemen dan kontrol.

  • Flexible control: Mendukung tiga lapisan kontrol: toggle global, toggle konsol, dan filter level.

  • Extensible: Mekanisme pendengar mendukung penanganan log kustom, seperti penulisan ke file dan pelaporan jarak jauh.

  • Thread safe: Daftar pendengar menggunakan CopyOnWriteArrayList untuk akses konkuren yang aman.

Kemampuan inti

Kemampuan

Deskripsi

Multi-level logging

Mendukung level VERBOSE, DEBUG, INFO, WARN, dan ERROR.

Exception logging

Mendukung output detail exception Throwable.

Long-log segmentation

Secara otomatis membagi log panjang untuk menghindari pemotongan oleh Logcat.

Performance logging

Menyediakan log timing performa untuk analisis.

SDK log integration

Mengelola log SDK player secara terpadu melalui antarmuka IPlayerLogger.

Komponen bawaan

Level log

Level

Nilai

Deskripsi

Skenario

VERBOSE

0

Level paling detail. Meng-output semua informasi debug.

Pengembangan dan debugging.

DEBUG

1

Level informasi debug.

Debugging fitur tertentu.

INFO

2

Level informasi. Meng-output pesan umum.

Level default. Direkomendasikan untuk produksi.

WARN

3

Level peringatan. Menunjukkan potensi masalah.

Memantau risiko potensial.

ERROR

4

Level error. Melaporkan kesalahan.

Memantau masalah kritis.

NONE

100

Menonaktifkan semua log.

Mematikan output log.

Kelas inti

Kelas

Deskripsi

LogHub

Kelas utilitas untuk pusat log. Titik masuk terpadu untuk output log.

LogLevel

Anotasi yang mendefinisikan level log.

LogInfo

Kelas data yang mengenkapsulasi informasi lengkap untuk satu entri log.

LogHubListener

Antarmuka callback untuk menerima callback log.

IPlayerLogger

Antarmuka logging player global yang mengenkapsulasi fungsionalitas logging SDK.

DefaultPlayerLogger

Implementasi default logger player.

LoggerCallback

Antarmuka callback untuk log player.

Penggunaan dasar

Sistem logging menyediakan tiga strategi penggunaan. Pilih yang sesuai dengan kebutuhan Anda.

Strategi

Deskripsi

Skenario

Direct log output

Metode paling sederhana. Panggil metode LogHub secara langsung.

Pengembangan, debugging, atau logging sementara.

Configure log level

Atur level log berbeda berdasarkan lingkungan.

Membedakan antara lingkungan pengembangan dan produksi.

Register a listener

Menyesuaikan penanganan log menggunakan pendengar.

Persistensi log atau pelaporan jarak jauh.

Strategi 1: Direct log output

Anda dapat memanggil metode statis LogHub secara langsung:

// Output log INFO
LogHub.i(this, "playVideo", "Mulai memutar video");

// Output log WARN
LogHub.w(this, "onBuffering", "Buffering. Progres saat ini: ", progress);

// Output log ERROR
LogHub.e(this, "onError", "Pemutaran gagal. Kode error: ", errorCode);

// Output log ERROR dengan exception
LogHub.e(this, "onException", throwable, "Terjadi exception");

// Output log timing performa
LogHub.t("loadVideoSource", costTime);

Format log:

[Nama kelas] Nama metode: Pesan

Saran filter Logcat:

package:mine tag:AliPlayerKit

Strategi 2: Configure log level

Anda dapat mengatur level log berbeda berdasarkan lingkungan runtime:

// Lingkungan pengembangan: Output semua log
if (BuildConfig.DEBUG) {
    LogHub.setEnableLog(true);
    LogHub.setEnableConsoleLog(true);
    LogHub.setLogLevel(LogLevel.VERBOSE);
}

// Lingkungan produksi: Hanya output INFO dan di atasnya
else {
    LogHub.setEnableLog(true);
    LogHub.setEnableConsoleLog(false);  // Nonaktifkan output konsol
    LogHub.setLogLevel(LogLevel.INFO);
}

// Nonaktifkan semua log (untuk skenario sensitif)
LogHub.setEnableLog(false);

Strategi 3: Register a listener

Anda dapat menyesuaikan penanganan log menggunakan pendengar:

// Buat pendengar
LogHubListener listener = logInfo -> {
    // Proses log
    String formattedLog = logInfo.getFormattedMessage();
    // Tulis ke file, unggah ke server, dll.
    saveToFile(formattedLog);
};

// Daftarkan pendengar
LogHub.addListener(listener);

// Hapus pendengar jika tidak lagi diperlukan
LogHub.removeListener(listener);   

Penggunaan lanjutan

Bagaimana cara mengimplementasikan persistensi log?

Implementasikan logging berbasis file menggunakan antarmuka LogHubListener untuk membantu troubleshooting.

  1. Buat pendengar log.

    public class FileLogListener implements LogHubListener {
    
        private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();
        private final File mLogFile;
    
        public FileLogListener(Context context) {
            // Jalur file log
            File logDir = new File(context.getExternalFilesDir(null), "logs");
            if (!logDir.exists()) {
                logDir.mkdirs();
            }
            mLogFile = new File(logDir, "player_" + getDateStr() + ".log");
        }
    
        @Overridepublic void onLog(@NonNull LogInfo logInfo) {
            // Tulis ke file secara asinkron untuk menghindari pemblokiran thread pemanggil
            mExecutor.execute(() -> {
                try {
                    String log = logInfo.getFormattedMessage() + "\n";
                    FileOutputStream fos = new FileOutputStream(mLogFile, true);
                    fos.write(log.getBytes(StandardCharsets.UTF_8));
                    fos.close();
                } catch (IOException e) {
                    // Abaikan exception penulisan
                }
            });
        }
    }
  2. Daftarkan di kelas Application Anda.

    public class MyApplication extends Application {
    
        private FileLogListener mFileLogListener;
    
        @Overridepublic void onCreate() {
            super.onCreate();
    
            // Buat dan daftarkan pendengar log file
            mFileLogListener = new FileLogListener(this);
            LogHub.addListener(mFileLogListener);
        }
    }
  3. Ambil file log.

    // Jalur file log
    File logDir = new File(getExternalFilesDir(null), "logs");
    File[] logFiles = logDir.listFiles();
    
    // Bagikan kepada dukungan teknis untuk analisis

Referensi contoh: playerkit-examples/example-log-system/FileLogListener.java.

Bagaimana cara mengintegrasikan log SDK player?

Gunakan antarmuka IPlayerLogger untuk mengelola log SDK player secara terpadu.

  1. Buat instans logger player.

    // Inisialisasi di Application
    IPlayerLogger playerLogger = new DefaultPlayerLogger(context);
    
    // Aktifkan log konsol SDK (aktifkan hanya untuk debugging)
    playerLogger.enableConsoleLog(BuildConfig.DEBUG);
    
    // Atur level log SDK
    playerLogger.setLogLevel(LogLevel.INFO);
  2. Atur callback log SDK.

    playerLogger.setLogCallback((level, message) -> {
        // Tangani log SDK, seperti menulis ke file atau melaporkan jarak jauh
        LogHub.log(level, "PlayerSDK", message);
    });

Bagaimana cara menampilkan log di UI?

Anda dapat menggunakan pendengar untuk menampilkan log secara real-time di layar.

public class LogPanelActivity extends AppCompatActivity {

    private TextView mTvLogOutput;
    private LogHubListener mLogListener;

    @Overrideprotected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_log_panel);

        mTvLogOutput = findViewById(R.id.tv_log_output);

        // Buat pendengar log UI
        mLogListener = logInfo -> runOnUiThread(() -> {
            mTvLogOutput.append(logInfo.getFormattedMessage() + "\n");
        });

        // Daftarkan pendengar
        LogHub.addListener(mLogListener);
    }

    @Overrideprotected void onDestroy() {
        super.onDestroy();
        // Hapus pendengar untuk mencegah memory leak
        LogHub.removeListener(mLogListener);
    }
}

Praktik terbaik

Pemilihan level log

Skenario

Level yang direkomendasikan

Deskripsi

Detailed debug information

VERBOSE

Jejak alur kerja selama pengembangan.

Debug key points

DEBUG

Catat perubahan status kunci.

Important business information

INFO

Pertahankan informasi penting di produksi.

Potential issue warnings

WARN

Exception yang dapat dipulihkan atau peringatan performa.

Critical errors

ERROR

Kesalahan yang menyebabkan kegagalan fitur.

Konfigurasi lingkungan produksi

public class MyApplication extends Application {

    @Override
    public void onCreate() {
        super.onCreate();

        if (BuildConfig.DEBUG) {
            // Pengembangan: Log detail + output konsol
            LogHub.setEnableLog(true);
            LogHub.setEnableConsoleLog(true);
            LogHub.setLogLevel(LogLevel.VERBOSE);
        } else {
            // Produksi: Log minimal + tanpa konsol + persistensi file
            LogHub.setEnableLog(true);
            LogHub.setEnableConsoleLog(false);  // Nonaktifkan output Logcat
            LogHub.setLogLevel(LogLevel.INFO);   // Pertahankan hanya INFO dan di atasnya
            LogHub.addListener(new FileLogListener(this));
        }
    }
}  

Catatan

Catatan

Deskripsi

Avoid sensitive information

Jangan mencatat privasi pengguna, kunci, atau informasi sensitif lainnya.

Asynchronous file writes

Tulis file secara asinkron di pendengar untuk menghindari pemblokiran.

Handle listener exceptions

Exception pada pendengar tidak boleh memengaruhi output log normal.

Remove listeners promptly

Hapus pendengar saat halaman dihancurkan untuk mencegah memory leak.

Global listener location

Tempatkan pendengar log file di kelas Application untuk memastikan pengumpulan sepanjang siklus hidup.

Contoh

Proyek menyertakan contoh lengkap di playerkit-examples/example-log-system.

Fitur contoh

Fitur

Deskripsi

Log output demo

Menunjukkan output log pada setiap level.

UI log display

Menampilkan log secara real-time di layar.

File log listener

Menunjukkan persistensi log.

Menjalankan Contoh

Di Aplikasi Demo, pilih contoh Log System untuk melihat hasilnya.

Referensi API

Antarmuka inti

Antarmuka/kelas

Deskripsi

LogHub

Pusat log. Titik masuk terpadu untuk output log.

LogHubListener

Antarmuka callback untuk menerima callback log.

LogInfo

Kelas data untuk informasi log.

IPlayerLogger

Antarmuka logging player global.

Metode utama LogHub

Metode

Deskripsi

setEnableLog(boolean)

Aktifkan atau nonaktifkan output log (toggle global).

setEnableConsoleLog(boolean)

Aktifkan atau nonaktifkan output log konsol.

setLogLevel(int)

Atur filter level log.

addListener(LogHubListener)

Tambahkan pendengar log.

removeListener(LogHubListener)

Hapus pendengar log.

v/d/i/w/e(Object, String, Object...)

Output log pada setiap level.

t(String, long)

Output log timing performa.

Metode utama LogInfo

Metode

Deskripsi

getLevel()

Dapatkan level log.

getTag()

Dapatkan tag log.

getMessage()

Dapatkan pesan log.

getThrowable()

Dapatkan informasi exception.

getThreadName()

Dapatkan nama thread.

getTimestamp()

Dapatkan timestamp (dalam milidetik).

getFormattedMessage()

Dapatkan string log yang telah diformat.

Prinsip teknis

Long-log segmentation

Logcat membatasi setiap baris log hingga sekitar 4000 karakter. LogHub menangani log panjang dengan membaginya:

private static final int BUFFER_SIZE = 3000;

// Bagi dan output ke Logcatwhile (startIndex < length) {
    int endIndex = Math.min(length, startIndex + BUFFER_SIZE);
    String sub = s.substring(startIndex, endIndex);
    // Output log tersegmentasi...
    startIndex = endIndex;
}

Optimasi: Kirim log lengkap ke pendengar. Hanya segmentasi untuk output Logcat.

Thread safety

Daftar pendengar menggunakan CopyOnWriteArrayList untuk memastikan keamanan thread:

private static final List<LogHubListener> sListeners = new CopyOnWriteArrayList<>();

Karakteristik:

  • Operasi baca tidak memerlukan lock. Performa tinggi.

  • Operasi tulis menyalin array baru. Pembacaan yang sedang berlangsung tidak terpengaruh.

  • Ideal untuk pendaftaran dan penghapusan pendengar, di mana operasi baca jauh lebih sering daripada tulis.

FAQ

Bagaimana cara memfilter log PlayerKit di Logcat?

Gunakan filter ini:

package:mine tag:AliPlayerKit

Atau filter berdasarkan level:

package:mine tag:AliPlayerKit level:info       

Di mana file log lingkungan produksi disimpan?

Jalur default (jika menggunakan contoh FileLogListener):

/sdcard/Android/data/[nama paket]/files/logs/

Thread mana yang menjalankan callback pendengar?

Callback pendengar dijalankan pada thread yang sama dengan tempat log di-output. Untuk memproses log di thread UI, gunakan runOnUiThread() untuk mengganti thread.

Kesalahan umum

Berikut adalah masalah paling sering dilaporkan pelanggan. Hindari hal-hal ini:

Kesalahan 1: Operasi pemblokiran di pendengar menyebabkan tersendat

Kode salah:

@Overridepublic void onLog(@NonNull LogInfo logInfo) {
    // Penulisan file sinkron di main thread memblokir UItry {
        FileOutputStream fos = new FileOutputStream(mLogFile, true);
        fos.write(logInfo.getFormattedMessage().getBytes());
        fos.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
}

Kode yang benar:

private final ExecutorService mExecutor = Executors.newSingleThreadExecutor();

@Overridepublic void onLog(@NonNull LogInfo logInfo) {
    // Tulis ke file secara asinkron
    mExecutor.execute(() -> {
        try {
            // Logika penulisan file...
        } catch (IOException e) {
            // Abaikan
        }
    });
}

Akar penyebab: Jika log di-output di main thread, penulisan file sinkron akan memblokir UI. Hal ini menyebabkan tersendat atau ANR.

Kesalahan 2: Lupa menghapus pendengar menyebabkan memory leak

Kode salah:

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    // Mendaftarkan pendengar tetapi tidak pernah menghapusnya
    LogHub.addListener(logInfo -> {
        mTvLogOutput.append(logInfo.getMessage());
    });
}

Kode yang benar:

private LogHubListener mLogListener;

@Overrideprotected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    mLogListener = logInfo -> runOnUiThread(() -> {
        mTvLogOutput.append(logInfo.getMessage());
    });
    LogHub.addListener(mLogListener);
}

@Overrideprotected void onDestroy() {
    super.onDestroy();
    // Hapus pendengar segeraif (mLogListener != null) {
        LogHub.removeListener(mLogListener);
    }
}

Akar penyebab: Pendengar menyimpan referensi ke Activity. Jika Activity dihancurkan tetapi pendengar tetap ada, Activity tidak dapat dikumpulkan oleh garbage collector. Hal ini menyebabkan memory leak.

Kesalahan 3: Exception pada pendengar memengaruhi pendengar lain

Kode salah:

@Overridepublic void onLog(@NonNull LogInfo logInfo) {
    // Exception tidak ditangani. Jika dilempar di sini, akan memengaruhi pendengar lain
    String data = logInfo.getMessage();
    int result = 1 / 0;  // Melempar exception
}

Kode benar:

@Overridepublic void onLog(@NonNull LogInfo logInfo) {
    try {
        // Tangani exception di dalam pendengar
        processLog(logInfo);
    } catch (Exception e) {
        // Tangani exception spesifik pendengar tanpa memengaruhi sistem logging
        android.util.Log.e("FileLogListener", "Error processing log", e);
    }
}

Akar penyebab: Meskipun LogHub menangkap exception pendengar secara internal, pendengar harus menangani exception-nya sendiri untuk menjamin stabilitas.

Bagaimana cara melakukan debugging?

  1. Periksa status toggle log:

    boolean enabled = LogHub.isLogEnabled();
    boolean consoleEnabled = LogHub.isConsoleLogEnabled();
    int level = LogHub.getLogLevel();
  2. Lihat output Logcat:

    Filter log menggunakan tag:AliPlayerKit.

  3. Periksa jumlah pendengar:

    Anda dapat memeriksa jumlah pendengar yang terdaftar menggunakan refleksi (hanya untuk debugging). Verifikasi bahwa pendengar didaftarkan dan dihapus dengan benar.