Java Academy · Pelajaran

Pengelogan Berparameter

Pemformatan mesej yang cekap

Pelajaran 3 daripada 413 langkah

Pengelogan Berparameter ialah pelajaran Java Academy percuma di CoddyKit. Ini ialah pelajaran 3 daripada 4. Anda boleh membaca keseluruhan pelajaran di bawah secara percuma — kemudian berlatih secara praktikal dalam pelayar menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7. Pelajaran ini merupakan sebahagian daripada laluan pembelajaran Java Academy, dan kemajuan anda disegerakkan merentas web serta aplikasi CoddyKit. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Masalah Penggabungan Rentetan

Menggabungkan mesej log membina rentetan penuh sebelum panggilan dibuat, walaupun tahap tersebut dilumpuhkan.

log.debug("id=" + id + " name=" + name) membazirkan CPU apabila DEBUG dimatikan kerana rentetan tetap dibina.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        String name = "Ada"; int id = 7;
        // Bad: string is built even if DEBUG is disabled
        log.debug("id=" + id + " name=" + name);
    }
}

Ruang Letak dengan {}

SLF4J menggunakan {} sebagai ruang letak. Hantarkan nilainya sebagai hujah tambahan.

Mesej hanya dibina jika tahap tersebut diaktifkan, jadi kos log yang dilumpuhkan hampir tiada.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        String name = "Ada"; int id = 7;
        // Good: no string built unless DEBUG is on
        log.debug("id={} name={}", id, name);
    }
}

Berbilang Ruang Letak

Ruang letak diisi mengikut urutan. {} pertama menerima hujah pertama, yang kedua menerima hujah kedua dan seterusnya.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("order {} for user {} totaling {} cents", "A-1", 42, 1599);
    }
}

Mengapa Ia Cekap

Rangka kerja terlebih dahulu menyemak tahap. Jika dilumpuhkan, rangka kerja kembali serta-merta tanpa memanggil toString() pada mana-mana hujah.

Bahagian yang mahal, iaitu pemformatan, berlaku secara tertunda hanya apabila mesej benar-benar akan dikeluarkan.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String describe(Object o) { System.out.println("toString called"); return o.toString(); }
    public static void main(String[] args) {
        // Note: passing describe(...) still evaluates eagerly; pass the raw object instead
        log.trace("value={}", new int[]{1, 2, 3});
    }
}

Hantarkan Objek Mentah, Bukan Rentetan yang Telah Diformat

Untuk mendapatkan manfaat penangguhan, hantarkan objek mentah, bukan panggilan kaedah yang memformatkannya.

Jika Anda menulis log.debug("{}", buildReport()), buildReport() masih dijalankan dengan segera. Hantarkan hujah yang boleh diformatkan sendiri oleh Logger.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        Object user = new Object();
        // Logger calls user.toString() only if DEBUG is enabled
        log.debug("current user: {}", user);
    }
}

Pembekal Tertunda untuk Kerja Berat

Apabila pemformatan benar-benar mahal, gunakan API fasih SLF4J 2.x bersama Supplier supaya kerja itu ditangguhkan.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    static String heavyReport() { return "...expensive..."; }
    public static void main(String[] args) {
        log.atDebug()
           .setMessage("report: {}")
           .addArgument(() -> heavyReport())
           .log();
    }
}

Meloloskan Kurungan Berlengkung Literal

Jika Anda memerlukan {} literal dalam mesej, meloloskannya dengan garis condong terbalik: \\{}.

Hal ini jarang diperlukan, tetapi berguna apabila mencatat teks seperti JSON.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        // Logs a literal {} then the value
        log.info("empty object is \\{} and id is {}", 7);
    }
}

Pengecualian Bersama Ruang Letak

Anda boleh menggabungkan ruang letak dengan pengecualian pada hujung. SLF4J mengesan bahawa hujah terakhir ialah Throwable dan mencetak jejak tindanannya.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        int id = 99;
        try {
            throw new RuntimeException("db down");
        } catch (Exception e) {
            log.error("failed processing record {}", id, e);
        }
    }
}

Elakkan Terlalu Banyak Hujah

Jika bilangan ruang letak dan bilangan hujah tidak sepadan, SLF4J akan melakukan yang terbaik, tetapi hasilnya mungkin kelihatan salah.

