Log rotasi stdout?

53

Saya memiliki program Linux yang dapat menulis informasi ke stdout dan stderr.

Saya memiliki skrip shell yang mengarahkan output ke file di /var/log. (Via >>dan 2>&1.)

Apakah ada cara untuk membuat file log diputar? (ukuran maksimal, lalu beralih ke file lain, simpan hanya sejumlah file)

Saya telah melihat beberapa jawaban yang berbicara tentang logrotateprogram, yang terdengar bagus, tetapi mereka juga tampaknya berfokus pada program yang menghasilkan file log secara internal dan menangani sinyal HUP. Apakah ada cara untuk membuat ini bekerja dengan skrip redirection output dasar?

Miral
sumber
1
Mengapa Anda tidak bisa hanya memodifikasi skrip yang mengarahkan ulang output untuk mengandung logika rotasi?
MaQleod
Saya bisa, jika seseorang bisa memberi tahu saya cara mendeteksi ukuran file log dan memutarnya dari bawah proses tanpa mengganggu proses itu. Saya tidak harus menggunakan logrotatejika ada opsi yang lebih baik, yang hanya terdengar seperti titik awal yang nyaman untuk diskusi.
Miral
2
Anda tidak harus menggunakan logrotate, tetapi menggunakan logrotate hanya menghemat waktu ... Biasanya ada gunanya menciptakan kembali roda.
bubu
Maksud saya tepat. Jadi apakah ada cara untuk membuat logrotate berfungsi dengan proses pengalihan yang sedang berlangsung?
Miral

Jawaban:

44

Sebagai alternatif, Anda dapat menyalurkan output melalui alat yang dirancang dengan tujuan utama mempertahankan set file log yang dibatasi ukuran dan dirotasi secara otomatis, seperti:

Alat-alat untuk kemudian memproses multilogset file log format antara lain:

Bacaan lebih lanjut

JdeBP
sumber
1
Terima kasih, multilogsepertinya yang saya butuhkan.
Miral
multilog tampaknya menjadi satu-satunya solusi plug-and-play di debian (daemontools memiliki paket resmi). Tetapi dalam kasus khusus saya, di mana saya ingin menyimpan log pada partisi fat32, rotating tidak berfungsi, karena multilog ingin menggunakan symlink. Tidak ada plug and play untuk saya :)
Arnout
Itu tidak mungkin benar, karena multilogtidak ada tempat yang menciptakan atau menuntut tautan simbolik. Itu sepenuhnya netral sehubungan dengan mereka.
JdeBP
URL "Jangan gunakan logrotate atau newsyslog di abad ini" memiliki titik ekstra
duyue
15

yang rotatelogsalat dikirimkan dengan apache (dalam bindir) (lihat docs ) mengambil input dari stdin dan berputar log setelah beberapa jumlah waktu tertentu

BertNase
sumber
14

Jika Anda dapat menggunakannya untuk pergi ke salah satu aliran log standar (syslog, daemon, cron, pengguna, keamanan, mail, dll.) Anda dapat menggunakan loggerperintah dan pipa untuk itu sebagai gantinya.

echo "Hello." | logger -p daemon.info

Jika tidak, Anda mungkin lebih baik menyaring konten yang telah dicatat ke program atau skrip khusus untuk menanganinya, atau melihat menyiapkan logrotatekonfigurasi.

EDIT: Jawaban JdeBP tampaknya memiliki apa yang Anda cari.

Lara Dougan
sumber
2
+1 untuk kesederhanaan. BTW, Anda juga dapat mengonfigurasi fasilitas khusus (lokal0) alih-alih yang standar (daemon dalam contoh Anda)
Roger Keays
14

Saya memiliki masalah yang sama dan pada awalnya membuang logrotate tetapi ternyata logrotate sebenarnya dapat melakukan ini dengan baik, arahan kuncinya adalah " copytruncate ". Untuk beberapa alasan istilah itu tidak muncul di salah satu googling yang saya lakukan, jadi saya menambahkan jawaban ini untuk memperjelas bagaimana menggunakannya untuk kasus ini.

