Par défaut, logging.Formatter('%(asctime)s')
imprime le format suivant:
2011-06-09 10:54:40,638
où 638 est la milliseconde. J'ai besoin de changer la virgule en un point:
2011-06-09 10:54:40.638
Pour formater le temps que je peux utiliser:
logging.Formatter(fmt='%(asctime)s',datestr=date_format_str)
cependant, documentation ne spécifie pas comment formater les millisecondes. J'ai trouvé this SO question qui parle de microsecondes, mais a) je préférerais des millisecondes et b) ce qui suit ne fonctionne pas sur Python 2.6 (sur lequel je travaille) en raison de la %f
:
logging.Formatter(fmt='%(asctime)s',datefmt='%Y-%m-%d,%H:%M:%S.%f')
Veuillez noter que la solution de Craig McDaniel est clairement meilleur.
la méthode formatTime
de logging.Formatter ressemble à ceci:
def formatTime(self, record, datefmt=None):
ct = self.converter(record.created)
if datefmt:
s = time.strftime(datefmt, ct)
else:
t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
s = "%s,%03d" % (t, record.msecs)
return s
Notez la virgule dans "%s,%03d"
. Ceci ne peut pas être corrigé en spécifiant un datefmt
car ct
est un time.struct_time
et ces objets n'enregistrent pas les millisecondes.
Si nous changeons la définition de ct
pour en faire un objet datetime
à la place de struct_time
, alors (du moins avec les versions modernes de Python), on peut appeler ct.strftime
et ensuite nous pouvons utiliser %f
pour formater des microsecondes:
import logging
import datetime as dt
class MyFormatter(logging.Formatter):
converter=dt.datetime.fromtimestamp
def formatTime(self, record, datefmt=None):
ct = self.converter(record.created)
if datefmt:
s = ct.strftime(datefmt)
else:
t = ct.strftime("%Y-%m-%d %H:%M:%S")
s = "%s,%03d" % (t, record.msecs)
return s
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
console = logging.StreamHandler()
logger.addHandler(console)
formatter = MyFormatter(fmt='%(asctime)s %(message)s',datefmt='%Y-%m-%d,%H:%M:%S.%f')
console.setFormatter(formatter)
logger.debug('Jackdaws love my big sphinx of quartz.')
# 2011-06-09,07:12:36.553554 Jackdaws love my big sphinx of quartz.
Ou, pour obtenir des millisecondes, modifiez la virgule en point décimal et omettez l'argument datefmt
:
class MyFormatter(logging.Formatter):
converter=dt.datetime.fromtimestamp
def formatTime(self, record, datefmt=None):
ct = self.converter(record.created)
if datefmt:
s = ct.strftime(datefmt)
else:
t = ct.strftime("%Y-%m-%d %H:%M:%S")
s = "%s.%03d" % (t, record.msecs)
return s
...
formatter = MyFormatter(fmt='%(asctime)s %(message)s')
...
logger.debug('Jackdaws love my big sphinx of quartz.')
# 2011-06-09 08:14:38.343 Jackdaws love my big sphinx of quartz.
Cela devrait fonctionner aussi:
logging.Formatter(fmt='%(asctime)s.%(msecs)03d',datefmt='%Y-%m-%d,%H:%M:%S')
L'ajout de msecs était la meilleure option, merci. Voici mon amendement utilisant ceci avec Python 3.5.3 dans Blender
import logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s.%(msecs)03d %(levelname)s:\t%(message)s', datefmt='%Y-%m-%d %H:%M:%S')
log = logging.getLogger(__name__)
log.info("Logging Info")
log.debug("Logging Debug")
Le moyen le plus simple que j'ai trouvé était de remplacer default_msec_format:
formatter = logging.Formatter('%(asctime)s')
formatter.default_msec_format = '%s.%03d'
Après avoir instancié un Formatter
, je règle généralement formatter.converter = gmtime
. Donc, pour que la réponse de @ unutbu fonctionne dans ce cas, vous aurez besoin de:
class MyFormatter(logging.Formatter):
def formatTime(self, record, datefmt=None):
ct = self.converter(record.created)
if datefmt:
s = time.strftime(datefmt, ct)
else:
t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
s = "%s.%03d" % (t, record.msecs)
return s
Une simple extension qui ne nécessite pas le module datetime
et qui n’est pas handicapée comme d’autres solutions consiste à utiliser un simple remplacement de chaîne, comme ceci:
import logging
import time
class MyFormatter(logging.Formatter):
def formatTime(self, record, datefmt=None):
ct = self.converter(record.created)
if datefmt:
if "%F" in datefmt:
msec = "%03d" % record.msecs
datefmt = datefmt.replace("%F", msec)
s = time.strftime(datefmt, ct)
else:
t = time.strftime("%Y-%m-%d %H:%M:%S", ct)
s = "%s,%03d" % (t, record.msecs)
return s
De cette façon, un format de date peut être écrit comme vous le souhaitez, même en tenant compte des différences de région, en utilisant %F
pendant des millisecondes. Par exemple:
log = logging.getLogger(__name__)
log.setLevel(logging.INFO)
sh = logging.StreamHandler()
log.addHandler(sh)
fm = MyFormatter(fmt='%(asctime)s-%(levelname)s-%(message)s',datefmt='%H:%M:%S.%F')
sh.setFormatter(fm)
log.info("Foo, Bar, Baz")
# 03:26:33.757-INFO-Foo, Bar, Baz
Si vous utilisez flèche ou si l'utilisation de la flèche ne vous dérange pas. Vous pouvez substituer la mise en forme de l'heure par python par celle de arrow.
import logging
from arrow.arrow import Arrow
class ArrowTimeFormatter(logging.Formatter):
def formatTime(self, record, datefmt=None):
arrow_time = Arrow.fromtimestamp(record.created)
if datefmt:
arrow_time = arrow_time.format(datefmt)
return str(arrow_time)
logger = logging.getLogger(__name__)
default_handler = logging.StreamHandler()
default_handler.setFormatter(ArrowTimeFormatter(
fmt='%(asctime)s',
datefmt='YYYY-MM-DD HH:mm:ss.SSS'
))
logger.setLevel(logging.DEBUG)
logger.addHandler(default_handler)
Vous pouvez maintenant utiliser tous les formatage de la flèche dans l'attribut datefmt
.