3

I am using the logging module in the following way:

logging.basicConfig(level=logging.DEBUG,
                    format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
                    filename=my_filename,
                    filemode='w')

and

logging.info("Set up logger")

for writing. The output is:

2017-11-05 19:10:22,762 root      INFO     Set up logger

QUESTION: instead of the current timestamp, I would like to have a past (or future, whatever) timestamp. So whenever I want to write something in the log, I can pass the date as argument with something like:

logging.info(msg="Set up logger", date='2010-01-01 19:10:22,762')

in order to have

2010-01-01 19:10:22,762 root      INFO    Set up logger

Any help?

riccio777
  • 167
  • 4
  • 19
  • 2
    So you want the timestamp to be not the actual timestamp? What's the point of that? If you just want to put arbitrary things in the message you can *already do that*, it's not clear what the problem is. – jonrsharpe Nov 06 '17 at 22:03
  • If I put it in the message, I won't have a standard format like %(time)s %(name)s %(levelname)s %(message)s – riccio777 Nov 06 '17 at 22:06
  • You can do that formatting yourself. – user2357112 Nov 06 '17 at 22:06
  • How can I do that? – riccio777 Nov 06 '17 at 22:08
  • With [`time.stftime`](https://docs.python.org/3/library/time.html#time.strftime), like what `logging` itself uses. – user2357112 Nov 06 '17 at 22:10
  • It depends exactly what you want. You can do something completely different with e.g. https://stackoverflow.com/a/13131690/3001761 if you want to. Read the docs, research your options. – jonrsharpe Nov 06 '17 at 22:11
  • (You'll have to do the millisecond handling yourself, though; `time.strftime` doesn't handle that part.) – user2357112 Nov 06 '17 at 22:11
  • I dont think `time.strftime` is what he wants since this is the same that `logging`does. I think `datetime.datetime.strftime` is what he wants with some defined timestamp. I may be wrong tho. – Jose A. García Nov 06 '17 at 22:16
  • Thanks @user2357112 , can you show me a couple of code lines implementing the feature please? – riccio777 Nov 07 '17 at 19:10

2 Answers2

5

@m1keil's answer will work for simple cases, but gets cumbersome if you want, for example, to have multiple handlers which format the time in different ways, or if you don't need/want to specify the time every time you make a logging call, etc. Here is a solution which is slightly more complicated, but is the "more correct way", and integrates better with the logging system's normal timestamp handling:

First, you need to create a log filter (filters have the ability to modify log records that pass through loggers they're attached to):

class TimestampFilter (logging.Filter):
    """
    This is a logging filter which will check for a `timestamp` attribute on a
    given LogRecord, and if present it will override the LogRecord creation time
    to be that of the timestamp (specified as a time.time()-style value).
    This allows one to override the date/time output for log entries by specifying
    `timestamp` in the `extra` option to the logging call.
    """

    def filter(self, record):
        if hasattr(record, 'timestamp'):
            record.created = record.timestamp
        return True

Then, simply create an instance of the filter and add it to an appropriate logger instance:

logger = logging.getLogger(__name__)
filter = TimestampFilter()
logger.addFilter(filter)

Then when you want to override the date/time of a log entry, when making the logging call, supply a timestamp in extra:

my_timestamp = time.time() + 86400  # Let's pretend it's tomorrow already
logger.warn("I am a warning from the future!", extra={'timestamp': my_timestamp})
Foogod
  • 310
  • 2
  • 6
2

You can do that simply by:

logging.basicConfig(level=logging.DEBUG,
                    format='%(date)s %(name)-12s %(levelname)-8s %(message)s',
                    filename=my_filename,
                    filemode='w')

and logging with:

logging.info(msg="Set up logger", extra={'date':'2010-01-01 19:10:22,762'})

Do note that since you hardcoded the date argument in the format, a log message without one will fail. If you want to make it optional, you'll need to use something like filters to modify your log message on the fly.

m1keil
  • 4,515
  • 22
  • 26