Pastikan kedua-duanya sepadan. Untuk lebih daripada beberapa nilai, pertimbangkan konteks berstruktur (MDC).

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        // Two placeholders, two arguments: correct
        log.info("user {} did {}", "ada", "login");
    }
}

Menambah Konteks dengan MDC

Untuk nilai yang dikongsi merentasi banyak baris (seperti id permintaan), letakkannya dalam MDC dan bukannya dalam setiap mesej.

Tataletak corak kemudiannya boleh mencetak nilai MDC pada setiap baris secara automatik.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        MDC.put("requestId", "req-1234");
        try {
            log.info("handling request");
            log.info("request done");
        } finally {
            MDC.clear();
        }
    }
}

Ringkasan Amalan Terbaik

Peraturan untuk pengelogan yang cekap:

  • Sentiasa gunakan ruang letak {}, jangan gunakan penggabungan +.
  • Hantarkan objek mentah, bukan rentetan yang dibina terlebih dahulu.
  • Gunakan pembekal atau isXEnabled() untuk kerja yang benar-benar berat.
  • Gunakan MDC untuk konteks rentas fungsi.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("processed {} items in {} ms", 1000, 42);
    }
}

Semakan Pantas

Uji pengetahuan Anda tentang pengelogan berparameter.

Imbas Kembali

Anda telah mempelajari pengelogan berparameter:

  • Gunakan ruang letak {} bersama hujah tambahan.
  • Mesej dibina secara tertunda, hanya apabila tahap tersebut diaktifkan.
  • Hantarkan objek mentah; gunakan pembekal untuk kerja berat.
  • Gunakan MDC untuk nilai konteks yang dikongsi.

Seterusnya, mengkonfigurasi sistem belakang Logback.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class Main {
    private static final Logger log = LoggerFactory.getLogger(Main.class);
    public static void main(String[] args) {
        log.info("Parameterized logging recap: {}", "done");
    }
}
Percuma untuk bermula

Pelajari Java dengan tutor kecerdasan buatan — percuma

Tulis dan jalankan kod sebenar dalam pelayar anda, dapatkan bantuan segera daripada tutor kecerdasan buatan yang tersedia 24/7, dan sambung semula dari tempat anda berhenti di web atau dalam aplikasi.

Kursus
104
Pelajaran
374

Soalan Lazim

Adakah pelajaran “Pengelogan Berparameter” percuma?

Ya — teks penuh “Pengelogan Berparameter” boleh dibaca secara percuma di web ini. Untuk berlatih secara interaktif menggunakan penyunting kod terbina dalam dan tutor kecerdasan buatan 24/7, serta membuka kunci baki kursus Java Academy, tingkat taraf kepada CoddyKit PRO. Kursus Java Academy merangkumi sejumlah 4 pelajaran.

Apakah yang akan saya pelajari dalam “Pengelogan Berparameter”?

Pemformatan mesej yang cekap Anda berlatih Java Academy menggunakan kod praktikal yang dijalankan terus dalam pelayar, manakala tutor kecerdasan buatan 24/7 menjawab soalan anda semasa anda mengikuti pelajaran.

Adakah saya memerlukan pengalaman untuk memulakan Java Academy?

Tiada pengalaman terdahulu diperlukan. Pembelajaran Java Academy di CoddyKit disusun untuk pelajar daripada peringkat pemula hingga lanjutan, jadi anda boleh bermula di sini atau dari awal dan belajar mengikut kadar anda sendiri. Ini ialah pelajaran 3 daripada 4.

Berapa lamakah pelajaran “Pengelogan Berparameter” diambil?

Kebanyakan pelajaran CoddyKit mengambil masa kira-kira 5–10 minit. Setiap pelajaran ringkas dan interaktif, jadi anda boleh membuat kemajuan secara berterusan dan menyambung tepat dari tempat anda berhenti di web atau aplikasi.

Bolehkah saya menulis dan menjalankan kod dalam pelajaran Java Academy ini?

Ya. Setiap pelajaran Java Academy menyertakan penyunting kod terbina dalam, jadi anda boleh menulis dan menjalankan kod sebenar terus dalam pelayar serta menerima maklum balas kecerdasan buatan serta-merta — tanpa memerlukan persediaan setempat.

Semua pelajaran dalam kursus ini

  1. Mengapa Pengelogan Berstruktur
  2. Fasad SLF4J dan Pengelog
  3. Pengelogan Berparameter
  4. Mengkonfigurasi Logback
← Kembali ke Java Academy