Günlük dosyası satırlarıyla birlikte zaman damgası damgası ekleme


11

Bir günlük dosyası var ve onlar eklenir gibi her satıra zaman damgaları eklemek gerekir. Bu yüzden günlük satırlarındaki her girişe zaman damgaları ekleyen ve bir cron işi olarak çalışabilecek komut dosyası arıyorum.

Yanıtlar:


18

Genel Yol

$ cat input.log | sed -e "s/^/$(date -R) /" >> output.log

Nasıl çalışır:

  1. catadlı dosyayı okur input.logve standart çıktı akışına yazdırır.

    Normalde standart çıkış bir terminale bağlanır, ancak bu küçük komut dosyası, |kabuğun standart çıkışını catstandart girişine yönlendirir sed.

  2. sedverileri okur ( catürettiği gibi), işler ( -eseçenekle birlikte sağlanan komut dosyasına göre ) ve sonra standart çıktısına yazdırır. Komut dosyası "s/^/$(date -R) /", satırın her başlangıcını date -Rkomut tarafından oluşturulan bir metne değiştirir (replace komutunun genel yapısı:) s/pattern/replace/.

  3. Sonra göre >> bashçıktı sedbir dosyaya yönlendirir output.log( >dosya içeriğini değiştirmek >>anlamına gelir ve sonuna sonuna anlamına gelir).

$(date -R)Komut dosyasını çalıştırdığınızda, her satırın başına geçerli zaman damgasını ekleyecek şekilde sorun bir kez değerlendirilir . Geçerli zaman damgası, bir iletinin oluşturulduğu andan çok uzakta olabilir. Bunu önlemek için iletileri bir cron işi ile değil, dosyaya yazılırken işlemeniz gerekir.

FIFO

Yukarıda açıklanan standart akım yönlendirmesi boru olarak adlandırılır . Yalnızca |komut dosyasındaki komutlar arasında değil, bir FIFO dosyası aracılığıyla da adlandırılır (pip adı da verilir ). Bir program dosyaya yazar ve diğeri verileri okur ve ilk gönderilirken alır.

Bir örnek seçin:

$ mkfifo foo.log.fifo
$ while true; do cat foo.log.fifo | sed -e "s/^/$(date -R) /" >> foo.log; done;

# have to open a second terminal at this point
$ echo "foo" > foo.log.fifo
$ echo "bar" > foo.log.fifo
$ echo "baz" > foo.log.fifo

$ cat foo.log      

Tue, 20 Nov 2012 15:32:56 +0400 foo
Tue, 20 Nov 2012 15:33:27 +0400 bar
Tue, 20 Nov 2012 15:33:30 +0400 baz

Nasıl çalışır:

  1. mkfifo adlandırılmış bir kanal oluşturur

  2. while true; do sed ... ; donesonsuz bir döngü çalıştırır ve her yinelemede standart girişine sedyönlendirerek çalışır foo.log.fifo; sed giriş verilerinin beklemesini engeller ve daha sonra alınan bir mesajı işler ve yönlendirilen standart çıkışa yazdırır foo.log.

    Bu noktada, döngü geçerli terminali işgal ettiğinden yeni bir terminal penceresi açmanız gerekir.

  3. echo ... > foo.log.fifofifo dosyasına yönlendirilen standart çıktısına bir ileti yazdırır ve sedalır ve işler ve normal bir dosyaya yazar.

Önemli not, kenarlarından biri herhangi bir işleme bağlı değilse diğer boruların hiçbir anlamı olmadığı için fifo'dur. Bir boruya yazmaya çalışırsanız, geçerli işlem birisi borunun diğer tarafındaki verileri okuyana kadar engellenir . Bir kanaldan okumak istiyorsanız, birisi boruya veri yazana kadar işlem engellenir . sedBunu yapana kadar örnekte döngü üstünde bir şey (uyur) yapar echo.

Özel durumunuz için uygulamanızı fifo dosyasına günlük mesajları yazacak şekilde yapılandırmanız yeterlidir. Yapılandıramıyorsanız - orijinal günlük dosyasını silin ve bir fifo dosyası oluşturun. Ancak tekrarlayın, eğer seddöngü bir nedenden ötürü ölürse - programınız writebirisi readfifo'dan çıkana kadar dosyaya denendiğinde engellenir .

Yarar, program dosyayı dosyaya yazarken bir iletiye değerlendirilen ve eklenen geçerli zaman damgasıdır.

Eşzamansız İşlemler tailf

Günlüğe yazmayı ve işlemeyi daha bağımsız hale getirmek için iki normal dosya kullanabilirsiniz tailf. Bir uygulama ham bir dosyaya mesaj yazacak ve diğer işlemler yeni satırları okuyacaktır (eşzamansız olarak yazmaları takip edin) ve verileri ikinci dosyaya yazarak işleyecektir.

Bir örnek verelim:

# will occupy current shell
$ tailf -n0 bar.raw.log | while read line; do echo "$(date -R) $line" >> bar.log; done;

$ echo "foo" >> bar.raw.log
$ echo "bar" >> bar.raw.log
$ echo "baz" >> bar.raw.log

$ cat bar.log

Wed, 21 Nov 2012 16:15:33 +0400 foo
Wed, 21 Nov 2012 16:15:36 +0400 bar
Wed, 21 Nov 2012 16:15:39 +0400 baz

