Bir komutun çıktısını halka arabelleğe kaydetme


16

Stdout'ta çok fazla çıktı üreten uzun süren bir komutum var. Örneğin, yalnızca son üç günü veya son gibibiti (ortadaki kesme çizgilerinden kaçınarak) ve mümkünse 20 MiB'den büyük olmayan dosya parçalarında tutabilmek istiyorum. Her dosya yığını bir sayısal sonek veya zaman damgası ile adlandırılıyor.

Gibi bir şey:

my-cmd | magic-command --output-file-template=my-cmd-%t \
                       --keep-bytes=1G \
                       --keep-time=3d \
                       --max-chunk-size=20M \
                       --compress=xz

Yazarım:

my-cmd-2014-09-05T10:04:23Z

20M'ye ulaştığında, sıkıştırır ve yeni bir tane açar, vb. Ve bir süre sonra en eski dosyaları silmeye başlar.

Böyle bir komut var mı?

Biliyorum logrotateve diğer uygulamalar tarafından yazılan dosyaları yönetme yeteneği, ancak bir cron işi kurmak, kuralları belirtmek, işlemi askıya almak vb. Gerektirmeyen daha basit bir şey arıyorum.


"Gibibyte" nedir?
Peter Mortensen

@PeterMortensen Wikipedia: Gibibyte
jw013

Yanıtlar:


6

"Çalışmakta olan bir işlemin günlüğünü harici sinyallere yanıt veren bir ara kabloyla boruya çevirerek veya temizlemeye izin veren" olan pipelog aracılığıyla istediğinizi alabilirsiniz , örneğin:

spewstuff | pipelog spew.log -p /tmp/spewpipe.pid -x "gzip spew.log.1"

Daha sonra pid'i alabilirsiniz /tmp/spewpipe.pidve:

kill -s USR1 $(</tmp/spewpipe.pid)

Ama cron ya da başka bir şeyle kurman gerekecekti. Bununla birlikte, bir yakalama var. Uyarı I gzip spew.log.1- bunun nedeni -xkomutun günlük döndürüldükten sonra yürütülmesidir. Bu nedenle spew.log.1.gz, gzip'i yapmak ve daha sonra dosyayı taşımak için kısa bir komut dosyası yazmadıkça ve bunu komut olarak kullanmadığınız sürece her seferinde üzerine yazma sorunu yaşarsınız -x.

Tam açıklama: Bunu yazdım, bu yüzden elbette mükemmel çalışıyor . ;) Sürüm 0.2 için bir sıkıştırma seçeneğini veya daha iyi kolaylaştıran bir şeyi aklımda tutacağım (amaçlanan amaç -xbiraz farklıdır, ancak yukarıdaki gibi çalışacaktır). Ayrıca otomatik rollover iyi bir fikirdir ... ilk sürüm, gerekli olmayan özellikler eklemek için günaha karşı koyduğum için kasıtlı olarak minimumdur (sonuçta bunun için bir cron işi kurmak çok zor değildir).

Metin çıktısı için tasarlandığını unutmayın ; potansiyel null bayt varsa, kullanmalısınız -z- sıfır yerine başka bir şey koyar. Bu, uygulamayı basitleştirmek için bir ödünleşmedir.


Teşekkürler. pipelog-0.3;-) 'i dört gözle bekliyorum . Ayrıca metacpan.org/release/File-Write-Rotate ile de karşılaştım . Cron işlerinin dosya boyutuna göre döndürmeye pek yardımcı olmayacağını unutmayın.
Stéphane Chazelas

Boyutuna göre döndürme!?! Çıktıyı temiz tutar, bu nedenle dosyayı aralıklarla
sabitleyebilirsiniz

Boyutu 20M'nin altında tutamadım (soru gereksinimlerimdeki gibi) bu şekilde güvenilir bir şekilde.
Stéphane Chazelas

Diğer bir şey, sadece metin (bu konuda son bir paragraf ekledim).
goldilocks

4

Dan Bernstein'ın multilog için dosya tanımlayıcıları bir çıkışı sağlarken, belki de en bunun ya - görünüşte yapabilirsiniz ! İşlemci gibi senin kadar fark telafi etmek - 20 Milyon / 1G boyut özellikleri bazı finagling alabilir olsa göründüğü gibi 16M onun günlük başına dış sınır. Aşağıdaki, çoğunlukta, yukarıdaki bağlantıdan bir kopya + yapıştırma seçimidir, ancak bağlantı aynı zamanda satır başına zaman damgası, yalnızca en son satır eşleştirme desenini içeren [ve] başka bir dosya [lar] bulundurma ve daha fazlası gibi diğer seçenekleri de detaylandırır. .

Arayüz

 multilog script

... script herhangi bir sayıda argümandan oluşur. Her bağımsız değişken bir eylem belirtir. İşlemler, her girdi satırı için gerçekleştirilir.

Hatları seçme

Her satır başlangıçta seçilir. Eylem...

-pattern

... desen çizgiyle eşleşiyorsa çizginin seçimini kaldırır. Eylem...

+pattern

desen çizgiyle eşleşiyorsa çizgiyi seçer .