Kuncinya adalah ini hanya berfungsi jika pengalihan dilakukan dengan " >> " (append) bukan " > " (create).

File Konfigurasi (truncate.cfg):

/tmp/temp.log {
    size 10M
    copytruncate
    rotate 4
    maxage 100
}

Program Uji (tidak pernah menyerah file). Anda dapat melihatnya mengisi disk dan meskipun menghapus logfile akan berfungsi, sebenarnya tidak akan membebaskan ruang apa pun pada disk:

cat /dev/urandom >> /tmp/temp.log

Menjalankan log rotate:

logrotate truncate.cfg
Sam Hendley
sumber
Ini adalah teori yang bagus, tetapi tidak benar-benar berfungsi pada sistem apa pun yang saya coba. File tidak benar-benar terpotong dan program terus menambahkannya seperti sebelumnya. (Dan ya, itu bahkan dengan pengalihan dilakukan melalui >>.) ((BTW, jawaban ini sudah diberikan sebelumnya.))
Miral
1
... seperti yang dibahas dalam logrotate tidak akan memotong file asli (di situs Unix & Linux kami). Juga, echo /dev/urandom >> /tmp/temp.logakan menulis 13 karakter deterministik ke /tmp/temp.logdan kemudian segera keluar. Apakah maksud Anda cat /dev/urandom?
G-Man Mengatakan 'Reinstate Monica'
2
Baru diuji di sini, dan sepertinya berhasil. Konten file disalin ke file log baru. File asli tetap terbuka oleh proses dan dipotong (ukuran sekarang menunjukkan 0).
Philipp
1
Hati-hati dengan kemungkinan hilangnya data dengan copytruncate.
wanghq
1
+1 meskipun "Perhatikan bahwa ada irisan waktu yang sangat kecil antara menyalin file dan memotongnya, sehingga beberapa data logging mungkin hilang."
Tagar
3

Jadi apakah ada cara untuk membuat logrotate berfungsi dengan proses pengalihan yang sedang berlangsung?

Iya! Lihatlah arahan "copytruncate" yang ditawarkan oleh logrotate. Menentukan bahwa menginstruksikan logrotate untuk menangani situasi ini: sebuah program sederhana yang membuat file log-nya terbuka tanpa batas.

Satu peringatan mungkin atau mungkin tidak menjadi masalah dalam situasi Anda:

Perhatikan bahwa ada irisan waktu yang sangat kecil antara menyalin file dan memotongnya, sehingga beberapa data logging mungkin hilang.

Secara anekdot, saya telah melihat beberapa sumber log "dunia nyata" yang mendorong pengguna untuk menerapkan arahan ini. Ada beberapa diskusi tentang opsi ini di sini .

natevw
sumber
3

Gunakan split, itu bagian dari coreutils. Ia dapat mengambil stdin dan membaginya menjadi potongan-potongan (berdasarkan ukuran potongan, atau jumlah garis, dll.).

Contoh:

app | split --bytes 1G - /var/logs/put-prefix-here

Note dash (-) memerintahkan "split" untuk menggunakan stdin alih-alih file.

Nazar
sumber
Bisakah Anda memperluas jawaban Anda untuk menjelaskan bagaimana melakukannya? Terima kasih.
fixer1234
baru saja memperbarui balasan saya dengan contoh.
Nazar
1G adalah ukuran arbitrer, setelah itu memulai file baru?
fixer1234
1
Ini bukan solusi yang baik untuk masalah ini karena itu berarti Anda dapat mengakhiri dengan setengah pesan di satu file dan setengah di yang berikutnya. Ada juga risiko kehilangan data jika mesin mogok sementara splitmemiliki data dalam apa yang bisa menjadi buffer besar. Mengingat bahwa ada beberapa alat yang menyelesaikan masalah ini dengan benar, saya tidak berpikir solusi roll-your-own semacam ini dapat direkomendasikan.
David Richerby
1
@ David Richerby- bagaimana kalau menambahkan -u untuk unbuffered?
Nick
3

