Bussiere
Bussiere

Reputation: 1154

Logging in python with correct timezone

I would like to write log in a file with the correct timezone time (Europe/Paris) in a UpdateSubsStatus.log file ...

Here what i tried, the commented line are what i tired but it does not work.

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
#console = logging.StreamHandler()
logging.basicConfig(filename='UpdateSubsStatus.log', filemode='a', format='%(asctime)s;%(name)s - %(levelname)s - %(message)s',datefmt='%Y-%m-%d %H:%M:%S')
#console.setFormatter(Formatter)
#logging.getLogger('').addHandler(console)

Does it exist a simple way with the basic config to use a timezone ?

Regards

Upvotes: 2

Views: 6028

Answers (2)

Jacob
Jacob

Reputation: 2414

Hope This helps, just using simple logic and passing in the required Timezone as an argument. Also, the return value is created with dateTimenow format.

from datetime import datetime
import pytz

def getTime(timeZoneVal):
    # get the standard UTC time
    UTC = pytz.utc
    logTime = pytz.timezone(timeZoneVal)

    #print("US Time in Default Format : ",  datetime.now(logTime))
    return datetime.now(logTime)

logTime = getTime('Europe/Paris')
print(logTime)

Upvotes: 0

Yevhen Bondar
Yevhen Bondar

Reputation: 4707

I tried logging events using your code. the events are logged in the local timezone, not the specified one. I think the problem is with this code

def converter(self, timestamp):
    dt = datetime.datetime.fromtimestamp(timestamp)
    tzinfo = pytz.timezone('America/Denver')
    return tzinfo.localize(dt)

This code converts timestamp to local datetime and changes tzinfo without a real datetime conversion

>>> timestamp
1619258964.3946261
>>> dt = datetime.datetime.fromtimestamp(timestamp)
>>> dt
datetime.datetime(2021, 4, 24, 13, 9, 24, 394626)
>>> tzinfo = pytz.timezone('America/Denver')
>>> res = tzinfo.localize(dt)
>>> res
datetime.datetime(2021, 4, 24, 13, 9, 24, 394626, tzinfo=<DstTzInfo 'America/Denver' MDT-1 day, 18:00:00 DST>)
# Hours left unchanged

So I change method converter

def converter(self, timestamp):
    # Create datetime in UTC
    dt = datetime.datetime.fromtimestamp(timestamp, tz=pytz.UTC)
    # Change datetime's timezone 
    return dt.astimezone(pytz.timezone('America/Denver'))

Here the final code

import pytz
import logging
import datetime


class Formatter(logging.Formatter):
    """override logging.Formatter to use an aware datetime object"""

    def converter(self, timestamp):
        # Create datetime in UTC
        dt = datetime.datetime.fromtimestamp(timestamp, tz=pytz.UTC)
        # Change datetime's timezone
        return dt.astimezone(pytz.timezone('America/Denver'))

    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


console = logging.FileHandler('UpdateSubsStatus.log')
console.setFormatter(Formatter(
    '%(asctime)s;%(name)s - %(levelname)s - %(message)s', '%Y-%m-%d %H:%M:%S'))
logging.getLogger('').addHandler(console)
logging.critical("Critical event")

Log file UpdateSubsStatus.log (still America/Denver timezone)

2021-04-24 04:19:16;root - CRITICAL - Critical event
2021-04-24 04:19:17;root - CRITICAL - Critical event

Also, don't forget to change the timezone to Europe/Paris

Upvotes: 7

Related Questions