Daemon Çıktısını Upstart ile Günlüğe Kaydetmek


34

Ubuntu sunucumda başlangıç ​​tarafından yönetilen özel bir arka planım var. Daemon'un çıktısını yakalamam (kaydetmem) dışında mükemmel çalışıyor. Resmi kıta sayfa kullandığım söylüyor console loggedbunu, ama hangi dosya o kadar log geliyor?

Ben de okumuştum console loggedolduğunu artık geçerli bir dörtlük . Şu anda 0.3.9 (Hardy) kullanıyorum ancak birkaç ay içinde 0.6.x (Lucid) sürümüne yükseltirim. Eğer console loggedgerçekte sonraki sürümlerinde işe yaramaz, bunun yerine neyi kullanırım?


1
Çıktının syslog'a veya arka planın yapılandırma dosyasında belirtilen bir günlük dosyasına göndermek için özel arka planınızı güncelleyebilir misiniz?
Zoredache

Yanıtlar:


35

Bu kod parçacığı, hizmetinizin çıktısını günlükleyiciye yönlendirirken, hizmet işleminin yürütülmesine izin verir (böylece kabuk işleminin değiştirilmesi), böylece başlama başlangıcı karışmaz. Ayrıca, logger işleminin init olarak yeniden yapılandırılmasını da sağlar, bu nedenle hizmetiniz çocuğunuz değildir ve geçici olarak bir beşlik yaratması gerekse de, dosya sisteminde oturup durmaktan kaçınır.

script
  mkfifo /tmp/myservice-log-fifo
  ( logger -t myservice </tmp/myservice-log-fifo & )
  exec >/tmp/myservice-log-fifo
  rm /tmp/myservice-log-fifo
  exec myservice 2>/dev/null
end script

İşte nasıl çalışıyor:

  1. mkfifo /tmp/myservice-log-fifosadece fifo özel dosyasını (aka isimli boru) yapar. Tip man 7 fifodaha fazla bilgi için.
  2. ( logger ... </tmp/myservice-log-fifo & ) Kaydediciyi arka planda, fifodan okumaya başlar. Parens, logger işleminin mevcut kabuk işleminin bir çocuğu olarak kalmak yerine, initelenmesine neden olur.
  3. exec >/tmp/myservice-log-fifomevcut kabuğun stdout'unu fifo'ya yönlendirir. Şimdi bu beşlik için açık bir dosya tanımlayıcımız var ve artık dosya sistemi girdisine ihtiyacımız yok ...
  4. rm /tmp/myservice-log-fifo bu yüzden onu kaldıracağız.
  5. exec myservice 2>/dev/nullhizmeti her zamanki gibi yapar. Stdout zaten beşe gidiyor ve yeni program çalıştırıldığında bu değişmeyecek.