Saya suka multiloguntuk use case saya, tetapi use case saya sangat sepele / sederhana sehingga tidak ditata dengan sangat sederhana dalam dokumen / contoh yang saya temukan. Berikut ini adalah contoh rotate multilog sederhana:

mkdir /tmp/myapp
./myapp | multilog t s10000 n5 '!tai64nlocal' /tmp/myapp 2>&1

Beberapa catatan:

  • dumps ini masuk ke direktori / tmp / myapp /
  • s10000 mewakili 10.000 byte *
  • n5 mewakili 5 file. * Log 'saat ini' dianggap sebagai salah satu file, jadi ini termasuk 4 log lama + 'saat ini'
  • ini didasarkan pada, diadaptasi dari contoh-contoh yang disediakan oleh François Beausoleil di: http://blog.teksol.info/pages/daemontools/best-practices
  • Saya tidak mengerti banyak pilihan - saya merujuk Anda ke berbagai dokumentasi untuk memperpanjang ini ...
  • Dokumen memperingatkan bahwa: di "Note that running processor may block any program feeding input to multilog."mana 'prosesor' adalah '!tai64nlocal'bagian dari perintah

* Untuk banyak aplikasi, ini adalah pilihan yang buruk untuk penggunaan jangka panjang. Mereka memungkinkan Anda untuk mengamati perilaku mengisi dan memutar log lebih cepat daripada log besar.

Akhirnya, jangan lupa nohup jika diminta! Dengan nohup, Anda tidak perlu 2>&1(s = 10e6 dan n = 30 di sini):

mkdir -p /tmp/myapp
nohup ./myapp | multilog t s10000000 n30 '!tai64nlocal' /tmp/myapp &

Perintah itu harus membantu Anda memulai.

Sage
sumber
1

Saya hanya ingin menambahkan komentar Sam Hendley di atas:

Kuncinya adalah ini hanya berfungsi jika pengalihan dilakukan dengan >>(append) bukan >(buat).

Saya mengalami masalah yang sama di mana file asli terus tumbuh jika Anda menggunakan >(buat) tetapi jika Anda menggunakan >>(menambahkan) Logrotate copytruncate berfungsi dengan baik dan seperti yang diharapkan. File asli kembali ke nol byte dan program terus menulis.

Redirect STDOUT dan STDERR ke file log berputar:

  1. some-program.sh >> /tmp/output.txt 2>&1 &
  2. Buat file konfigurasi logrotate dengan /etc/logrotate.dnama apa pun, output_roll dalam kasus saya.

    Contoh konfigurasi untuk kasus saya:

    /tmp/output.txt {
        notifempty
        missingok
        size 1G
        copytruncate
        start 0
        rotate 15
        compress
    }
    
  3. Atur pekerjaan cron Anda di dalam /etc/crontabfile

    *  *  *  *  * root /usr/sbin/logrotate /etc/logrotate.d/output_roll
    

    Ini akan memeriksa file setiap menit. Anda dapat menyesuaikan sesuai dengan kebutuhan Anda.

  4. Mulai itu:

    $> service crond restart
    
  5. Itu dia

Catatan: Saya juga punya masalah dengan SELinux yang diatur SELINUX=enforcingjadi saya atur SELINUX=disabled.

pengguna578558
sumber
1

Saya menulis logrotee akhir pekan ini. Saya mungkin tidak akan melakukannya jika saya sudah membaca jawaban JdeBP dan multilog.

Saya fokus pada itu menjadi ringan dan mampu bzip2 potongan outputnya seperti:

verbosecommand | logrotee \
  --compress "bzip2 {}" --compress-suffix .bz2 \
  /var/log/verbosecommand.log

Masih banyak yang harus dilakukan dan diuji.

Victor Sergienko
sumber