Hapus baris N pertama dari file log yang aktif

26

Apakah ada cara untuk menghapus Nbaris pertama dari log yang sedang aktif ditambahkan oleh aplikasi?

Adam Matan
sumber

Jawaban:

10

Tidak, sistem operasi seperti Linux, dan sistem filenya, tidak membuat ketentuan untuk menghapus data dari awal file. Dengan kata lain, titik awal penyimpanan untuk file diperbaiki.

Menghapus baris dari awal file biasanya dilakukan dengan menulis data yang tersisa ke file baru dan menghapus yang lama. Jika suatu program memiliki file lama terbuka untuk ditulis, penghapusan file itu ditunda hingga aplikasi menutup file.


Sebagai komentator mencatat, untuk alasan yang diberikan dalam kalimat saya sebelumnya, Anda biasanya perlu mengkoordinasikan pemangkasan logfile dengan program yang menulis log. Cara Anda melakukan ini tergantung pada programnya. Beberapa program akan menutup dan membuka kembali file log mereka ketika Anda mengirim sinyal (misalnya HUP) dan ini dapat digunakan untuk mencegah catatan log ditulis ke file log 'dihapus', tanpa mengganggu layanan.

Ada banyak utilitas yang tersedia untuk mengelola ukuran file log, misalnya logrotate

Beberapa program memiliki utilitasnya sendiri. Misalnya, server web Apache menyertakan utilitas rotatelogs .

RedGrittyBrick
sumber
3
Tetapi Anda tidak harus melakukan ini ketika sesuatu masih memiliki file terbuka dan masih menambahkannya, karena itu akan menulis ke file yang sekarang dihapus, dan Anda akan kehilangan pesan log tersebut.
Tarnay Kálmán
Benar. Bahkan jika Anda menggunakan nama file yang sama.
Hennes
sayang sekali OS jangan biarkan Anda, itu pasti nyaman untuk rotater log untuk tidak harus memuat ulang proses setelah rotasi: |
rogerdpack
25

Saya pikir tugas ini dapat dicapai dengan sed

sed -i '1,10d' myfile

akan menghapus baris dari 1 st ke 10 th bentuk baris file.

Saya pikir semua orang setidaknya harus melihat sed 1 liners ini .

Perhatikan bahwa ini tidak berfungsi untuk file log yang sedang ditambahkan secara aktif oleh aplikasi (sebagaimana dinyatakan dalam pertanyaan).

sed -iakan membuat file baru dan 'menghapus' file yang sedang ditulis. Sebagian besar aplikasi akan terus menulis catatan log ke file log yang dihapus dan akan terus mengisi ruang disk. File log yang baru, terpotong, tidak akan ditambahkan ke. Ini hanya akan berhenti ketika aplikasi di-restart atau ditandai untuk menutup dan membuka kembali file log-nya. Pada titik mana akan ada celah (catatan log yang hilang) dalam file log baru jika telah ada aktivitas yang dapat loggable antara penggunaan sed dan restart aplikasi.

Cara yang aman untuk melakukan ini adalah menghentikan aplikasi, menggunakan sed untuk memotong log, kemudian restart aplikasi. Pendekatan ini dapat tidak dapat diterima untuk beberapa layanan (misalnya server web dengan throughput tinggi dan persyaratan kontinuitas layanan tinggi)

lzard
sumber
2
Apakah Anda tahu apa yang terjadi pada aplikasi yang menambahkan?
Adam Matan
1
Mari kita asumsikan file handler normal terbuka yang menambahkan baris dan flush setiap saat.
Adam Matan
1
Saya tahu jalan sekitar sed, dan mengekstraksi baris ke file baru adalah no-brainer dengan sed. Masalahnya adalah menyimpan semuanya di file yang sama.
Adam Matan
10
Tidak, ini seharusnya tidak berhasil. sed -imembuat file baru dengan konten yang diedit dan yang lama dihapus sehingga Anda tidak mengedit file yang aktif: $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfile------ Silakan periksa bagaimana cara sed -ikerjanya. Mengapa jawaban yang salah ini memiliki begitu banyak upvotes?
pabouk
1
Pertanyaannya menyatakan "dari log yang sedang aktif ditambahkan oleh aplikasi". Kata yang digunakan adalah "aktif". Mungkin klarifikasi itu ditambahkan setelah jawaban Anda muncul. Tapi seperti berdiri, pembaca yang condong ke "sebagian besar upvotes" AKAN menyesatkan. Saya hanya bisa downvote sekali.
Scott Prive
5

Tidak. Solusi untuk masalah umum pertumbuhan file log ini adalah rotasi log. Ini melibatkan pemindahan reguler (malam atau mingguan, biasanya) dari file log yang ada ke nama file lain dan mulai dengan file log yang kosong. Setelah suatu periode file-file log lama dibuang.

Lihat: http://www-uxsup.csx.cam.ac.uk/~jw35/courses/apache/html/x1670.htm

Tarnay Kálmán
sumber
2

Ini adalah jawaban , bukan solusi. Tidak ada solusi untuk pertanyaan itu. Penanya dengan jelas menyatakan: "dari log yang sedang aktif ditambahkan oleh aplikasi". Anda dapat membaca terus untuk memahami lebih lanjut, dan lewati sampai akhir untuk saran yang saya buat berdasarkan anggapan saya mengapa kode ini tidak mengikuti praktik terbaik logging.

Agar lebih jelas: "jawaban" lain di sini menawarkan janji palsu . Pengubahan nama dalam jumlah apa pun tidak akan menipu aplikasi untuk menggunakan file baru. Informasi yang paling berguna terkubur dalam komentar yang dibuat untuk jawaban yang salah ini.

