Pregunta

Siguiendo Documentación de Python, Estoy tratando de anular logging.Formatter.converter Para controlar el tiempo registrado.
Como puede ver abajo - Los milisegundos no fueron anulados (Son los milisegundos de tiempo actual).

¿Cómo? ¿Cómo puedo controlar los milisegundos también?

>>> import logging, datetime
>>> formatter = logging.Formatter('%(asctime)s:%(message)s')
>>> handler = logging.StreamHandler()
>>> handler.setFormatter(formatter)
>>> def sim_time(t):
...     return datetime.datetime(2000,1,2,3,4,5,678).timetuple()
...
>>> formatter.converter = sim_time
>>> log = logging.getLogger('test')
>>> log.addHandler(handler)
>>> log.info('hi')
2000-01-02 03:04:05,898:hi
>>> log.info('hi')
2000-01-02 03:04:05,914:hi
>>> log.info('hi')
2000-01-02 03:04:05,434:hi
¿Fue útil?

Solución

anular logging.Formatter.formatTime() en su lugar con esto:

def sim_time(record, datefmt=None):
    return datetime.datetime(2000,1,2,3,4,5,678).strftime('%Y-%m-%d %H:%M:%S,%f')[:-3]

formatter.formatTime = sim_time

Si lo necesita para todos los registradores en este proceso, puede anular la función de clase en sí, pero hacerlo justo después de la primera import logging Declaración de su código Encuentra:

def sim_time(self, record, datefmt=None):
    return datetime.datetime(2000,1,2,3,4,5,678).strftime('%Y-%m-%d %H:%M:%S,%f')[:-3]

import logging
logging.Formatter.formatTime = sim_time

Otros consejos

timetuple() no utiliza milisegundos, de modo que la información de MS contenida en el objeto DateTime se pierde una vez que se llama el método:

>>> d
datetime.datetime(2000, 1, 2, 3, 4, 5, 678)
>>> d.timetuple()
time.struct_time(tm_year=2000, tm_mon=1, tm_mday=2, tm_hour=3, tm_min=4, tm_sec=5, tm_wday=6, tm_yday=2, tm_isdst=-1)

Tenga en cuenta que esto no es una limitación de este método en particular, sino más bien del time.struct_time escribe.

La conclusión es: si necesita anular la marca de tiempo, no pase por un time.struct_time objeto. Podría, por ejemplo, pasar la marca de tiempo ya formateada como una cadena, en lugar de un momento falso. Dependiendo de sus necesidades, ¡puede haber mejores métodos, por supuesto!

Aquí hay un mejor ejemplo que le permite reemplazar el tiempo que se generó, ya que la respuesta aceptada realmente no hizo eso.

def inSimulatedTime(self,secs=None):
    global myTimeKeeper
    try:
       ts=myTimeKeeper.getCurrentTimeLocal() # returns a datetime.datetime object
       return ts.timetuple()
except Exception as e:
    #sometimes my timekeeper hasn't been initialized yet.
    return time.localtime(secs)

Para habilitarlo:

logging.Formatter.converter=inSimulatedTime
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top