diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py index ce341891aa0..6ae2cd07185 100755 --- a/test/functional/test_framework/test_framework.py +++ b/test/functional/test_framework/test_framework.py @@ -7,6 +7,7 @@ import configparser from enum import Enum import argparse +from datetime import datetime, timezone import logging import os import platform @@ -837,9 +838,16 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass): # User can provide log level as a number or string (eg DEBUG). loglevel was caught as a string, so try to convert it to an int ll = int(self.options.loglevel) if self.options.loglevel.isdigit() else self.options.loglevel.upper() ch.setLevel(ll) + # Format logs the same as bitcoind's debug.log with microprecision (so log files can be concatenated and sorted) - formatter = logging.Formatter(fmt='%(asctime)s.%(msecs)03d000Z %(name)s (%(levelname)s): %(message)s', datefmt='%Y-%m-%dT%H:%M:%S') - formatter.converter = time.gmtime + class MicrosecondFormatter(logging.Formatter): + def formatTime(self, record, _=None): + dt = datetime.fromtimestamp(record.created, timezone.utc) + return dt.strftime('%Y-%m-%dT%H:%M:%S.%f') + + formatter = MicrosecondFormatter( + fmt='%(asctime)sZ %(name)s (%(levelname)s): %(message)s', + ) fh.setFormatter(formatter) ch.setFormatter(formatter) # add the handlers to the logger