File AKTIF bukanlah semacam wadah tempat Anda memasukkan data. Nama file menunjuk ke ONE inode (mulai dari file) dan setiap inode memiliki pointer ke inode lain (jika ada lebih banyak data). Itu berarti file yang ditulis terus-menerus memiliki aliran konstan dari inode yang ditambahkan padanya, dan apa yang Anda pikirkan tentang "file" sebenarnya adalah urutan log dari inode.

Bayangkan Anda melacak seseorang di Google Maps, dan orang itu dapat berteleportasi ke mana saja di dunia, kapan saja, dan Anda mencoba menghubungkan titik-titik ini.

Alat Linux "truncate" dapat membuang data di akhir file, hanya dengan berjalan di pohon inode dan (pada lokasi / ukuran yang Anda tentukan) itu akan membuang semua pointer berikutnya dalam stack. Untuk melakukan sebaliknya - membuang data di awal file - akan menjadi proses yang sangat rumit dan berisiko menulis ulang pohon inode secara real-time sehingga tidak ada yang akan menulis alat seperti itu untuk umum, karena mereka sering gagal dan mengarah ke Data hilang. The inode wiki pendek tapi menjelaskan beberapa konsep-konsep ini.

** Saran saya: balikkan masalah ini - MENGAPA aplikasi ini bersikap seperti ini? Ada banyak praktik terbaik Pencatatan, tetapi seringkali mereka terkait dengan sistem logging Anda yang sebenarnya (syslog, dll). Pada intinya, sebuah aplikasi diharapkan untuk "melepaskan" itu menangani ke file, sehingga logrotate (dll) dapat menangani pemrosesan lebih lanjut dari data lama.

Setiap kali saya mendengar "ke logfile AKTIF", saya segera meminta orang itu untuk memberi tahu saya "cerita khusus" di balik aplikasi ini. Biasanya itu adalah "pengembang berhenti, dan kami tidak dapat mengubah kode. Ini sebenarnya kebalikan dari keamanan, memiliki set risiko sendiri. Tapi saya mendapatkan Anda menginginkan solusi yang menghindari menyentuh kode sumber. Jika ini adalah kasus, pertanyaan yang lebih spesifik diperlukan.

Scott Prive
sumber
0

Membuka dalam teks yang luhur Menghapus baris dan menyimpan file berfungsi entah bagaimana, bahkan jika file tersebut ditambahkan, tapi saya datang ke sini untuk mencari solusi untuk solusi baris perintah, jadi saya hanya akan meninggalkan solusi yang berfungsi tapi tidak berguna ini di sini !!

Ashok Kumar Sahoo
sumber
-1

Mungkin menyalin, memotong, mengembalikan salinan ke ukuran = 0 pemotongan, dan menghapus salinan?

Lebih baik lagi untuk menyalin-ekor, memotong asli, menyalin-ekor konat ke asli.

Anda mendapatkan garis dalam log pada panjang ekor jadi lebih baik daripada batas panjang byte.

Mengubah detail dari komentar:

Pertama, kita memiliki skrip logger di Python3 apa pun yang Anda inginkan

from time import sleep

idx = 0
while 1 == 1:
    idx = (idx + 1)
    lf = open('tailTrunc.log', 'a')
    lf.write("line to file " + str(idx) + '\n')
    lf.close()
    sleep(0.01)

Lalu kita memiliki truncator kita

#!/usr/bin/env bash

trap "kill 0" EXIT

rm tailTrunc.log
touch tailTrunc.log

python3 logLoop.py &
loggerPID=$!
sleep 1

kill -STOP $loggerPID
tail -10 tailTrunc.log > trimEnd.log
truncate -s 0 tailTrunc.log
kill -CONT $loggerPID
sleep 1

trimEnd.log menunjukkan 80 hingga 89

log menunjukkan 90 hingga akhir

Pokoknya di mana ada kemauan di sana ada jalan.

Banyak contoh yang lebih rumit dari konsolidator dan bagaimana aliran penulisan dibuka atau ditutup mungkin perlu menyesuaikan per cpu core dll

Tuan James
sumber
"dari log yang sedang aktif ditambahkan oleh aplikasi". Masalahnya solusi Anda mengabaikan adalah bahwa file log "secara permanen" digunakan oleh aplikasi - yang berarti inode dari file log tetap dimainkan. Solusi Anda "mencadangkan" data logfile, yang mungkin menggunakan di luar pertanyaan ini.
Scott Prive
Terima kasih atas komentar dan suara Anda? Saya telah mengubah contoh murah cepat sebagai makanan untuk dipikirkan Anda harus berpikir lebih dalam tentang situasi Anda, tetapi di mana ada surat wasiat ada jalan.
Tuan James
Jangan mengira itu adalah suara turun saya, tapi saya pikir poinnya terpaku di komentar jawaban lain: JIKA Anda menyalin logfile, maka itu bukan lagi logfile aktif ... tidak peduli apa yang Anda lakukan. Filehandle aplikasi akan selalu menunjuk pada inode dari file log asli. Pikirkan seperti ini: Anda memiliki aplikasi yang menggunakan fungsi logging non-standar, dan terus menambahkan byte ke file yang telah dibuka.
Scott Prive
1
Maaf benar untuk menyimpulkan. Ya inode harus tetap sama itu sebabnya contoh / bukti yang diberikan menggunakan truncate, dan sekali lagi itu tergantung pada situasi (opsi untuk semua tampaknya bersembunyi di situs biasa).
Tuan James