Sebagai RDBMS modern, PostgreSQL hadir dengan banyak parameter untuk fine-tuning. Salah satu area yang perlu dipertimbangkan adalah bagaimana PostgreSQL harus mencatat aktivitasnya. Logging sering diabaikan dalam manajemen database Postgres, dan jika tidak diabaikan, biasanya salah set. Hal ini terjadi karena sebagian besar waktu, tujuan logging tidak jelas. Tentu saja, alasan mendasar untuk logging sudah diketahui, tetapi yang terkadang kurang adalah pemahaman tentang bagaimana log akan digunakan.
Persyaratan logging setiap organisasi adalah unik, dan oleh karena itu bagaimana logging PostgreSQL harus dikonfigurasi akan berbeda juga. Apa yang perlu dicatat oleh perusahaan jasa keuangan dalam log basis datanya akan berbeda dari apa yang perlu dicatat oleh perusahaan yang berurusan dengan informasi kesehatan kritis. Dan dalam beberapa kasus, mereka juga bisa serupa.
Pada artikel ini, saya akan membahas beberapa praktik mendasar untuk mendapatkan hasil terbaik dari log PostgreSQL. Blog ini bukanlah buku aturan yang keras dan cepat; pembaca dipersilakan untuk berbagi pemikiran mereka di bagian komentar. Untuk mendapatkan nilai terbaik darinya, saya meminta pembaca untuk memikirkan bagaimana mereka ingin menggunakan log server database PostgreSQL mereka:
- Alasan kepatuhan hukum saat informasi spesifik perlu diambil
- Audit keamanan yang memerlukan detail acara tertentu
- Pemecahan masalah kinerja di mana kueri dan parameternya akan direkam
- Dukungan operasional sehari-hari dengan sejumlah metrik yang harus dipantau
Dengan itu, mari kita mulai.
Jangan Membuat Perubahan Manual pada postgresql.conf
Setiap perubahan pada file postgresql.conf harus dilakukan menggunakan sistem manajemen konfigurasi seperti Puppet, Ansible, atau Chef. Ini memastikan perubahan dapat dilacak dan dapat dengan aman dikembalikan ke versi sebelumnya jika perlu. Ini berlaku saat Anda membuat perubahan pada parameter logging.
DBA sering membuat banyak salinan dari file postgresql.conf, masing-masing dengan parameter yang sedikit berbeda, masing-masing untuk tujuan yang berbeda. Mengelola file konfigurasi yang berbeda secara manual adalah tugas yang rumit jika tidak rentan terhadap kesalahan. Di sisi lain, sistem manajemen konfigurasi dapat dibuat untuk mengganti nama dan menggunakan versi berbeda dari file postgresql.conf berdasarkan parameter yang diteruskan ke sana. Parameter ini akan menentukan tujuan dari versi saat ini. Ketika kebutuhan selesai, file konfigurasi lama dapat dikembalikan dengan mengubah parameter input yang sama.
Misalnya, jika Anda ingin mencatat semua pernyataan yang berjalan pada instance PostgreSQL Anda, file konfigurasi dengan nilai parameter “log_statement=all” dapat digunakan. Ketika tidak perlu merekam semua pernyataan – mungkin setelah latihan pemecahan masalah – file konfigurasi sebelumnya dapat dipulihkan.
Gunakan File Log Terpisah untuk PostgreSQL
Saya sarankan untuk mengaktifkan kolektor logging asli PostgreSQL selama operasi normal. Untuk mengaktifkan logging asli PostgreSQL, setel parameter berikut ke on:
logging_collector = on
Ada dua alasan untuk itu:
Pertama-tama, dalam sistem yang sibuk, sistem operasi mungkin tidak secara konsisten merekam pesan PostgreSQL di syslog (dengan asumsi instalasi berbasis nix) dan sering menjatuhkan pesan. Dengan logging PostgreSQL asli, daemon terpisah menangani perekaman acara. Saat PostgreSQL sibuk, proses ini akan menunda penulisan ke file log agar utas kueri selesai. Ini dapat memblokir seluruh sistem hingga peristiwa log ditulis. Oleh karena itu, sangat berguna untuk merekam lebih sedikit pesan yang bertele-tele dalam log (seperti yang akan kita lihat nanti) dan menggunakan awalan baris log yang dipersingkat.
Kedua – dan seperti yang akan kita lihat nanti – log harus dikumpulkan, diurai, diindeks, dan dianalisis dengan utilitas Manajemen Log. Memiliki PostgreSQL merekam acaranya di syslog berarti membuat lapisan tambahan pemfilteran dan pencocokan pola di bagian Manajemen Log untuk menyaring semua “pesan derau”. File log khusus dapat dengan mudah diurai dan diindeks untuk acara oleh sebagian besar alat.
Setel Tujuan Log ke stderr
Mari kita pertimbangkan parameter "log_destination". Itu dapat memiliki empat nilai:
log_destination = stderr | syslog | csv | eventlog
Kecuali ada alasan bagus untuk menyimpan peristiwa log dalam format yang dipisahkan koma atau log peristiwa di Windows, saya sarankan untuk mengatur parameter ini ke stderr. Ini karena dengan tujuan file CSV, nilai parameter "log_line_prefix" khusus tidak akan berpengaruh apa pun, namun, awalan dapat dibuat berisi informasi berharga.
Di sisi lain, log CSV dapat dengan mudah diimpor ke tabel database dan kemudian ditanyakan menggunakan SQL standar. Beberapa pengguna PostgreSQL merasa lebih nyaman daripada menangani file log mentah. Seperti yang akan kita lihat nanti, solusi Manajemen Log modern dapat secara native mengurai log PostgreSQL dan secara otomatis membuat wawasan yang berarti darinya. Dengan CSV, pelaporan dan visualisasi harus dilakukan secara manual oleh pengguna.
Pada akhirnya itu tergantung pada pilihan Anda. Jika Anda merasa nyaman membuat saluran penyerapan data Anda sendiri untuk memuat log CSV ke dalam tabel database, membersihkan dan mengubah data, serta membuat laporan khusus yang sesuai dengan kebutuhan bisnis Anda, pastikan “log_destination” disetel ke CSV.
Gunakan Nama File Log yang Bermakna
Ketika file log PostgreSQL disimpan secara lokal, mengikuti gaya penamaan mungkin tidak diperlukan. Gaya nama file default adalah “postgresql-%Y-%m-%d_%H%M%S.log” untuk log berformat non-CSV, yang cukup untuk sebagian besar kasus.
Penamaan menjadi penting saat Anda menyimpan file log dari beberapa server ke lokasi pusat seperti server log khusus, volume NFS terpasang, atau bucket S3. Saya sarankan menggunakan dua parameter dalam kasus seperti ini:
log_directory log_filename
Untuk menyimpan file log dari beberapa instance di satu tempat, pertama, buat hierarki direktori terpisah untuk setiap instance. Ini bisa seperti berikut:
/<Application_Name>/<Environment_Name>/<Instance_Name>
“log_directory” setiap instance PostgreSQL kemudian dapat diarahkan ke folder yang ditentukan.
Setiap instance kemudian dapat menggunakan nilai parameter “log_filename” yang sama. Nilai default akan membuat file seperti
postgresql_2020-08-25_2359.log
Untuk menggunakan nama yang lebih bermakna, setel “log_filename” menjadi seperti ini:
log_filename = "postgresql_%A-%d-%B_%H%M"
File log kemudian akan diberi nama seperti:
postgresql_Saturday-23-August_2230
Gunakan Awalan Baris Log yang Berarti
Awalan baris log PostgreSQL dapat berisi informasi paling berharga selain pesan sebenarnya itu sendiri. Dokumentasi Postgres menunjukkan beberapa karakter pelarian untuk konfigurasi awalan peristiwa log. Urutan pelarian ini diganti dengan berbagai nilai status saat dijalankan. Beberapa aplikasi seperti pgBadger mengharapkan awalan baris log tertentu.
Saya sarankan untuk menyertakan informasi berikut di awalan:
- Waktu kejadian (tanpa milidetik):%t
- Nama klien jarak jauh atau alamat IP:%h
- Nama pengguna:%u
- Basis data diakses:%d
- Nama aplikasi:%a
- ID Proses:%p
- Menghentikan keluaran proses non-sesi:%q
- Nomor baris log untuk setiap sesi atau proses, mulai dari 1:%l
Untuk memahami tentang apa masing-masing bidang dalam awalan, kita dapat menambahkan string literal kecil sebelum bidang. Jadi, nilai ID proses dapat didahului dengan literal “PID=”, nama database dapat diawali dengan “db=" dll. Berikut ini contohnya:
log_line_prefix = 'time=%t, pid=%p %q db=%d, usr=%u, client=%h , app=%a, line=%l '
Bergantung pada asal acara, awalan baris log akan menampilkan nilai yang berbeda. Proses latar belakang dan proses pengguna akan merekam pesan mereka dalam file log. Untuk proses sistem, saya telah menetapkan %q, yang akan menyembunyikan teks apa pun setelah ID proses (%p). Sesi lainnya akan menampilkan nama database, nama pengguna, alamat klien, nama aplikasi, dan baris bernomor untuk setiap peristiwa.
Juga, saya menyertakan satu spasi setelah awalan baris log. Ruang ini memisahkan awalan peristiwa log dari pesan peristiwa sebenarnya. Itu tidak harus berupa karakter spasi- apa pun seperti titik dua ganda (::), tanda hubung (-), atau pemisah bermakna lainnya dapat digunakan.
Juga, atur parameter “log_hostname” ke 1:
log_hostname = 1
Tanpa ini, hanya alamat IP klien yang akan ditampilkan. Dalam sistem produksi, ini biasanya berupa alamat proxy, penyeimbang beban, atau pooler koneksi. Kecuali Anda hafal alamat IP dari sistem ini, mungkin ada baiknya untuk mencatat nama host mereka. Namun, pencarian DNS juga akan menambah waktu ekstra bagi daemon logging untuk menulis ke file.
Parameter lain yang harus disetel bersama dengan "log_line_prefix" adalah "log_timezone". Menyetel ini ke zona waktu lokal server akan memastikan peristiwa yang dicatat mudah diikuti dari stempel waktunya alih-alih mengonversi ke waktu lokal terlebih dahulu. Dalam cuplikan kode di bawah, kami menyetel log_timzeone ke Zona Waktu Standar Timur Australia:
log_timezone = 'Australia/Sydney'
Log Koneksi Saja
Dua parameter mengontrol cara PostgreSQL merekam koneksi dan pemutusan klien. Kedua parameter dinonaktifkan secara default. Berdasarkan persyaratan keamanan organisasi Anda, Anda mungkin ingin menyetel salah satunya ke 1 dan yang lainnya ke 0 (kecuali jika Anda menggunakan alat seperti pgBadger – lebih lanjut tentang itu nanti).
log_connections = 1 log_disconnections = 0
Menyetel log_connections ke 1 akan merekam semua koneksi resmi serta usaha koneksi. Ini jelas bagus untuk audit keamanan:serangan brute force dapat dengan mudah diidentifikasi dari log. Namun, dengan pengaturan ini diaktifkan, lingkungan PostgreSQL yang sibuk dengan ribuan, atau bahkan ratusan koneksi valid berumur pendek dapat melihat file log dibanjiri.
Namun demikian, itu juga dapat mengidentifikasi masalah aplikasi yang mungkin tidak terlihat jelas. Sejumlah besar upaya koneksi dari banyak alamat klien valid yang berbeda dapat menunjukkan bahwa instans memerlukan penyeimbang beban atau layanan penyatuan koneksi di depannya. Sejumlah besar upaya koneksi dari satu alamat klien dapat mengungkap aplikasi dengan terlalu banyak utas yang memerlukan beberapa jenis pembatasan.
Log DDL dan Operasi DML Saja
Ada banyak perdebatan tentang apa yang harus dicatat di log Postgres – yaitu, apa yang seharusnya menjadi nilai dari parameter “log_statement”. Itu dapat memiliki tiga nilai:
log_statement = 'off' | 'ddl' | 'mod' | 'all'
Mungkin tergoda untuk menyetel ini ke "semua" untuk menangkap setiap pernyataan SQL yang berjalan di server, tetapi ini mungkin tidak selalu merupakan ide yang baik dalam kenyataannya.
Sistem produksi yang sibuk sebagian besar menjalankan pernyataan SELECT, terkadang ribuan di antaranya per jam. Instance mungkin berjalan dengan sangat baik, tanpa masalah kinerja. Menyetel parameter ini ke "semua" dalam kasus seperti itu tidak akan membebani daemon logging karena harus menulis semua pernyataan tersebut ke file.
Apa yang ingin Anda tangkap, bagaimanapun, adalah kerusakan data, atau perubahan dalam struktur database yang menyebabkan beberapa jenis masalah. Perubahan database yang tidak diinginkan atau tidak sah menyebabkan lebih banyak masalah aplikasi daripada memilih data; itu sebabnya saya merekomendasikan pengaturan parameter ini ke "mod". Dengan pengaturan ini, PostgreSQL akan merekam semua perubahan DDL dan DML ke file log.
Jika instance PostgreSQL Anda cukup sibuk (puluhan kueri per jam), jangan ragu untuk menyetel parameter ini ke "semua". Saat Anda memecahkan masalah kueri SELECT yang berjalan lambat atau mencari akses data yang tidak sah, Anda juga dapat mengatur ini ke "semua" untuk sementara. Beberapa aplikasi seperti pgBadger juga mengharapkan Anda menyetelnya ke "semua".
Masukkan Pesan "Peringatan" dan Lebih Tinggi
Jika parameter “log_statement” menentukan jenis pernyataan yang akan direkam, dua parameter berikut menentukan seberapa detail pesan tersebut:
log_min_messages log_min_error_statement
Setiap event PostgreSQL memiliki level pesan terkait. Level pesan bisa apa saja dari DEBUG verbose hingga PANIC singkat. Semakin rendah levelnya, semakin bertele-tele pesannya. Nilai default untuk parameter “log_min_messages” adalah “PERINGATAN”. Saya sarankan untuk mempertahankannya pada level ini kecuali jika Anda ingin pesan informasi juga dicatat.
Parameter "log_min_error_statement" mengontrol kesalahan pelemparan pernyataan SQL mana yang akan dicatat. Seperti "log_min_message", setiap pernyataan SQL yang memiliki tingkat keparahan kesalahan sama atau di atas nilai yang ditentukan dalam "log_min_error_statement" akan direkam. Nilai defaultnya adalah “ERROR”, dan saya sarankan untuk tetap menggunakan default.
Jaga Parameter Durasi Log ke Default
Kemudian kita memiliki dua parameter berikut:
log_duration log_min_duration_statement
Parameter "log_duration" mengambil nilai boolean. Jika disetel ke 1, durasi setiap pernyataan yang diselesaikan akan dicatat. Jika disetel ke 0, durasi pernyataan tidak akan dicatat. Ini adalah nilai default, dan saya sarankan untuk mempertahankannya ke 0 kecuali Anda memecahkan masalah kinerja. Menghitung dan merekam durasi pernyataan membuat mesin database melakukan pekerjaan ekstra (tidak peduli seberapa kecil), dan ketika diekstrapolasi ke ratusan atau ribuan kueri, penghematannya bisa signifikan.
Terakhir, kita memiliki parameter “log_min_duration_statement”. Ketika parameter ini disetel (tanpa unit apa pun, dianggap sebagai milidetik), durasi pernyataan apa pun yang diambil sama dengan atau lebih lama dari nilai parameter akan dicatat. Menyetel nilai parameter ini ke 0 akan merekam durasi semua pernyataan yang diselesaikan. Menyetel ini ke -1 akan menonaktifkan pencatatan durasi pernyataan. Ini adalah nilai default, dan saya sarankan untuk tetap menggunakannya.
Satu-satunya waktu Anda ingin menyetel parameter ini ke 0 adalah saat Anda ingin membuat garis dasar kinerja untuk kueri yang sering dijalankan. Ingatlah, jika parameter “log_statement” disetel, pernyataan yang dicatat dalam log tidak akan diulang dalam pesan log yang menunjukkan durasi. Jadi, Anda perlu memuat file log dalam tabel database, lalu menggabungkan nilai ID Proses dan ID Sesi dari awalan baris log untuk mengidentifikasi pernyataan terkait dan durasinya.
Apa pun artinya, setelah Anda memiliki garis dasar untuk setiap kueri yang sering dijalankan, Anda dapat menyetel parameter “log_min_duration_statement” ke nilai dasar tertinggi. Sekarang, kueri apa pun yang berjalan lebih lama dari nilai dasar tertinggi akan menjadi kandidat untuk penyempurnaan.
Simpan Verbositas Pesan Kesalahan ke Default
Parameter “log_error_verbosity” dapat memiliki tiga kemungkinan nilai:
log_error_verbosity = terse | standard | verbose
Parameter ini mengontrol jumlah informasi yang akan direkam PostgreSQL untuk setiap peristiwa yang direkam dalam file log. Kecuali men-debug aplikasi database, parameter ini sebaiknya tetap "default". Modus verbose akan berguna ketika Anda perlu untuk menangkap file atau nama fungsi dan nomor baris di sana yang menghasilkan kesalahan. Menyetel ini ke "terse" akan menekan logging kueri, yang mungkin juga tidak berguna.
Temukan Kebijakan Rotasi Log yang Berfungsi untuk Anda Kasus Penggunaan
Saya sarankan membuat kebijakan rotasi log berdasarkan ukuran atau usia file log, tetapi tidak keduanya. Dua parameter konfigurasi PostgreSQL menentukan bagaimana log lama diarsipkan dan log baru dibuat:
log_rotation_age = <number of minutes> log_rotation_size = <number of kilobytes>
Nilai default untuk “log_rotration_age” adalah 24 jam, dan nilai default untuk “log_rotation_size” adalah 10 megabita.
Dalam kebanyakan kasus, memiliki kebijakan rotasi ukuran tidak selalu menjamin bahwa pesan log terakhir dalam file log yang diarsipkan benar-benar dimuat dalam file itu saja.
Jika "log_rotation_age" disimpan ke nilai default 24 jam, setiap file dapat dengan mudah diidentifikasi dan diperiksa satu per satu, karena setiap file akan berisi kejadian sehari. Namun, ini juga tidak menjamin bahwa setiap file akan menjadi unit log mandiri dalam 24 jam terakhir. Terkadang kueri berperforma lambat membutuhkan waktu lebih dari 24 jam untuk diselesaikan; peristiwa bisa terjadi ketika file lama ditutup, dan yang baru dibuat. Hal ini dapat terjadi selama pekerjaan batch malam, sehingga beberapa bagian kueri direkam dalam satu file dan sisanya di file lain.
Rekomendasi kami adalah menemukan periode rotasi log yang sesuai untuk Anda kasus penggunaan. Periksa perbedaan waktu antara dua periode aktivitas terendah berturut-turut (misalnya, antara satu Sabtu ke Sabtu berikutnya). Anda kemudian dapat mengatur nilai “log_rotation_age” ke perbedaan waktu tersebut, dan selama salah satu periode tersebut, restart layanan PostgreSQL. Dengan begitu, PostgreSQL akan memutar file log saat ini ketika periode jeda berikutnya terjadi. Namun, jika Anda perlu memulai ulang layanan di antara periode ini, rotasi log akan kembali miring. Anda harus mengulangi proses ini. Tetapi seperti banyak hal lain di PostgreSQL, coba-coba akan menentukan nilai terbaik. Selain itu, jika Anda menggunakan utilitas manajemen log, usia atau ukuran rotasi log tidak akan menjadi masalah karena agen pengelola log akan menyerap setiap peristiwa dari file saat ditambahkan.
Gunakan Alat Seperti pgBadger
pgBadger adalah penganalisis log PostgreSQL yang kuat yang dapat membuat wawasan yang sangat berguna dari file log Postgres. Ini adalah alat sumber terbuka yang ditulis dalam Perl dengan jejak yang sangat kecil di mesin tempat ia berjalan. Alat ini dijalankan dari baris perintah dan dilengkapi dengan sejumlah besar opsi. Ini akan membutuhkan satu atau lebih log sebagai masukannya dan dapat menghasilkan laporan HTML dengan statistik terperinci tentang:
- Permintaan yang paling sering menunggu.
- Kueri yang menghasilkan sebagian besar file sementara atau file sementara terbesar
- Kueri berjalan paling lambat
- Durasi kueri rata-rata
- Kueri yang paling sering dijalankan
- Kesalahan yang paling sering terjadi dalam kueri
- Pengguna dan aplikasi yang menjalankan kueri
- Statistik pos pemeriksaan.
- Autovacuum dan analisis otomatis statistik.
- Statistik penguncian
- Kejadian error (panik, fatal, error, dan peringatan).
- Profil koneksi dan sesi (berdasarkan database, pengguna, aplikasi)
- Profil sesi
- Profil kueri (jenis kueri, kueri menurut basis data/aplikasi)
- Statistik I/O
- dst.
Seperti yang saya sebutkan sebelumnya, beberapa parameter konfigurasi terkait log harus diaktifkan untuk menangkap semua peristiwa log sehingga pgBadger dapat menganalisis log tersebut secara efektif. Karena ini dapat menghasilkan file log besar dengan banyak peristiwa, pgBadger seharusnya hanya digunakan untuk membuat tolok ukur atau memecahkan masalah kinerja. Setelah log terperinci dibuat, parameter konfigurasi dapat diubah kembali ke nilai aslinya. Untuk analisis log berkelanjutan, sebaiknya gunakan aplikasi pengelolaan log khusus.
Jika Anda lebih nyaman melakukan sesuatu di command prompt dan memanfaatkan tampilan sistem, Anda akan ingin menggunakan pg_stat_statements. Sebenarnya, ini harus diaktifkan di instalasi PostgreSQL produksi apa pun.
pg_stat_statements adalah ekstensi PostgreSQL dan dengan instalasi default sekarang. Untuk mengaktifkannya, parameter konfigurasi “shared_preload_libraries” harus memiliki pg_stat_statements sebagai salah satu nilainya. Itu kemudian dapat diinstal seperti ekstensi lainnya menggunakan perintah "CREATE EXTENSION". Ekstensi membuat tampilan pg_stat_statement yang memberikan informasi terkait kueri yang berharga.
Gunakan Aplikasi Manajemen Log untuk Mendapatkan Wawasan
Ada banyak utilitas manajemen log di pasar, dan sebagian besar organisasi menggunakan satu atau lebih hari ini. Alat apa pun yang ada, saya sarankan untuk menggunakannya untuk mengumpulkan dan mengelola log PostgreSQL.
Ada beberapa alasan untuk itu:
Jauh lebih mudah untuk mengurai, menganalisis, dan menyaring kebisingan dari file log dengan alat otomatis. Terkadang, suatu peristiwa dapat menjangkau beberapa file log berdasarkan durasi peristiwa, dan usia atau ukuran rotasi log. Memiliki pengelola log mempermudah penyajian informasi ini secara keseluruhan.
Solusi manajemen log saat ini biasanya hadir dengan kemampuan bawaan untuk mengurai log PostgreSQL. Beberapa juga dilengkapi dengan dasbor yang dapat menampilkan metrik paling umum yang diambil dari log ini.
Sebagian besar aplikasi manajemen log modern juga menawarkan fitur pencarian, filter, pencocokan pola, korelasi peristiwa, dan analisis tren yang mendukung AI. Apa yang tidak terlihat oleh mata biasa dapat dengan mudah dibuktikan dengan alat ini.
Terakhir, menggunakan pengelola log untuk menyimpan log PostgreSQL juga berarti peristiwa disimpan untuk anak cucu, bahkan jika file asli terhapus secara tidak sengaja atau jahat.
Meskipun ada keuntungan nyata menggunakan aplikasi manajemen log, banyak organisasi memiliki batasan tentang di mana log mereka bisa hidup. Ini adalah kasus umum dengan solusi berbasis SaaS di mana log sering kali disimpan di luar batas geografis organisasi – sesuatu yang mungkin tidak sesuai dengan persyaratan peraturan.
Dalam kasus seperti itu, saya sarankan untuk memilih vendor dengan kehadiran pusat data lokal – jika memungkinkan – atau menggunakan pengelola log yang dikelola sendiri yang dihosting di jaringan organisasi, seperti tumpukan ELK.
Kata Akhir
Log server PostgreSQL dapat menjadi tambang emas informasi jika dikonfigurasi dengan tepat. Triknya adalah menentukan apa yang harus dicatat dan berapa banyak yang harus dicatat, dan yang lebih penting, menguji apakah log dapat memberikan informasi yang benar saat dibutuhkan. Ini akan menjadi masalah coba-coba, tetapi apa yang telah saya bahas di sini hari ini seharusnya memberikan awal yang cukup baik. Seperti yang saya katakan di awal, saya akan sangat senang mendengar tentang pengalaman Anda mengonfigurasi logging PostgreSQL untuk hasil yang optimal.