... desen bir dizi yıldızdır ve yıldız değildir. Tüm yıldızlar ve yıldız olmayanlar tarafından aynı sırada dizelerin birleştirilmesi ile eşleşir. Yıldız olmayan bir kişi kendini gösterir. Desenin sonundan önceki yıldız, desendeki bir sonraki karakteri içermeyen herhangi bir dizeyle eşleşir. Desenin sonundaki bir yıldız herhangi bir dizeyle eşleşir.

Otomatik döndürülmüş kütükler

Eğer dir veya bir nokta ile başlar daha sonra eylemi çizgi ...

 dir

... seçilen her satırı dir adlı bir günlüğe ekler . Eğer dir yoksa, multilogbunu oluşturur.

Günlük biçimi aşağıdaki gibidir:

  1. dir , işlemlerini izlemek için birkaç eski günlük dosyası, current adlı bir günlük dosyası ve diğer dosyaları içeren bir dizindir multilog.

  2. Her eski günlük dosyasının @ ile başlayan , dosyanın ne zaman bittiğini gösteren ve aşağıdaki kodlardan biriyle biten kesin bir zaman damgasıyla devam eden bir adı vardır :

    • .s : Bu dosya tamamen işlenir ve güvenli bir şekilde diske yazılır.
    • .u : Bu dosya bir kesinti anında oluşturuluyordu. Kesilmiş olabilir. İşlenmedi.

Eylem...

 ssize

... devam eden için maksimum dosya boyutunu ayarlar dir eylemleri. multilogkarar verecek akımı ise yeterince büyük olduğunu akımı vardır boyutu bayt. ( multilogayrıca, maksimum dosya boyutunun 2000 bayt içinde yeni bir satır görürse, akımın yeterince büyük olduğuna karar verir; günlük dosyalarını satır sınırlarında bitirmeye çalışır.) boyutu 4096 ve 16777215 arasında olmalıdır. Varsayılan maksimum dosya boyutu 99999'dur.

0.75 ve üzeri sürümlerde: Bir ALRM sinyali multilogalırsa , akım boş değilse hemen akımın yeterince büyük olduğuna karar verir .

(Not: zsh scheduleYerleşikliğin ALRMgerekirse belirli aralıklarla göndermeye kolayca ikna edilebileceğinden şüpheleniyorum .)

Eylem...

 nnum

... sonraki dir eylemleri için günlük dosyalarının sayısını ayarlar . Adlandırma sonra akımı ise, multiloggördüğü num veya daha fazla eski günlük dosyalarını, en küçük zaman damgası ile eski günlük dosyasını kaldırır. sayı en az 2 olmalıdır. Varsayılan günlük dosyası sayısı 10'dur.

Eylem...

 !processor

... daha sonraki dir eylemleri için bir işlemci ayarlar . akımı işlemci üzerinden multilogbesler ve çıkışı akım yerine eski bir günlük dosyası olarak kaydeder . işlemcinin tanımlayıcı 5'e yazdığı tüm çıktıları kaydeder ve sonraki günlük dosyasında işlemciyi çalıştırdığında bu çıktıyı tanımlayıcı 4'te okunabilir hale getirir. Güvenilirlik için, işlemci çıktısını oluşturmada herhangi bir sorun yaşıyorsa sıfırdan çıkmalıdır; sonra tekrar çalıştırır. Çalışan işlemcinin herhangi bir program besleme girişini engelleyebileceğini unutmayın .multilogmultilogmultilog


2

Şimdiye kadar kod büyük parçalar yazmayı içermeyen bir yaklaşım olarak bulabildiğim en iyi bu zshkod:

autoload zmv
mycmd |
  while head -c20M > mycmd.log && [ -s mycmd.log ]; do
    zmv -f '(mycmd.log)(|.(<->))(|.gz)(#qnOn)' '$1.$(($3+1))$4'
    {rm -f mycmd.log.1 mycmd.log.50.gz; (gzip&) > mycmd.log.1.gz} < mycmd.log.1
  done

Burada en fazla 51 20MiB büyük dosyaya bölme ve döndürme.


belki ... loopmounts? btrfsile de monte edilebilir compress-force=zlib.
mikeserv

2

İstediğiniz gibi bir şey yapmak için saldırıya uğramış bir python betiği:

#!/bin/sh
''':'
exec python "$0" "$@"
'''

KEEP = 10
MAX_SIZE = 1024 # bytes
LOG_BASE_NAME = 'log'

from sys import stdin
from subprocess import call

log_num = 0
log_size = 0
log_name = LOG_BASE_NAME + '.' + str(log_num)
log_fh = open(log_name, 'w', 1)

while True:
        line = stdin.readline()
        if len(line) == 0:
                log_fh.close()
                call(['gzip', '-f', log_name])
                break
        log_fh.write(line)
        log_size += len(line)
        if log_size >= MAX_SIZE:
                log_fh.close()
                call(['gzip', '-f', log_name])
                if log_num < KEEP:
                        log_num += 1
                else:
                        log_num = 0
                log_size = 0
                log_name = LOG_BASE_NAME + '.' + str(log_num)
                log_fh = open(log_name, 'w', 1)

1
Veya hashbang execkullanmak yerine ilk şey olarak python bir kabuk komut dosyası olarak sahip olmak için bir nedeni var mı? pythonenv python
peterph
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.