Domanda

Seguente Documentazione di Python, Sto cercando di sovrascrivere logging.Formatter.converter Per controllare il tempo registrato.
Come puoi vedere di seguito - I millisecondi non sono stati sostituiti (Sono gli attuali millisecondi).

Come mai? Come posso controllare anche i millisecondi?

>>> 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
È stato utile?

Soluzione

oltrepassare logging.Formatter.formatTime() Invece con questo:

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

Se ne hai bisogno per tutti i logger in questo processo, puoi sovrascrivere la funzione di classe stessa, ma farlo subito dopo il primo import logging Dichiarazione del tuo codice incontra:

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

Altri suggerimenti

timetuple() non utilizza millisecondi, quindi le informazioni MS contenute nell'oggetto DateTime vengono perse una volta chiamato il metodo:

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

Si noti che questa non è una limitazione di questo particolare metodo, ma piuttosto del time.struct_time genere.

La linea di fondo è: se è necessario sovrascrivere il timestamp, non passare attraverso un time.struct_time oggetto. Potresti - ad esempio, passare il timestamp già formattato come stringa, piuttosto che un tempo falso. A seconda delle tue esigenze potrebbero esserci metodi migliori, ovviamente!

Ecco un esempio migliore che ti consente di sostituire il tempo generato, poiché la risposta accettata non lo ha fatto davvero.

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)

Per abilitarlo:

logging.Formatter.converter=inSimulatedTime
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top