İlk N satırını etkin bir günlük dosyasından kaldırın.


26

İlk Nsatırları bir uygulama tarafından aktif olarak eklenmiş olan bir kütükten çıkarmanın bir yolu var mı ?

Yanıtlar:


10

Hayır, Linux gibi işletim sistemleri ve dosya sistemleri, bir dosyanın başındaki verileri kaldırmak için gerekli önlemleri almazlar. Başka bir deyişle, bir dosyanın depolamasının başlangıç ​​noktası sabittir.

Bir dosyanın başlangıcından satırları kaldırmak, genellikle kalan verileri yeni bir dosyaya yazıp eskisini silerek gerçekleştirilir. Bir program eski dosyayı yazmaya açıksa, uygulama dosyayı kapatıncaya kadar bu dosyanın silinmesi ertelenir.


Yorum yapanların da belirttiği gibi, önceki cümlemde verilen nedenlerden dolayı, genellikle günlük dosyasını budama günlüklerini yazan programlarla koordine etmeniz gerekir. Tam olarak bunu nasıl yaptığınız programlara bağlıdır. Bazı programlar, bir sinyal gönderdiğinizde (ör. HUP) günlük dosyalarını kapatır ve yeniden açar ve bu, hizmetin kesilmeden günlük kayıtlarının 'silinen' günlük dosyalarına yazılmasını önlemek için kullanılabilir.

Günlük dosyalarının boyutunu yönetmek için kullanılabilecek birçok yardımcı program vardır, örneğin logrotate

Bazı programların kendi yardımcı programları vardır. Örneğin, Apache web sunucusu bir rotatelog yardımcı programı içerir .


3
Ancak, bir şey hala dosyayı açmış ve hala ekleyebilecek bir şey varken bunu yapmamalısınız, çünkü şimdi silinen dosyaya yazacak ve bu günlük iletilerini kaybedeceksiniz.
Tarnay Kálmán

Doğru. Aynı dosya adını kullanmış olsanız bile.
Hennes

işletim sistemlerinin izin vermemesi çok kötü, günlük döndürücüler için döndürmeden sonra işlemleri yeniden yüklemek zorunda kalmamaları kesinlikle uygun olurdu: |
rogerdpack

25

Bence bu görev başarılabilir sed

sed -i '1,10d' myfile

1 çizgileri gidermeye olur st 10 inci çizgi formunda dosyasını.

Bence herkes en azından bu 1 gömleke bir göz atmalı .

Bunun bir uygulama tarafından aktif olarak eklenmiş olan logfile'ler için işe yaramadığını unutmayın (soruda belirtildiği gibi).

sed -iyeni bir dosya oluşturacak ve yazılmakta olan dosyayı 'silecektir'. Çoğu uygulama silinen günlük dosyasına günlük kayıtları yazmaya ve disk alanını doldurmaya devam edecektir. Yeni, kesilmiş, günlük dosyasına eklenmeyecek. Bu, yalnızca uygulama yeniden başlatıldığında ya da günlük dosyalarını kapatıp yeniden açmak için işaret edildiğinde kesilir. Sed kullanımı ile uygulamanın yeniden başlatılması arasında herhangi bir kayda değer aktivite varsa, bu noktada yeni kayıt dosyasında bir boşluk (eksik kayıt kayıtları) olacaktır.

Bunu yapmanın güvenli bir yolu, uygulamayı durdurmak, günlüğü kesmek için sed komutunu kullanmak ve uygulamayı yeniden başlatmak olabilir. Bu yaklaşım bazı servisler için kabul edilemez (örneğin, yüksek verimli ve yüksek servis sürekliliği gereksinimleri olan bir web sunucusu)


2
Eklenen uygulamalara ne olacağını biliyor musunuz?
Adam Matan

1
Her seferinde ve sonrasında satır ekleyen ve sifon çeken normal bir açık dosya işleyicisi alalım.
Adam Matan

1
Sed 'e doğru yolumu biliyorum ve yeni bir dosyaya satır çıkarmak, sed' le alakasız. Sorun, hepsini aynı dosyada tutmak.
Adam Matan

10
Hayır, bu çalışmamalı. Düzenlenen içeriğe sahip yeni bir dosyased -i oluşturur ve eskisini kaldırır, böylece etkin dosyayı düzenlemezsiniz: ------ Lütfen nasıl çalıştığını kontrol edin . Neden bu yanlış cevabın bu kadar çok olumlu yönü var? $ ls -i --- 6823554 testfile --- $ sed -i 's/test/final/' testfile --- $ ls -i --- 6823560 testfilesed -i
pabouk

1
Soru, "bir uygulama tarafından aktif olarak eklenen bir kütükten" demiştir. İşlemsel kelime "aktif" dir. Belki de cevabınız göründükten sonra açıklama eklenmiştir. Ancak, geçerli olduğu gibi, “en çok oyuna” odaklanan okuyucular yanıltıcı olacaktır. Sadece bir kere oy kullanabildim.
Scott Prive

5

Hayır. Günlük dosyası büyümesinin bu genel sorununa bir çözüm günlük döndürmedir. Bu, mevcut bir günlük dosyasının başka bir dosya adına düzenli olarak (gece veya haftalık olarak) taşınmasını ve boş bir günlük dosyasıyla yeni bir başlangıç ​​yapmasını içerir. Bir süre sonra eski günlük dosyaları atılır.

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


2