Nasıl çalışır:

  1. Yazmaları tailfizleyen işlemi çalıştırın bar.raw.logve bunları sonsuz while read ... echodöngüye yönlendirilen standart çıktıya yazdırın . Bu döngü iki eylem gerçekleştirir: standart girişten veri adlı bir tampon değişkenine veri okuyun lineve ardından aşağıdaki tamponlanmış verilerle oluşturulan zaman damgasını yazın bar.log.

  2. Adresine bazı mesajlar yazın bar.raw.log. Bunu ayrı bir terminal penceresinde yapmak zorundasınız, çünkü ilki tailfyazmaları takip edecek ve işini yapacak. Oldukça basit.

Artıları, öldürürseniz uygulamanızın engellemeyeceğidir tailf. Eksileri daha az doğru zaman damgaları ve yinelenen günlük dosyaları.


Teşekkür ederim .Fifo benim kullanımım için çok uygun görünüyor. Programım zaten bir file.txt günlüğüne yazıyor, ancak bu dosyanın foo.log.fifo adresine yönlendirilmesi gerekiyor. ! Peki nasıl ben de zaman ekleyebilir böylece bir güncelleme günlük dosyasında içeriği bu foo.log.fifo yönlendirebilir miyim.
Kratos

Sadece cevabı geliştirdim. Fifo'nuzun neden engellendiğini tailfaçıkladı, kullanmak için doğru yolu ekledi. Aslında bunun yolu tailfdaha zarif görünüyor, ama birileri için yararlı olacağını umarak fifo yolunu bıraktım.
Dmitry Vasilyanov

Vmstat çıktısına açıklama eklemek için sed cevabınızı kullanmak, değişmeyen zaman damgası verir, vmstat 1 | sed -e "s / ^ / $ (tarih -R) /"
ChuckCottrill


2

Dmitry Vasilyanov'un cevabından değiştirildi.

Bh komut dosyasında, çıkışı zaman damgası ile satır satır satır yönlendirebilir ve sarabilirsiniz.

Ne zaman kullanılır:

  • Bh betiği işleri için, satırı ana betiğin önüne ekleyin
  • Komut dosyası olmayan işler için, programı çağırmak üzere bir komut dosyası oluşturun.
  • Sistem tarafından kontrol edilen hizmetler tailfiçin, Dmitry Vasilyanov'un dediği gibi günlük dosyası için kullanmak daha iyidir .

Adlı bir örnek foo.sh:

#!/bin/bash
exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;)

echo "foo"
sleep 1
echo "bar" >&2
sleep 1
echo "foobar"

Ve sonuç:

$ bash foo.sh
$ cat foo.log
May 12 20:04:11 foo
May 12 20:04:12 bar
May 12 20:04:13 foobar

Nasıl çalışır

  1. exec &> Stdout ve stderr'ı aynı yere yönlendirin
  2. >( ... ) asenkron iç komuta boru çıkışları
  3. Geri kalan kısım Dmitry Vasilyanov genişledikçe çalışıyor.

Örneğin:

  • boru zaman damgası ve günlük dosyası

    #!/bin/bash        
    exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line" >> foo.log; done;)
    
    echo "some script commands"
    /path-to/some-thrid-party-programs
    
  • Veya zaman damgasını yazdırın ve stdout'a giriş yapın

    #!/bin/bash        
    exec &> >(while read line; do echo "$(date +'%h %d %H:%M:%S') $line"; done;)
    
    echo "some script commands"
    /path-to/some-thrid-party-programs
    

    sonra onları /etc/crontabortamda kaydedin

    * * * * * root /path-to-script/foo.sh >> /path-to-log-file/foo.log
    

1

tsBu yolu, Cacti'nin uzak bir ana bilgisayarın istatistikleriyle doldurmasını sağlamak için kullandığım bir komut dosyasının hata günlüğünde bir zaman damgası içeren bir giriş almak için kullanılır .

Kaktüsleri test randetmek için, sistemlerimin sıcaklığını izlemek amacıyla sıcaklık grafikleri için kullandığım bazı rastgele değerler eklemek için kullanıyorum.

Pushmonstats.sh, bilgisayarımın sistem sıcaklığı istatistiklerini toplayan ve bunu Cacti'nin çalıştığı bir Raspberry Pi'ye gönderen bir komut dosyasıdır. Bir süre önce, ağ sıkışmıştı. Hata günlüğümde yalnızca SSH zaman aşımları var. Ne yazık ki, bu günlükte zaman girişi yok. Bir günlük girişine nasıl zaman damgası ekleyeceğimi bilmiyordum. Yani, internette yapılan bazı aramalardan sonra, bu yazıyı tökezledim ve bunu kullanarak yaptım ts.

Test etmek için bilinmeyen bir seçenek kullandım rand. Hangi stderr bir hata verdi. Yakalamak için geçici bir dosyaya yönlendiriyorum. Sonra cat içeriğini kullanarak dosyanın içeriğini göstermek ve pipo ts, bu yazı bulduğum bir zaman biçimi eklemek ve nihayet hata dosyasına oturum. Daha sonra geçici dosyanın içeriğini temizlerim, aksi takdirde aynı hata için çift giriş alırım.

crontab:

* * * * * /home/monusr/bin/pushmonstats.sh 1>> /home/monusr/pushmonstats.log 2> /home/monusr/.err;/bin/cat /home/monusr/.err|/usr/bin/ts %F-%H:%M:%.S 1>> /home/monusr/pushmonstats.err;> /home/monusr/.err

Bu, hata günlüğümde aşağıdakileri verir:

2014-03-22-19:17:53.823720 rand: unknown option -- '-l'

Belki de bunu yapmanın çok zarif bir yolu değil, ama işe yarıyor. Daha zarif bir yaklaşım olup olmadığını merak ediyorum.

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.