Episode ini mempersiapkan aplikasi C untuk produksi: logging, tracing, dan monitoring, crash dump analysis memakai core files dan post-mortem debugging, rollback strategy dan release management, serta documentation, code review, dan maintenance best practices.

Aplikasi yang berjalan di produksi membutuhkan lebih dari kode yang benar — ia butuh visibilitas. Episode 22 membahas observability: bagaimana melihat apa yang terjadi di dalam program saat berjalan, dan bagaimana menyelidiki kegagalan setelah terjadi.
Kita akan membangun logging dan tracing untuk aplikasi C, memantau metrik runtime, lalu menganalisis crash memakai core files dengan post-mortem debugging. Tidak kalah penting, kalian akan belajar release management dan rollback, serta kebiasaan documentation dan code review yang menjaga proyek tetap sehat.
Inilah episode yang menyatukan seluruh keterampilan teknis kalian menjadi kemampuan produksi yang utuh.
Log yang baik mencatat peristiwa penting dengan konteks yang cukup: waktu, level, dan lokasi:
#include <stdio.h>
#include <time.h>
void log_info(const char *pesan) {
time_t now = time(NULL);
char waktu[32];
struct tm *t = localtime(&now);
strftime(waktu, sizeof(waktu), "%Y-%m-%d %H:%M:%S", t);
fprintf(stderr, "[%s] INFO %s\n", waktu, pesan);
}Fungsi log_info di atas menulis pesan dengan stempel waktu ke stderr. Memakai stderr memisahkan log dari output data normal sehingga bisa dialihkan ke file atau systemd terpisah.
Gunakan level: DEBUG, INFO, WARN, dan ERROR, dan biarkan level minimum diatur saat runtime. Tracing melacak alur melalui banyak komponen; di aplikasi terdistribusi, trace ID menyatukan log yang tersebar. Untuk monitoring, ekspor metrik seperti jumlah request dan latensi ke sistem seperti Prometheus lewat endpoint HTTP atau file.
Saat program crash, kernel bisa menyimpan snapshot memori ke core file. Aktifkan dan periksa:
ulimit -c unlimited
./appPerintah ulimit -c unlimited mengizinkan pembuatan core files. Ketika program crash, file bernama core muncul di direktori kerja. Pastikan build memakai -g agar core file berisi informasi simbol yang bisa dibaca. Di sistem production, atur core dump agar dikumpulkan ke direktori khusus dan diputar secara otomatis agar tidak memenuhi disk.
Analisis crash tanpa menjalankan ulang — ini yang membedakan post-mortem debugging:
gdb -q ./app coreDi dalam gdb dengan core file, bt mencetak backtrace saat crash, info registers menampilkan kondisi CPU, dan print variabel membaca isi variabel pada momen kegagalan. Backtrace ini menjawab pertanyaan paling penting: di fungsi apa dan dari jalur mana program jatuh.
Agar backtrace bermakna, kompilasi dengan -g -fno-omit-frame-pointer. Di produksi, banyak tim juga memakai breakpad untuk mengumpulkan crash report dari pengguna yang tidak bisa mengakses server. Core file juga bisa diunduh dan dianalisis di mesin pengembangan.
Simpan core file dari tiap versi rilis sebagai arsip. Ketika laporan crash datang, bandingkan dengan core file versi tersebut menggunakan alamat simbol yang cocok. Kebiasaan ini mengubah insiden produksi yang membingungkan menjadi investigasi yang terstruktur.
Setiap rilis harus identifikasi dan bisa dibangun ulang: tag versi di repositori, lockfile dependency, dan hash binary. Hasilkan versi ke dalam binary:
gcc -DVERSI=\"1.4.2\" main.c -o app
./app --version-DVERSI=\"1.4.2\" mengkompilasi versi sebagai macro sehingga program bisa mencetaknya lewat --version. Versi yang jelas mempermudah pelaporan bug dan melacak mana yang berjalan di server.
Bahkan dengan testing terbaik, rilis bisa salah. Siapkan jalur mundur: deploy versi sebelumnya harus semudah deploy versi baru. Teknik umum adalah blue-green deployment — dua set instance, versi baru diuji lalu traffic dipindah, dan kembalikan traffic ke versi lama saat masalah. Rilis bertahap dan flag fitur memungkinkan menarik fitur bermasalah tanpa deploy ulang.
Dokumentasi yang baik menjelaskan kontrak fungsi: parameter, nilai kembalian, dan perilaku error. Header file adalah tempat dokumentasi antarmuka di C — pemakai modul membaca header tanpa membuka implementasi. Jangan dokumentasikan yang sudah jelas; dokumentasikan asumsi dan kasus tepi.
Code review menemukan bug sebelum digabung dan menyebarkan pengetahuan antar anggota tim. Review efektif menanyakan: apakah kode ini jelas, apakah menangani error, apakah ada bagian yang rapuh. Untuk pemeliharaan, kurangi hutang teknis bertahap, jaga dependency diperbarui, dan pantau CVE untuk library yang dipakai.
Tip
Rilis yang sukses adalah rilis yang bisa dipulihkan. Sebelum mengumumkan rilis baru, pastikan proses rollback sudah diuji — bukan hanya ditulis di dokumen.
Inti yang harus dibawa pulang:
Di episode 23 selanjutnya, episode terakhir, kita akan membahas fitur modern C11, C17, C23 dan future trends — fitur stabil standar modern, concurrency dan atomic operations, peran C di sistem modern, embedded, dan performance-critical, hingga strategi menjaga keahlian C tetap relevan di ekosistem teknologi.