Bu bir cevap , bir çözüm değil. Sorunun hiçbir çözümü yok. Soru sahibi açıkça " Bir uygulama tarafından aktif olarak eklenmiş bir kayıttan". Daha fazla bilgi edinmek için okumaya devam edebilirsiniz ve bu kodun neden en iyi uygulamaları kaydetmeyi takip etmediğine dair varsayımımı temel alarak yaptığım bir öneri için atlayabilirsiniz .

Açık olmak gerekirse: buradaki diğer “cevaplar” yanlış söz veriyor . Hiçbir yeniden adlandırma, uygulamayı yeni dosyayı kullanmaya kandırmaz. Bu yanlış cevaplara yapılan yorumlarda en yararlı bilgiler yer almaktadır.

AKTİF dosyalar basitçe veri koyduğunuz bir tür konteyner değildir. Bir dosya adı BİR inode'a (dosyanın başlangıcı) işaret eder ve her inode'un başka bir inode'a (daha fazla veri varsa) işaretçisi vardır. Bu, sürekli yazılmış bir dosyaya, kendisine eklenen sabit bir inode akışına sahip olduğu ve bir "dosya" hakkında düşündüğünüzün aslında bir inode günlük dizisi olduğu anlamına gelir.

Birini Google Haritalar'da takip ettiğinizi ve bu kişinin dünyanın herhangi bir yerine, herhangi bir zamanda ışınlanabileceğini ve bu noktaları birleştirmeye çalıştığınızı hayal edin.

Linux aracı "truncate", dosya sonunda, sadece inode ağacında yürüyerek verileri atabilir ve (belirlediğiniz yerde / boyutta) yığındaki sonraki tüm işaretleyicileri atar. Dosyanın başında geriye doğru atma - yapmak - inode ağacını gerçek zamanlı olarak kimsenin böyle bir araç yazamayacağı kadar sık ​​sık karmaşık ve riskli bir işlem olurdu - çünkü çoğu zaman başarısız olur ve yol açar. veri kaybı. Wiki Dosyaindeksi kısadır ama bu kavramların bazılarını açıklar.

** Benim tavsiyem: Bu sorunu ters çevirin - Bu uygulama neden bu şekilde davranıyor? Birçok Günlük En İyi uygulaması var, ancak çoğu zaman günlük sisteminizin gerçekte ne olduğuna (syslog vb.) Bağlılar. Çekirdekte bir uygulamanın dosyaya tanıtıcısını "serbest bırakması" beklenir, böylece logrotate (etc) eski verilerin işlenmesini kaldırabilir.

Ne zaman "AKTİF bir günlük dosyasına" duyduğumda hemen bu kişiden bana bu uygulamanın arkasındaki "özel hikayeyi" söylemesini rica ediyorum. Genellikle "geliştirici istifa eder ve kodu değiştiremeyiz. Bu aslında güvenliğin tersidir, kendine özgü riskleri vardır. Ama kaynak koduna dokunmaktan kaçınan bir çözüm istiyorum. Bu durumda, daha spesifik bir soru gereklidir.


0

Üstün metinle açma Dosyaların eklenmesi halinde bile satırların silinmesi ve kaydedilmesi bir şekilde çalışır, ancak buraya bir komut satırı çözümü için çözüm aramaya geldim, bu yüzden bu çalışmayı ancak işe yaramaz çözümü burada bırakayım !!


-1

Belki kopyala, kes, kopyayı tekrar büyüklük = 0 kesmeye getir ve kopyayı sil?

Kuyruğa kopyalamak için daha iyi, ancak orijinali kısaltın, orijinal üzerine concat kuyruk kopyasını yerleştirin.

Günlükte kuyruk uzunluğunda çizgiler elde edersiniz, bayt uzunluğu sınırından daha iyidir.

Yorumdaki ayrıntıları değiştirme:

İlk önce Python3'te ne istersen bir logger scriptimiz var.

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)

Öyleyse truncator'umuz var.

#!/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 80 - 89’u gösterir

kütük 90 bittiğini gösterir

Zaten bir isteğin olduğu bir yol var.

Bir çok daha karmaşık konsolidasyon örneği ve yazma akışının nasıl açıldığı veya kapatıldığı, cpu çekirdeği başına ayarlamalar gerektirebilir.


msgstr "bir uygulama tarafından aktif olarak eklenmiş bir kütükten". Çözümünüzün gözardı ettiği sorun, günlük dosyasının uygulama tarafından "kalıcı olarak kullanımda" olmasıdır - bunun anlamı günlük dosyasının düğümü oyunda kalır. Çözümünüz bu sorunun dışında kullanmış olabilecek günlük dosyası verilerini "yedekler".
Scott Prive

Yorumunuz ve aşağı oy için teşekkür ederiz? Durumunuz hakkında daha derin düşünmek zorunda kalacağınız düşüncesi için yiyecek olarak hızlı ve ucuz bir örneği değiştirdim, ancak bir iradenin olduğu bir yol var.
Usta James

Aşağı oyum olduğunu sanmıyorum, ama diğer cevapların yorumlarına katlanılan nokta sanırım: Eğer bir günlük dosyasını kopyalarsan, o zaman artık aktif günlük dosyası değil, ne yaparsan yap. Uygulamanın dosya yuvası her zaman orijinal günlük dosyasının inode'una işaret eder. Bunu şu şekilde düşünün: standart olmayan kayıt işlevlerini kullanan ve sürekli açtığı dosyaya bayt ekleyen bir uygulamanız var.
Scott Prive

1
Çıkarım için üzgünüm. Evet, inode'un aynı kalması gerekiyor, bu nedenle verilen örnek / ispatın kısaltılmasını kullanıyor ve yine duruma bağlı (herkes için seçenekler düz sitelerde saklanıyor).
Usta James
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.