Stdout'un günlük dönüşü?


53

Stdout ve stderr'e bilgi yazabilen bir Linux programım var.

Bu çıktıyı bir dosyaya yönlendiren bir kabuk betiğim var /var/log. (Via >>ve 2>&1.)

Bu günlük dosyasını döndürmenin bir yolu var mı? (maksimum boyut, daha sonra farklı bir dosyaya geçin, yalnızca sınırlı sayıda dosyayı saklayın)

logrotateProgramdan bahseden , kulağa hoş gelen birkaç cevap gördüm , ancak bunlar ayrıca dahili olarak log dosyaları üreten ve HUP sinyallerini idare eden programlara odaklanmış görünüyorlar. Bu işlemi temel çıktı yönlendirme betiği ile yapmanın bir yolu var mı?


1
Döndürme mantığını içermesi için çıktıyı yeniden yönlendiren komut dosyasını neden değiştiremiyorsunuz?
MaQleod

Birisi bana bir log dosyasının boyutunu nasıl tespit edeceğimi söylerse ve o süreci rahatsız etmeden bir sürecin altından çıkarmayı söyleyebilirim. Ben yok olması kullanmak logrotatesadece tartışma için uygun bir başlangıç noktası gibiydi daha iyi bir seçenek, varsa.
Miral

2
Logrotate kullanmak zorunda değilsiniz, ancak logrotate kullanmak sadece zaman kazandırıyor ... Tekerleği yeniden icat eden genellikle küçük bir nokta var.
bubu

Kesinlikle benim açımdan. Peki, devam eden bir sürecin yönlendirilen stdout ile logrotate çalışmasını sağlamanın bir yolu var mı?
Miral

Yanıtlar:


44

Alternatif olarak, çıktıyı, örneğin: büyüklüğünde kapaklı, otomatik olarak döndürülmüş, günlük dosyası kümelerini korumak amacıyla birincil amaçlarla tasarlanmış araçlar aracılığıyla yönlendirebilirsiniz:

Daha sonra multilog-format günlük dosyası kümelerini işlemeye yarayan araçlar arasında, diğerleri:

daha fazla okuma


1
Teşekkürler, multilogtam ihtiyacım olan şeye benziyor.
Miral

multilog debian'daki tek tak-çalıştır çözümü gibi görünüyor (daemontools'un resmi paketi var). Ancak, özel durumumda, günlükleri bir fat32 bölümünde depolamak istediğimde, çok dilli bir sembolik bağlantı kullanmak istediğinden, döndürme çalışmaz. Benim için tak ve kullan yok :)
Arnout

multilogHiçbir yerde sembolik bağlar yarattığı veya talep ettiği gibi bu doğru olamaz . Onlara göre tamamen tarafsız.
JdeBP 23:18

"Bu yüzyılda logrotate ya da newsyslog kullanmayın" URL'sinin fazladan bir noktası var
duyue 6

15

rotatelogs(apache ile birlikte alet bindir) (bakınız dokümanlar ) zaman belirli bir süre sonra Standart giriş ve döndükçe log girişi alır


14

Standart günlük akışlarından birine (syslog, daemon, cron, kullanıcı, güvenlik, posta vb.) loggerGidebilirseniz bunun yerine komutu ve pipoyu kullanabilirsiniz.

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

Aksi takdirde, oturum açmak için içeriğinizi özel bir programa veya komut dosyasına işlemek veya logrotateyapılandırmayı ayarlamaya bakmak daha iyi olabilir .

EDIT: JdeBP'nin cevabı aradığın şeye sahip görünüyor.


2
Sadelik için +1. BTW, standart tesisler yerine özel bir tesis de (yerel0) yapılandırabilirsiniz (örneğinizdeki arka plan programı)
Roger Keays 9:12

14

Ben de benzer bir problem yaşadım ve başlangıçta logrotate'i atmıştım, ancak logrotate'in aslında bunu iyi yapabildiği ortaya çıktı, ana yönerge " copytruncate ". Bazı sebeplerden dolayı, bu terim benim yaptığım googlinglerden hiçbirinde ortaya çıkmadı, bu yüzden bu cevabı, bu dava için tam olarak nasıl kullanılacağını netleştirmek için ekliyorum.

İşin püf noktası, sadece yönlendirme " > " (oluştur) yerine " >> " (append) ile yapılırsa işe yarar .

Yapılandırma Dosyası (truncate.cfg):

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

Test Programı (asla dosyadan vazgeçmez). Doldurma diski izleyebilir ve logfile silme çalışacak gibi gözükse de, diskte yer boşaltmaz:

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

Çalışan günlük döndürme:

logrotate truncate.cfg

Güzel bir teori, ama üzerinde denediğim hiçbir sistemde çalışmıyor. Dosya aslında kesilmez ve program daha önce olduğu gibi eklemeye devam eder. (Ve evet, bu >> aracılığıyla yapılan yönlendirmelerde bile var.) ((BTW, bu cevap daha önce verildi.))
Miral

1
Logrotate'de tartışıldığı gibi orijinal dosyayı kesmeyecek (Unix ve Linux sitemizde). Ayrıca, echo /dev/urandom >> /tmp/temp.log13 deterministik karakter yazacak /tmp/temp.logve hemen çıkacaktır. Bunu mu demek istediniz cat /dev/urandom?
G-Man

2
Sadece burada test ve iş gibi görünüyor. Dosyanın içeriği yeni günlük dosyasına kopyalanır. Orijinal dosya işlem tarafından açık tutulur ve kesilir (boyut şimdi 0 gösterir).
Philipp

