Esiste uno strumento per reindirizzare dinamicamente l'output su un nuovo file su richiesta


8

Attualmente sto reindirizzando l'output di uno strumento di monitoraggio su un file, tuttavia ciò che mi piacerebbe fare è reindirizzare questo output su un nuovo file su mia richiesta (utilizzando un keybinding), senza interrompere lo strumento.

Qualcosa di simile a

monitor_program | handle_stdout

Dove handle_stdoutmi permette di definire un nuovo file dove mettere il registro ad un certo punto.

So che potrei facilmente scriverlo, ma mi chiedo se ci sia qualche strumento che lo permetta già.


Probabilmente potresti eseguire logrotatemanualmente un file di configurazione personalizzato, a seconda del comportamento del tuo monitor_program, ma è un po 'hacker.
Ulrich Schwarz,

Sembra che la tua modifica sia in realtà una risposta alla domanda. In tal caso, pubblicalo come risposta (le risposte automatiche sono incoraggiate!) E rimuovi la risposta dalla tua domanda.
cat

Risposte:


9

Suggerirò una pipa denominata.

  1. Crea una pipe mkfifo p(chiamala come vuoi, se non 'p')

  2. Crea uno script "reader" che legge dalla pipe e scrive dove preferisci

  3. Indicare al programma di monitoraggio di scrivere i suoi registri nella pipa denominata

Ecco uno script lettore di esempio che legge da una pipe denominata 'p' e scrive i dati in un file 'mylog' indicizzato:

#!/bin/sh

INDEX=0

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

trap switchlog USR1

while :
do
  cat p >> mylog."$INDEX"
done

2
È inoltre possibile intercettare un segnale (USR1 ad esempio) nello script del lettore come segnale per cambiare registro.
Jeff Schaller

Questo inizia ad essere qualcosa di cui avrei bisogno ... Comunque lo script del lettore dovrebbe essere in grado di cambiare l'output in base a un mio kebinding. E potenzialmente chiedimi un nuovo nome file da usare (anche se questo è facoltativo, anche avere nomi di registro sequenziali andrebbe bene)
Treviño

Ho modificato lo script di esempio per mostrare un esempio di cambio log con kill -USR1. inserire un nuovo numero nel file 'newindex' per poterlo raccogliere.
Jeff Schaller

1
solo un'altra idea: se si tiene aperta una finestra per lo script "reader" in esecuzione, è possibile intercettare "INT" anziché USR1 e premere semplicemente Control-C in quella finestra per notificarlo con un nuovo nome file di registro.
Jeff Schaller

1
Perché reade printfinvece di solo cat <p >> mylog."$INDEX"?
Wildcard

7

Sviluppando la tua idea SIGINT, qui usando SIGQUIT ( Ctrl+\) puoi ancora usare Ctrl+Cper fermare il tutto:

(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)

Ciò presuppone che catnon sia incorporato nella shell (quindi viene interrotto dalla stampa Ctrl+\).

Nota che, come nel tuo approccio, esiste la possibilità che SIGQUIT venga consegnato nel momento sbagliato (nella chiamata di sistema di scrittura) causando la perdita di alcuni dati.


1

Probabilmente potresti usare lesse salvare da lì digitando squindi il nome del file che desideri salvare, quindi Enter. Da Come scrivo tutte le righe da meno a un file? .


Sfortunatamente non è possibile utilizzare più file di registro, una volta impostato uno non è possibile ridefinirne uno nuovo. Inoltre, non è possibile cancellare il registro una volta fatto. Quindi ... Buon punto di partenza (grazie), ma non ancora abbastanza.
Treviño,

0

Senza sapere di più sulla tua "richiesta" non è davvero possibile rispondere. Se fosse basato sulla dimensione o sull'intervallo del file, allora rotatelogs (che dovrebbe essere fornito in bundle con Apache httpd) funzionerebbe.


Siamo spiacenti, non l'ho detto esplicitamente, presumo che un keybinding consentirebbe di modificare il nome del registro.
Treviño,

0

Grazie alla risposta di Jeff Schaller , ho finito con qualcosa del genere, che sostanzialmente fa quello che mi serve, chiamiamolo 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

Quindi si tratta solo di creare una pipe con nome mkfifo pe di usare due terminali dove monitor_program > pe reader.shsono in esecuzione. Posso quindi interrompere il lettore per impostare un nuovo registro utilizzando Ctrl+ Ce inserire un nuovo nome. Ctrl+ Z, come al solito, quindi fermarsi e ucciderlo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.