I would like to change the timestamp in the log file so that it reflects my current time zone so that i can debug errors at a faster rate,
is it possible that i can change the time zone in the log file ?
currently my config is:
logging.basicConfig(filename='audit.log', filemode='w', level=logging.INFO, format='%(asctime)s %(message)s', datefmt='%m/%d/%Y %I:%M:%S %p')
An alternative solution if you want to use logging configuration function: import pytz import logging import logging. config from datetime import datetime tz = pytz. timezone('Asia/Tokyo') class TokyoFormatter(logging.
tzname returns a tuple of two strings: The first is the name of the local non-DST timezone, the second is the name of the local DST timezone. To take this one further, you can use time. tzname[time. daylight] to get the name of the current timezone, accounting for daylight saving time.
Timezone is defined as a geographical area or region throughout which standard time is observed. It basically refers to the local time of a region or country. Most of the time zones are offset from Coordinated Universal Time (UTC), the world's standard for time zone.
%Z
from strftime format
Windows
>>> import logging >>> logging.basicConfig(format="%(asctime)s %(message)s", datefmt="%m/%d/%Y %I:%M:%S %p %Z") >>> logging.error('test') 11/03/2017 02:29:54 PM Mountain Daylight Time test
Linux
>>> import logging >>> logging.basicConfig(format="%(asctime)s %(message)s", datefmt="%m/%d/%Y %I:%M:%S %p %Z") >>> logging.error('test') 11/03/2017 02:30:50 PM MDT test
If the question is
How do I log in a different timezone than the local time on the server?
part of the answer is logging.Formatter.converter, however, you have to understand naive and aware datetime objects. Unless you want to write your own timezone module, I highly suggest the pytz library (pip install pytz
). Python 3 includes a UTC and UTC offset timezone, but there's rules you'll have to implement for daylight saving or other offsets, so I would suggest the pytz library, even for python 3.
For example,
>>> import datetime >>> utc_now = datetime.datetime.utcnow() >>> utc_now.isoformat() '2019-05-21T02:30:09.422638' >>> utc_now.tzinfo (None)
If I apply a timezone to this datetime object, the time won't change (or will issue a ValueError
for < python 3.7ish).
>>> mst_now = utc_now.astimezone(pytz.timezone('America/Denver')) >>> mst_now.isoformat() '2019-05-21T02:30:09.422638-06:00' >>> utc_now.isoformat() '2019-05-21T02:30:09.422638'
However, if instead, I do
>>> import pytz >>> utc_now = datetime.datetime.now(tz=pytz.timezone('UTC')) >>> utc_now.tzinfo <UTC>
now we can create a properly translated datetime
object in whatever timezone we wish
>>> mst_now = utc_now.astimezone(pytz.timezone('America/Denver')) >>> mst_now.isoformat() '2019-05-20T20:31:44.913939-06:00'
Aha! Now to apply this to the logging module.
The LogRecord.created
attribute is set to the time when the LogRecord
was created (as returned by time.time()
), from the time
module. This returns a timestamp (seconds since the epoch). You can do your own translation to a given timezone, but again, I suggest pytz
, by overriding the converter.
import datetime import logging import pytz class Formatter(logging.Formatter): """override logging.Formatter to use an aware datetime object""" def converter(self, timestamp): dt = datetime.datetime.fromtimestamp(timestamp) tzinfo = pytz.timezone('America/Denver') return tzinfo.localize(dt) def formatTime(self, record, datefmt=None): dt = self.converter(record.created) if datefmt: s = dt.strftime(datefmt) else: try: s = dt.isoformat(timespec='milliseconds') except TypeError: s = dt.isoformat() return s
Python 3.5, 2.7
>>> logger = logging.root >>> handler = logging.StreamHandler() >>> handler.setFormatter(Formatter("%(asctime)s %(message)s")) >>> logger.addHandler(handler) >>> logger.setLevel(logging.DEBUG) >>> logger.debug('test') 2019-05-20T22:25:10.758782-06:00 test
Python 3.7
>>> logger = logging.root >>> handler = logging.StreamHandler() >>> handler.setFormatter(Formatter("%(asctime)s %(message)s")) >>> logger.addHandler(handler) >>> logger.setLevel(logging.DEBUG) >>> logger.debug('test') 2019-05-20T22:29:21.678-06:00 test
Substitute America/Denver
with America/Anchorage
for the posix timezone as defined by pytz
>>> next(_ for _ in pytz.common_timezones if 'Alaska' in _) 'US/Alaska'
US/Alaska is deprecated
>>> [_ for _ in pytz.all_timezones if 'Anchorage' in _] ['America/Anchorage']
If you got to this question and answers looking for how to log the local timezone, then instead of hardcoding the timezone, get tzlocal
(pip install tzlocal
) and replace
tzinfo = pytz.timezone('America/Denver')
with
tzinfo = tzlocal.get_localzone()
Now it will work on whatever server runs the script, with the timezone on the server.
I should add, depending on the application, logging in local time zones can create ambiguity or at least confusion twice a year, where 2 AM is skipped or 1 AM repeats, and possibly others.
#!/usr/bin/env python from datetime import datetime import logging import time from pytz import timezone, utc def main(): logging.basicConfig(format="%(asctime)s %(message)s", datefmt="%Y-%m-%d %H:%M:%S") logger = logging.getLogger(__name__) logger.error("default") logging.Formatter.converter = time.localtime logger.error("localtime") logging.Formatter.converter = time.gmtime logger.error("gmtime") def customTime(*args): utc_dt = utc.localize(datetime.utcnow()) my_tz = timezone("US/Eastern") converted = utc_dt.astimezone(my_tz) return converted.timetuple() logging.Formatter.converter = customTime logger.error("customTime") # to find the string code for your desired tz... # print(pytz.all_timezones) # print(pytz.common_timezones) if __name__ == "__main__": main()
pytz
package is the blessed way of converting time zones in Python. So we start with datetime
, convert, then get the (immutable) time_tuple
to match return type of the time
methodslogging.Formatter.converter
function is recommended by this answer: (Python logging: How to set time to GMT).If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With