Apakah ada alat untuk mengarahkan output secara dinamis ke file baru berdasarkan permintaan

8

Saat ini saya mengarahkan output alat pemantauan ke file, namun apa yang ingin saya lakukan adalah mengarahkan output ini ke file baru berdasarkan permintaan saya (menggunakan keybinding), tanpa menghentikan alat tersebut.

Sesuatu seperti

monitor_program | handle_stdout

Di mana handle_stdoutmemungkinkan saya untuk menentukan file baru tempat meletakkan log pada titik tertentu.

Saya tahu saya bisa dengan mudah menulisnya, tetapi saya bertanya-tanya apakah ada alat yang sudah memungkinkan ini.

Treviño
sumber
Anda mungkin dapat menjalankan logrotatedengan file konfigurasi kustom secara manual, tergantung pada perilaku monitor_program Anda, tetapi itu agak meretas.
Ulrich Schwarz
Sepertinya hasil edit Anda sebenarnya adalah jawaban untuk pertanyaan itu. Dalam hal ini, silakan posting sebagai jawaban (jawaban mandiri dianjurkan!) Dan hapus jawaban dari pertanyaan Anda.
kucing

Jawaban:

9

Saya akan menyarankan pipa bernama.

  1. Buat pipa mkfifo p(sebut saja apa pun yang Anda inginkan, jika tidak 'p')

  2. Buat skrip "pembaca" yang membaca dari pipa dan menulis di mana pun Anda suka

  3. Beri tahu program pemantauan untuk menulis log-nya ke pipa bernama

Berikut ini skrip pembaca sampel yang membaca dari pipa bernama 'p' dan menulis data ke file 'mylog' yang diindeks:

#!/bin/sh

INDEX=0

switchlog() {
  read INDEX < newindex
  echo now writing to "mylog.$INDEX"
}

trap switchlog USR1

while :
do
  cat p >> mylog."$INDEX"
done
Jeff Schaller
sumber
2
Anda juga bisa menjebak sinyal (misalnya USR1) di skrip pembaca sebagai sinyal untuk beralih log.
Jeff Schaller
Ini mulai menjadi sesuatu yang saya butuhkan ... Namun skrip pembaca harus dapat mengubah output berdasarkan kebinding saya. Dan berpotensi meminta saya untuk menggunakan nama file baru (meskipun ini opsional, bahkan memiliki nama log berurutan akan baik-baik saja)
Treviño
Saya mengedit skrip sampel untuk menunjukkan contoh pengalihan log dengan kill -USR1. gema nomor baru ke dalam file 'newindex' untuk diambil.
Jeff Schaller
1
hanya ide lain - jika Anda tetap membuka jendela untuk skrip "pembaca" yang sedang berjalan, Anda bisa menjebak 'INT' alih-alih USR1 dan cukup tekan Control-C di jendela itu untuk memberi tahu nama file log yang baru.
Jeff Schaller
1
Mengapa readdan printfbukannya adil cat <p >> mylog."$INDEX"?
Wildcard
7

Membangun ide SIGINT Anda, di sini menggunakan SIGQUIT ( Ctrl+\) yang dapat Anda gunakan Ctrl+Cuntuk menghentikan semuanya:

(trap '' QUIT; monitor_command) | (
   trap : QUIT
   ulimit -c 0 # prevent core dump so SIGQUIT behaves like SIGINT
               # for cat
   n=0; while n=$((n+1)); file=output.$n.log; do
     printf 'Outputting to "%s"\n' "$file"
     cat > "$file"
   done)

Itu mengasumsikan catbukan builtin di shell Anda (jadi itu bisa terganggu oleh Anda menekan Ctrl+\).

Perhatikan bahwa seperti dalam pendekatan Anda, ada kemungkinan bahwa SIGQUIT dikirimkan pada waktu yang salah (dalam panggilan sistem tulis) menyebabkan beberapa data hilang.

Stéphane Chazelas
sumber
1

Anda mungkin bisa menggunakan lessdan menyimpan dari sana dengan mengetikkan snama file yang ingin Anda simpan, lalu Enter. Dari Bagaimana cara saya menulis semua baris dari kurang ke file? .

BenjaminH
sumber
Sayangnya tidak mungkin bagi pengguna untuk lebih banyak file log, setelah Anda mengatur yang Anda tidak dapat mendefinisikan kembali yang baru. Anda juga tidak dapat menghapus log setelah selesai. Jadi ... Titik awal yang bagus (terima kasih), tetapi belum cukup.
Treviño
0

Tanpa mengetahui lebih lanjut tentang "permintaan" Anda, tidak mungkin untuk menjawab. Jika didasarkan pada ukuran atau interval file, maka rotatelogs (yang seharusnya dibundel dengan Apache httpd) akan berfungsi.

symcbean
sumber
Maaf, saya tidak mengatakan itu secara eksplisit, saya mengasumsikan pengikat kunci yang memungkinkan untuk mengubah nama log.
Treviño
0

Berkat jawaban Jeff Schaller , saya berakhir dengan sesuatu seperti ini, yang pada dasarnya melakukan apa yang saya butuhkan, sebut saja reader.sh:

#!/bin/sh

INDEX=0
LOGNAME="$INDEX.log"

switchlog() {
  local custom_name
  read -p "Add log name: " custom_name
  INDEX=$((INDEX+1))
  LOGNAME="$(printf "%03d" $INDEX).$custom_name.log"
  echo now writing to $LOGNAME
}

trap switchlog INT
switchlog

while :
do
  read foo < p
  printf "%s\n" "$foo" >> "$LOGNAME"
done

Maka itu hanya tentang membuat pipa bernama mkfifo p, dan menggunakan dua terminal di mana monitor_program > pdan reader.shsedang berjalan. Saya kemudian dapat menghentikan pembaca untuk mengatur log baru dengan menggunakan Ctrl+ C, dan memasukkan nama baru. Ctrl+ Z, seperti biasa lalu berhenti dan bunuh.

Treviño
sumber