1
Copytruncate ile olası veri kaybı konusunda dikkatli olun.
wanghq

1
+1, "Dosyayı kopyalamak ve kesmek arasında çok küçük bir zaman dilimi olduğunu unutmayın; bu nedenle bazı günlük verileri kaybolabilir."
Tagar

3

Peki, devam eden bir sürecin yönlendirilen stdout ile logrotate çalışmasını sağlamak için bir yolu var mı?

Evet! Logrotate tarafından sunulan "copytruncate" yönergesine göz atın. Bu durumun üstesinden gelmek için logrotate talimatı verildiğini belirtmek: log dosyasını süresiz olarak açık tutan basit bir program.

Bir uyarı, sizin durumunuzda bir sorun olabilir veya olmayabilir:

Dosyanın kopyalanması ve kesilmesi arasında çok küçük bir zaman dilimi olduğunu unutmayın; bu nedenle bazı günlük verileri kaybolabilir.

Her halükarda, kullanıcıları bu yönergeyi uygulamaya teşvik eden "gerçek dünya" log kaynakları gördüm. Burada bu seçeneğin bir tartışması var .


3

Bölünmüş kullanın, çekirdek çekirdeklerin bir parçası. Stdin'i alabilir ve parçalara bölebilir (yığın boyutuna veya satır sayısına vb. Bağlı olarak).

Örnek:

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

Not dash (-) "split" komutuna dosya yerine stdin kullanma talimatını verir.


Bunun nasıl yapıldığını açıklamak için cevabınızı genişletebilir misiniz? Teşekkürler.
fixer1234

cevabımı örnek ile güncelledim.
Nazar

1G isteğe bağlı bir boyuttur ve bundan sonra yeni bir dosya başlatır mı?
fixer1234

1
Bu, problem için genel olarak iyi bir çözüm değildir, çünkü bir dosyada yarım mesaj, diğerinde yarım mesaj olabilir. splitBüyük bir arabellek olabilecek verilerde makine çökerse veri kaybı riski de vardır . Bu sorunu doğru bir şekilde çözen birden fazla araç olduğu göz önüne alındığında, bu tür bir çözüm için kendi çözümünüzü tavsiye edebileceğimi sanmıyorum.
David Richerby

1
@David Richerby - arabelleksizler için -u eklemeye ne dersiniz?
Nick,

3

Sevdiğim multilogbenim kullanım örneği için, ama benim kullanma durumu ben buldum docs / örneklerde çok basit düzenlendiği değil böylece önemsiz / basittir. İşte basit bir çoklu dil döndürme örneği:

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

Bazı notlar:

  • bu, o / tmp / myapp / dizinine giriş yapar
  • s10000 10.000 baytı temsil eder *
  • n5 5 dosyayı temsil eder. * 'current' günlüğü dosyalardan biri olarak sayılır, bu yüzden 4 eski günlüğü + 'current'
  • Bu, François Beausoleil tarafından sağlanan örneklere göre uyarlanmıştır: http://blog.teksol.info/pages/daemontools/best-practices
  • Seçeneklerin çoğunu anlamadım - sizi genişletmek için çeşitli belgelere atıfta bulunuyorum ...
  • Dokümanlar şunu uyarır: "Note that running processor may block any program feeding input to multilog."'işlemci' '!tai64nlocal'komutun kısmıdır

* Pek çok uygulama için, bunlar uzun süreli kullanım için zayıf seçimlerdir. Büyük kütüklerden daha hızlı bir şekilde kütükleri doldurma ve döndürme davranışını gözlemlemenizi sağlar.

Son olarak, gerekirse nohup unutma! Nohup ile, 2>&1(s = 10e6 ve n = 30 burada) ihtiyacınız yok:

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

Bu komut seni başlatmalı.


1

Sadece Sam Hendley'in yukarıdaki yorumuna eklemek istedim:

İşin püf noktası, bu sadece yönlendirme (create) >>yerine (append) ile yapılırsa işe yarar >.

Aynı dosyayı kullandıysanız >(oluştur) kullanırsanız >>(ekleme) Logrotate copytruncate güzel ve beklendiği gibi çalışıyorsa , orijinal dosyanın büyümeye devam etmesiyle karşılaştım. Orijinal dosya sıfır bayta geri gider ve program yazmaya devam eder.

STDOUT ve STDERR'i dönen bir günlük dosyasına yönlendirin:

  1. some-program.sh >> /tmp/output.txt 2>&1 &
  2. /etc/logrotate.dBenim durumumda, her ne kadar output_roll adında bir logrotate config dosyası oluşturun .

    Benim durumum için örnek yapılandırma:

    /tmp/output.txt {
        notifempty
        missingok
        size 1G
        copytruncate
        start 0
        rotate 15
        compress
    }
    
  3. Cron işinizi /etc/crontabdosyanın içine yerleştirin

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

    Bu dosyayı her dakika kontrol eder. İhtiyaçlarınıza göre ayarlayabilirsiniz.

  4. Başla:

    $> service crond restart
    
  5. Bu kadar

Not: Ben de hiç SELinux'un olmak seti ile ilgili bir sorun vardı SELINUX=enforcingben ayarlayın böylece SELINUX=disabled.


1

Bu haftasonu bir kayıt defteri yazdım . @ JdeBP'nin en iyi cevabını okuduysam muhtemelen söylemem multilog.

Hafif olmasına ve çıktı parçalarını bzip2'ye yapabilmeye odaklandım:

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

Yine de yapılacak ve test edilecek çok şey var.

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.