4
\$\begingroup\$

Here is a simple Python logger I would like some general feedback on.

Features:

  • Dynamically creates log folder and files wherever user runs the program
  • Abillity to create multiple logs from a single program
  • Names logs from time stamp to the latest second preventing name conflicts

I understand there may be far better alternatives to this but I just wanted to tinker around with this concept a bit!

Thank you!

logger.py:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import datetime
import time
import os
import sys

# get user's current directory

directory = os.path.dirname(os.path.realpath(__file__)) + '/logs'


def createNewLog():

    # ensure log folder exists

    if not os.path.exists(directory):
        os.mkdir(directory)

    # get timestamp for naming the log

    timeInSeconds = time.time()
    timestamp = \
        datetime.datetime.fromtimestamp(timeInSeconds).strftime('%Y-%m-%d %H:%M:%S'
            )

    logFile = directory + '/' + timestamp + '.txt'
    mostRecentLog = directory + '/mostRecentLog.txt'

    # create log file and file with the log file's name

    with open(logFile, 'w') as log:
        with open(mostRecentLog, 'w') as recentLog:
            recentLog.write(timestamp)


def findMostRecentLog():

    # ensure logger has been intiated

    try:
        with open(directory + '/mostRecentLog.txt', 'r') as logFile:
            logName = logFile.read()
    except FileNotFoundError:

        print("Must initiate logger first!")
        sys.exit(1)

    return directory + '/' + logName + '.txt'


def log(comment):
    comment = str(comment)

    # write to log file retriving most recent log from corresponding file

    with open(findMostRecentLog(), 'a') as log:
        log.write(comment + '\n')
\$\endgroup\$
2
\$\begingroup\$

In case you do not know it yet, I suggest you to use pylint to parse your code and have automatic feedbacks. In fact some of my notes come from pylint.

Styling notes:

  • Constant names like var "directory" require uppercase style PEP8
  • Function and variable names require snake_case style PEP8
  • Functions require docstring, as well as the module itself PEP8

Inline notes

#NOTE: 'from datetime import datetime' allows a shorter line below
import datetime
import time
import os
import sys

# get user's current directory

# NOTE: use os.path.join for concat filesystem paths for cross compatibility (also below)
directory = os.path.dirname(os.path.realpath(__file__)) + '/logs'


def createNewLog():

    # ensure log folder exists

    if not os.path.exists(directory):
        # NOTE: what if user has no permission to create files/directory in current directory? (also below)
        # HINT: give a way to choose where to store logs
        os.mkdir(directory)

    # get timestamp for naming the log

    timeInSeconds = time.time()
    # NOTE: fromtimestamp may raise an exception which is not not managed here
    timestamp = \
        datetime.datetime.fromtimestamp(timeInSeconds).strftime('%Y-%m-%d %H:%M:%S'
            )

    logFile = directory + '/' + timestamp + '.txt'
    mostRecentLog = directory + '/mostRecentLog.txt'

    # create log file and file with the log file's name

    # NOTE: redefining name 'log' (it's also a function name)
    # NOTE: this 'log' is not used. What it's that for?
    with open(logFile, 'w') as log:
        with open(mostRecentLog, 'w') as recentLog:
            recentLog.write(timestamp)


def findMostRecentLog():

    # ensure logger has been intiated

    try:
        with open(directory + '/mostRecentLog.txt', 'r') as logFile:
            logName = logFile.read()
    except FileNotFoundError:
        print("Must initiate logger first!")
        # NOTE: kind of rugh, I suggest returning an error and managing at caller level
        sys.exit(1)

    return directory + '/' + logName + '.txt'


def log(comment):
    # NOTE: why forcing the type?
    comment = str(comment)

    # write to log file retriving most recent log from corresponding file

    # NOTE: this dependency will make hard testing this function alone.
    with open(findMostRecentLog(), 'a') as log:
        log.write(comment + '\n')
\$\endgroup\$
  • \$\begingroup\$ The fromtimestamp assignment won't raise an exception. The log variable is only altered in the local scope of createNewLog, so it's mostly harmless (except for hurting readability, perhaps). \$\endgroup\$ – Daniel Dec 28 '17 at 13:04
  • \$\begingroup\$ @Coal_ could you explain better the first part? I saw from here that datetime.fromtimestamp could raise a OverflowError. What am I missing? Second part, I agree it's harmless in this context, but I consider it something to avoid (for readability, for future changes, etc.) not an error. \$\endgroup\$ – Carlo Lobrano Dec 28 '17 at 17:05

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.