¿Cómo gestionar el archivo nohup.out en tornado?

Construí un servicio web utilizando tornado y sirve días y noches. Utilicé el comando para iniciar mi servicio:

nohup python my_service.py & 

El registro de servicio puede escribir en nohup.out . Sin embargo, el archivo se hace más grande con el tiempo. Quiero saber cómo puedo manejarlo más convenientemente. ¿Por decir, usando un método automático para generar los archivos de registro con nombres y tamaño apropiados? Como:

 service_log_1.txt service_log_2.txt service_log_3.txt ... 

Gracias.

Sí hay. Poner en marcha un trabajo cron, que trunca el archivo (por algo como "cat /dev/null > nohup.out" ). La frecuencia con la que tendrá que ejecutar este trabajo dependerá de la cantidad de salida que genere su proceso.

Pero si no necesita la salida del trabajo por completo (tal vez sea basura, de todos modos, solo puede responder eso) podría evitar escribir en el archivo nohup.out en primer lugar. Ahora mismo empiezas el proceso de esta manera:

 nohup command & 

reemplazar esto por

 nohup command 2>/dev/null 1>/dev/null & 

y el archivo nohup.out ni siquiera se creará.

La razón por la que la salida del proceso se dirige a un archivo es:

Normalmente, todos los procesos (es decir, los comandos que ingresa desde la línea de comandos, hay excepciones, pero no importan aquí) se adjuntan a un terminal. Por defecto (así es como Unix está manejando esto) esto es algo que puede mostrar texto y se conecta al host a través de una línea serie. Si ingresa un comando y apaga el terminal que ingresó, el proceso se termina también porque perdió su terminal. Debido a que en la comunicación en serie, los técnicos tradicionalmente empleaban las palabras de la comunicación telefónica (de donde provenía) la terminación de una comunicación no se llamaba “interrupción” o “terminación” sino una “suspensión”. Así que los progtwigs terminaron en “hangups” y el progtwig para evitar esto fue “nohup”, el progtwig “no-termination-upon-hangup”.

Pero como puede ser que un proceso huérfano no tenga terminal para escribir, nohup usa el archivo nohup.out como un “reemplazo de pantalla”, redirigiendo la salida allí, que normalmente iría a la pantalla. Si un comando no tiene salida alguna, no se creará nohp.out.

Sencillo:

 nohup python my_service.py >service_log_1.txt 2>&1 & 

Si la salida está siendo producida por alguna biblioteca que está usando y no tiene control sobre ella, puede redirigir la salida estándar a un archivo cuando se inicie el progtwig. Luego, puede cerrar y volver a abrir el archivo periódicamente para evitar que los archivos crezcan para siempre. Puede usar una marca de tiempo para el nombre del archivo, por lo que siempre es diferente. Algo como:

 import sys import datetime current_stdout = None def reset_stdout(): global current_stdout if current_stdout: current_stdout.close() sys.stdout = open( "{}.log".format( datetime.datetime.now().strftime('%Y%m%d%H%M%S') ), "w") current_stdout = sys.stdout reset_stdout() # Then call this every day.. week .. reset_stdout() 

Si prefiere restablecer el archivo dependiendo del tamaño del mismo, puede monitorear periódicamente su tamaño con algo como esto:

 if current_stdout.tell() > 1000000: reset_stdout() 

Pero si tiene control sobre la salida que está enviando, le recomiendo que utilice la biblioteca de registro . Tiene mucha flexibilidad en lo que puedes hacer con la salida. Los mensajes enviados al registro pueden ser procesados ​​por objetos llamados manejadores . Uno de los controladores incluidos en la biblioteca hace lo que quiere, se llama RotatingFileHandler . De la documentación:

 class logging.handlers.RotatingFileHandler(filename, mode='a', maxBytes=0, backupCount=0, encoding=None, delay=0) 

“Puede usar los valores maxBytes y backupCount para permitir que el archivo se transfiera a un tamaño predeterminado. Cuando el tamaño está a punto de superarse, el archivo se cierra y se abre un nuevo archivo para su salida. El rollover se produce cada vez que el archivo de registro actual tiene una longitud de casi MaxBytes; si maxBytes es cero, la reinversión nunca ocurre “.

Así que puedes hacer todo el registro usando algo como esto:

 import logging import logging.handlers # Create a logger log = logging.getLogger('example') # Set the level of the logger. By doing this all the messages with a "level" of INFO or higher will be # sent to the log log.setLevel(logging.INFO) # Create the handler and set 20 files to rotate and a maximum size of 1MB handler = logging.handlers.RotatingFileHandler('log',maxBytes = 1000000,backupCount=20) # Now attach the handler to the logger object log.addHandler(handler) # Now you can send your output like: log.info('text text text text text text text text text') log.info(.... 

La respuesta de @jujaro es bastante útil y probé el módulo de logging en mi servicio web. Sin embargo, todavía hay algunas restricciones para usar el registro en Tornado . Ver la otra pregunta formulada.

Como resultado, probé crontab en linux para crear un trabajo cron a la medianoche (use crontab -e en linux shell):

 59 23 * * * source /home/zfz/cleanlog.sh 

Este trabajo cron inicia mi script cleanlog.sh a las 23:59 todos los días.

Los contenidos de clean.sh :

 fn=$(date +%F_service_log.out) cat /home/zfz/nohup.out >> "/home/zfz/log/$fn" echo '' > /home/zfz/nohup.out 

Esta secuencia de comandos crea un archivo de registro con la fecha del día y echo '' borra el nohup.out en caso de que crezca. Aquí están mis archivos de registro divididos de nohup.out por ahora:

 -rw-r--r-- 1 zfz zfz 54474342 May 22 23:59 2013-05-22_service_log.out -rw-r--r-- 1 zfz zfz 23481121 May 23 23:59 2013-05-23_service_log.out