Bagaimana cara melanjutkan mengarahkan stdout ke file setelah logrotate memindahkannya?

22

Saya memiliki skrip sederhana yang menampilkan sekelompok log ke layar dan saya mengirim STDOUT ke file untuk menyimpan log. Karena skrip ini berjalan lama, saya perlu memutar file log sehingga mereka dibuang ke yang lebih kecil dan lebih mudah dikelola.

Masalah yang saya hadapi adalah bahwa setelah logrotatememindahkan file log saat ini ke yang baru, file log yang baru dibuat tidak diisi dengan log lagi. Tampaknya begitu file log asli dihapus, penangan filenya hilang dan pengalihan tidak akan berfungsi lagi.

Saya juga menemukan posting ini yang memiliki masalah yang sama dengan saya dan mengklaim bahwa itu dapat diperbaiki dengan menggunakan >>alih-alih >untuk mengarahkan kembali output. Saya menguji solusinya tetapi tidak berhasil untuk saya. Adakah yang tahu cara mempertahankan pengalihan?

Mehran
sumber
4
Saya masih merekomendasikan, dalam kasus Anda, untuk menggunakan ">>" daripada ">" jika Anda berniat untuk menulis ke file terpotong: sebagai ">>" terbuka dalam mode append, itu akan mencari sampai akhir file setiap kali ia menulis. Dengan begitu, ketika Anda memotong file (membuatnya dari XXXX byte ke 0 byte), itu akan "mencari sampai akhir", jadi akan tahu sekarang harus menulis setelah byte 0. Jika tidak, ia dapat menulis setelah byte XXXX, dan dengan demikian buat file jarang dengan XXXX null byte sebelum itu (yaitu, ketika ">", fd hanya dapat mengingat di mana file itu ada di file itu, dan menulis dari sana, tanpa menyadari ukuran file menyusut!)
Olivier Dulac

Jawaban:

25

Anda harus menggunakan arahan copytruncate dalam konfigurasi logrotate Anda untuk file log ini.

copytruncate Memotong file log asli di tempat setelah membuat salinan, alih-alih memindahkan file log lama dan secara opsional membuat yang baru. Ini dapat digunakan ketika beberapa program tidak dapat diberitahu untuk menutup logfile-nya dan dengan demikian dapat terus menulis (menambahkan) ke file log sebelumnya selamanya. Perhatikan bahwa ada irisan waktu yang sangat kecil antara menyalin file dan memotongnya, sehingga beberapa data logging mungkin hilang. Ketika opsi ini digunakan, opsi buat tidak akan berpengaruh, karena file log lama tetap di tempatnya

user9517 mendukung GoFundMonica
sumber
2
Mungkin perlu disebutkan: Untuk waktu yang singkat, sebelum compressoperasi, data digandakan. Itu menyebabkan kami masalah sekali tapi itu adalah masalah kami karena kami seharusnya tidak sedekat itu dengan lvbatas ruang. Juga, seperti yang dinyatakan dalam mancuplikan, Anda mungkin kehilangan beberapa data log di antara operasi salin dan terpotong.
Belmin Fernandez
6

Sebagai alternatif, Anda juga dapat:

  • gunakan utilitas logger dalam skrip Anda alih-alih perpipaan, dengan fasilitas khusus (mis. local5), misalnya:

    logger -p local5.info -t myscriptname "this is some log data"

  • konfigurasikan syslog untuk menulis fasilitas ini ke file log yang diinginkan, contoh (rsyslog.conf):

    local5.* /var/log/mylogfile

  • atur aturan logrotate untuk log ini.

tonioc
sumber
Ini hanya berfungsi jika Anda memiliki perintah output eksplisit seperti echo. Keluaran alat pihak ketiga yang dipanggil dari skrip dan juga keluaran sesuatu tidak dapat dialihkan ke logger dengan cara ini
Daniel Alder
4

Alternatif lain untuk solusi Iain adalah menggunakan postrotateskrip untuk meluncurkan kembali skrip Anda begitu rotasi telah terjadi. Ini dilakukan untuk banyak daemon (restart atau reload daemon), tetapi tidak mengetahui skrip Anda, saya tidak tahu apakah solusi ini cocok untuk Anda atau tidak (apakah skrip Anda bergantung pada beberapa keadaan yang dibuat beberapa saat yang lalu?).

Isi dari /etc/logrotate.d/your-script-name:

/var/log/your-script-name.log {
    # your current logrotate options
    ...
    postrotate
        # this supposing you have the current pid stored
        cat /run/your-script-name.pid | xargs -r kill
        #relaunch it again
        /usr/local/bin/your-script-name
    endscript
}
Carlos Campderrós
sumber
0

Anda dapat mem-pipe stdout ke "split" (bagian dari coreutils di linux). Ini memungkinkan Anda untuk membagi file / stdin menjadi potongan-potongan berdasarkan ukuran, jumlah baris, dll. Setelah Anda memotong Anda dapat mengelolanya dengan logrotate jika diperlukan.

Nazar
sumber