5

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?

9
  • 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. Commented Nov 6, 2017 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 Commented Nov 6, 2017 at 22:06
  • You can do that formatting yourself. Commented Nov 6, 2017 at 22:06
  • How can I do that? Commented Nov 6, 2017 at 22:08
  • With time.stftime, like what logging itself uses. Commented Nov 6, 2017 at 22:10

2 Answers 2

7

@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
    (and msecs) 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
            record.msecs = (record.timestamp % 1) * 1000
        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})
Sign up to request clarification or add additional context in comments.

Comments

3

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.

4 Comments

I tried what you said but it doesn't work: TypeError: _log() got an unexpected keyword argument 'date'
my bad @riccio777, updated the code (forgot it's the extra arg).
Thank you, just one little thing: date in the dictionary should be with the quotes.
I will test my code before I post next time :| glad I could help

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.