GÜNCELLEME: set -e Upstart varsayılan olarak bu seçeneğe sahip komut dosyalarını çalıştırdığı için gerekli değildir (bkz. Http://upstart.ubuntu.com/cookbook/#develop-scripts-using-bin-sh )


Harika bir cevap ve etrafta hiçbir yerde yalan olmayan iki dosya bırakmıyor.
Ash Berlin-Taylor

Nedir set -e?
Peter,

1
set -eHerhangi bir komut başarısız olursa hemen çıkmak için komut dosyası neden olur. Bu satır olmadan, komut dosyası işe yaramaz bir şekilde (ve muhtemelen tehlikeli bir şekilde) sonraki komutları çalıştırmaya devam eder.
Keith Rarick

1
Stderr yanı sıra stdout'u günlüğe kaydetmek için, çizginin exec 2>&1üstüne bir satır ekleyin ve son satırdan rmkaldırın 2>/dev/null.
itsadok


11

console output Stanza kullanıyorsanız ve betiğinizin çıktısını logger(syslog (3) sistem günlüğü modülüne kabuk komut arayüzü) yönlendiriyorsanız, o zaman işe yarayacaktır.

Örneğin

console output
exec /my/script | logger

giriş yapacak /var/log/messages

Örneğin

console output
exec /my/script | logger -t my-script

/var/log/messagesHer iletiye oturum açacak ve etiketlenecekmy-script

logger --help logger kullanım seçenekleri için.

(Centos 5.x tabanlı olan Amazon Linux AMI'deyim; YMMV)


4
Görünüşe göre bu iyi bir çözüm değil. upstart logger, gerçekte yönetmesini istediğiniz işlemin değil, PID'ine kilitlenir .
Peter,

10

mkfifoHile tatmin edici çalışmak için alamadım ; stderr'i yakalamak gibi görünmüyordu ve yönlendirme denemeleri Upstart'ın hatasız bir şekilde kurtarılmasına neden oldu.

Aynı zamanda loggersürecin bir çocuk olarak takılmasının talihsiz bir yan etkisi vardır init, bu nedenle kaydedicinin "kime sahip olduğu" hakkındaki bilgiler kaybedilir ve kudretten haberi olmayan biri mkfifobunun öldürülebilecek sarkan bir süreç olduğunu varsayabilir.

Bunun yerine, tüm bu sorunları çözen aşağıdaki çözüme ulaştım. Bu neden logger kök süreç olarak hizmet korurken, bir çocuk süreç haline. Ne yazık ki, yürütülmesi gerekiyor bash, ama sadece kirli görünüyor .

script
  # ... setup commands here, e.g. environment, cd, ...
  exec bash <<EOT
    exec 1> >(logger -t myservice) 2>&1
    exec myservice
EOT
end script

Bu stdout ve stderr komutlarını bir komuta yönlendiren bir numara kullanır. Hizmeti bashkomutun içinde yürüttüğümüz için , kabuğun değiştirilmesi ve sihirli bir şekilde bash'ın aşağıdaki gibi gösterildiği gibi hizmetin bir alt süreci haline gelmesinin yan etkisi vardır ps aufxw:

myservice 
 \_ bash -c exec 1> >(logger -t myservice) 2>&1 && exec myservice
    \_ logger -t myservice

Nedense Yukarıdaki komut bir sarılmış olması gerekir bash -c. Bunun, Upstart'ın sadece betiğinizi Bash üzerinden çalıştırıyormuş gibi davrandığı içindir, ancak aslında değildir. Herhangi biri ekstra bash kabuğundan kaçınmanın bir yolunu önerebilirse, bu harika olurdu.


1
Evet! Bunu bulduğuma sevindim. Mkfifo varyantından daha iyi görünüyor ve benim durumumda exec bash -l << EOForada hiçbir kayıp olmam gerekiyordu .
thom_nic

6

Bu çirkin ama şimdiye kadar bulduğum en iyisi

exec / path / to / server >> /tmp/upstart.log 2> & 1


2
Çözüm, günlük döndürme konusunda iyi değil çünkü uygulama doğrudan dosyaya giriyor. Sistem günlüğü üzerinden giriş yapmak, ilgili sorunları önler.
Mark Stosberg,

3

Çıktıyı syslog'a da yönlendirebilirsiniz, örn.

exec $SERVER 2>&1 | logger -t myservice -p local0.info

Bununla birlikte, boru hattı, start-up işleminin PID ile günlük sürecinin PID'ini karıştırmasına neden olabilir.


PID'yi karıştıran arka plan programı aslında işe yaramaz bir arka plandır, çünkü süreci izlemesi gerekiyordu, sonra yeniden doğdu. Doğru PID'in izlendiğinden nasıl emin olacağınıza dair bir fikriniz var mı?
Johann Philipp Strathausen,

Sanırım (ama henüz denemedim) expect forkveya expect daemonstanza isteyeceksiniz . Ya catda günlük dosyasını pid dosyasına yazabilirsin, sanırım.
Peter,

1

Başka bir alternatif tee benzeri kullanıyor:

exec $SERVER 2>&1 | tee /dev/stderr | logger -t myservice

hem starttart hem de syslog çıktısını almak için

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.