Cara yang tepat untuk memutar log Nginx

12

Saya ingin mencapai rotasi log nginx yang:

  1. akan bekerja tanpa perangkat lunak tambahan (mis. - terbaik jika tanpa "logrotate")
  2. akan membuat file yang diputar dengan nama berdasarkan tanggal

Pendekatan terbaik adalah sesuatu yang dimiliki PostgreSQL - yaitu dalam variabel config log_filename-nya, saya dapat menentukan strftime-style% Y-% m-% d, dan itu akan secara otomatis mengubah log pada tanggal (atau waktu) perubahan.

Pendekatan lain dari apache - mengirimkan log melalui pipa ke program rotatelogs.

Sejauh yang saya bisa cari - tidak ada pendekatan seperti itu. Yang bisa saya lakukan adalah menggunakan logrotate dengan opsi dateext, tetapi ia memiliki sejumlah kekurangannya sendiri, dan saya lebih suka menggunakan sesuatu yang berfungsi seperti | rotatelogs atau log_filename di PostgreSQL.

Bryan
sumber
Ini artikel blog menggambarkan solusi yang mungkin untuk masalah Anda. Tapi saya punya pertanyaan: Mengapa Anda tidak ingin menggunakan logrotate? Itu melakukan pekerjaan dengan sangat baik, hampir tidak memiliki dependensi dan terbukti bekerja (pertempuran-keras jika Anda mau). Mengapa melompat melalui lingkaran dan menggunakan solusi homegrown yang mungkin lebih rendah dan rawan kesalahan, jika Anda bisa menggunakan logrotate (yang mungkin juga berguna untuk memutar beberapa log lain pada mesin itu)?
joschi
logrotate (dengan dateext) hampir berfungsi, tetapi saya tidak suka karena harus dijalankan melalui cron, dan ini memiliki beberapa kelemahan.
Karena nginx tidak mendukung pip log-nya ke program lain, tidak mendukung rotasi log dengan sendirinya dan Anda tidak menyukai pendekatan berbasis cron, Anda mungkin tidak cukup mendapatkan apa yang Anda inginkan. Terkadang "hampir berhasil" sama bagusnya dengan yang didapat. ;) Kecuali, tentu saja, Anda ingin menambal nginx sendiri.
joschi

Jawaban:

7

Sementara dunia terbagi pada apakah pipa bernama rendah hati itu teman atau musuh, itu mungkin solusi paling sederhana untuk masalah Anda. Memang ada beberapa kekurangan (dalam hal itu Anda perlu membuat pipa sebelumnya), tetapi itu menghilangkan kebutuhan untuk cron dan memungkinkan Anda untuk menggunakan pipa log-filter pilihan Anda.

Berikut ini contoh menggunakan cronolog di access.log:

  1. Pilih jalur untuk pipa bernama kami. Saya bermaksud menyimpan log saya /var/log/nginx, jadi saya akan menaruh pipa saya di sana juga. Nama terserah Anda; Saya menambahkan .fifo, dan itu access.log, jadi milik saya akan berada di /var/log/nginx/access.log.fifo.
  2. Hapus file jika ada.
  3. Buat pipa bernama untuk file log:

    mkfifo /var/log/nginx/access.log.fifo
    
  4. Konfigurasikan nginx.confuntuk mengarahkan log ke pipa yang baru saja Anda buat:

    access_log /var/log/nginx/access.log.fifo;
    
  5. Ubah skrip init.d Anda untuk memulai rotator log mendengarkan pipa sebelum kita memulai server:

    LOGS="/var/log/nginx"
    pkill -f "/usr/sbin/cronolog --symlink $LOGS/access.log"
    ( cat $LOGS/access.log.fifo | /usr/sbin/cronolog --symlink $LOGS/access.log "$LOGS/%Y/%m/%d/access.log" ) &
    

    Baris perintah serupa akan digunakan rotatelogsjika Anda menginginkannya cronolog- lihat dokumen mereka untuk sintaks.

    Jika distrobution Anda memiliki start-stop-daemon, Anda harus menggunakannya sebagai gantinya, karena secara teoritis memiliki pengetahuan khusus apa pun tentang platform Anda, dan merawat pkillAnda. Hanya membungkus perintah dalam skrip, dan meneruskannya --execke start-stop-daemondalam init.d/nginx.

dsc
sumber
Saya suka kronolog; senang melihat lebih banyak orang menggunakan / merekomendasikannya.
natacado
1

Saya telah menulis sebuah program sederhana, datelog, untuk membagi log umum berdasarkan tanggal login, sebagai lawan dari waktu sistem saat ini ketika baris log dilihat oleh program. Ini mungkin atau mungkin bukan apa yang sudah dilakukan kronolog atau pembagi log lain, tetapi lebih cepat menulis sendiri daripada mencari tahu apa yang dilakukan orang lain.

Dengan menggunakan tahun dan bulan dalam permintaan yang dicatat, baris kemudian ditulis ke file atau pipa yang mencakup YYYYMM yang dihitung dari data yang dicatat. Ya ini agak spesifik untuk format log umum. Yang pertama [diasumsikan untuk membatasi tanggal. Waspadai alamat IPv6. :)

Untuk analisis log, penting bahwa setiap log hanya berisi permintaan untuk setiap bulannya, dan setiap log idealnya harus lengkap untuk hasil analisis yang benar. Tidak cukup menentukan nama file berdasarkan waktu saat ini di dalam splitter log, karena permintaan lambat mulai pukul 23:59:59 kemudian akan berakhir di file log untuk bulan yang salah.

Saya menggunakan ini dengan nginx dengan cara bernama fifo yang diperiksa keberadaannya sebelum nginx dimulai. Perhatikan bahwa ada tradeoff dalam program antara deteksi kesalahan dan output buffer, di mana datelog saat ini lebih memilih output buffer untuk alasan kinerja, jadi harap pastikan bahwa setup Anda benar-benar berfungsi, terutama ketika menggunakan pipa shell, agar tidak kehilangan data log .

Kode sumber: http://stuge.se/datelog.c

Jangan ragu untuk mengirim saya umpan balik dan tentu saja tambalan!

kaku
sumber
1

Anda dapat mencapai ini menggunakan skrip bash dan cron sederhana:

#!/bin/bash
DATE=$(date +%Y-%m-%d-%H%M)
mv /var/log/nginx/access.log /var/log/nginx/nginx.access.log.$DATE
mv /var/log/nginx/error.log /var/log/nginx/nginx_error.log.$DATE
kill -USR1 `cat /var/run/nginx.pid`
sleep 1
gzip /var/log/nginx/access.log.$DATE
gzip /var/log/nginx/error.log.$DATE

Lebih detail tentang pengaturan crontab dll. Ditemukan di sini: Memutar file log Nginx via Cron

John Collins
sumber
0

Saya khawatir saya tidak begitu mengerti pertanyaan Anda: Karena nginx tidak mendukung logrotasi bawaan, Anda harus menggunakan sesuatu seperti

mv access.log access.log.$(date "+%Y-%m%d")
kill -USR1 $(cat master.nginx.pid)

di suatu tempat di /etc/cron.daily (tentu saja Anda harus memenuhi syarat nama file di atas dengan nama path lengkap) atau menginstal utilitas apache2 untuk memiliki akses ke rotatelogs.

Stefan Förster
sumber
Ini sama dengan yang bisa saya lakukan dengan logrotate. Dan saya menginginkannya lebih baik.