2

I am attempting to make a logging module for Python that does not work because it fails on creation of the file object.

debug.py:

import os
import datetime
import globals

global fil
fil = None

def init(fname):
     fil = open(fname, 'w+')
     fil.write("# PyIDE Log for" + str(datetime.datetime.now()))

def log(strn):
    currentTime = datetime.datetime.now()

    fil.write(str(currentTime) + ' ' + str(os.getpid()) + ' ' + strn)
    print str(currentTime) + ' ' + str(os.getpid()) + ' ' + strn

def halt():
    fil.close()

fil will not work as None as I get an AttributeError. I also tried creating a dummy object:

fil = open("dummy.tmp","w+")

but the dummy.tmp file is written to instead, even though init() is called before log() is. Obviously you cannot open a new file over an already opened file. I attempted to close fil before init(), but Python said it could not perform write() on a closed file.

This is the code that is accessing debug.py

if os.path.exists(temp):
         os.rename(temp, os.path.join("logs","archived","log-" + str(os.path.getctime(temp)) + ".txt"))
         debug.init(globals.logPath)
         debug.log("Logger initialized!")

I would like to have logging in my program and I cannot find a workaround for this.

Eric
  • 95,302
  • 53
  • 242
  • 374
Galen Nare
  • 376
  • 2
  • 4
  • 18
  • out of curiosity, why arent you encompassign this in a class? Im pretty sure you would avoid this issue if you did this in a class – TehTris May 19 '15 at 20:06
  • @septi this won't work because I have a log archiving system set up. See the last code snippet. The file accesses conflict. If I open the file with `debug.py` before `init()` then I will not be able to wite because it is already used by a process. – Galen Nare May 19 '15 at 20:08
  • @TehTris No, completely self taught. – Galen Nare May 19 '15 at 20:08
  • Oh, lol, nice. you are going to like my answer then. – TehTris May 19 '15 at 20:09
  • he is attempting to MAKE a logger module, not use an existing one BTW – TehTris May 19 '15 at 20:12
  • @GalenNare I don't get it. You have probably no idea how powerful the `logging` module is? – tamasgal May 19 '15 at 20:13
  • @septi I looked at it and I still prefer not to use it. It still gets in the way of log archiving. – Galen Nare May 19 '15 at 20:14
  • Do what you need to do, but I'm pretty sure that you waste your time reimplementing stuff that is already there (and tested). ; ) – tamasgal May 19 '15 at 20:15
  • 1
    its also possible hes just trying to learn how to do something on his own? its always good practice to implement something that already exists on your own. – TehTris May 19 '15 at 20:18
  • @TehTris is right. I have only been using Python for a couple months. I'm not exactly what you would consider professional. – Galen Nare May 19 '15 at 20:20
  • 2
    It's always a good practice to learn some basic modules which are used in nearly every single project. – tamasgal May 19 '15 at 20:21

3 Answers3

6

Your problem is that you don't assign to the global fil:

def init(fname):
    fil = open(fname, 'w+')

This creates a new local variable called fil.

If you want to assign to the global variable fil you need to bring it into the local scope:

def init(fname):
    global fil
    fil = open(fname, 'w+')
Peter Wood
  • 23,859
  • 5
  • 60
  • 99
1

If you want to MAKE your own logging module, then you may want to turn what you already have into a class, so you can import it as a module.

#LoggerThingie.py
import os
import datetime



class LoggerThingie(object):
    def __init__(self,fname):
         self.fil = open(fname, 'w+')
         self.fil.write("# PyIDE Log for" + str(datetime.datetime.now()))

    def log(self,strn):
        currentTime = datetime.datetime.now()
        self.fil.write(str(currentTime) + ' ' + str(os.getpid()) + ' ' + strn)
        print str(currentTime) + ' ' + str(os.getpid()) + ' ' + strn

    def halt(self):
        self.fil.close()

If you did this as a class, you would not have to keep track of globals in the first place (which is generally understood as bad practice in the world of programming: Why are global variables evil? )

Since it is now a module on its own, when you want to use it in another python program you would do this:

from LoggerThingie import LoggerThingie
#because module filename is LoggerThingie.py and ClassName is LoggerThingie

and then use it wherever you want, for example:

x = LoggerThingie('filename.txt') #create LoggerThingie object named x

and every-time you want to insert logs into it:

x.log('log this to the file')

and when you are finally done:

x.halt() # when ur done
Community
  • 1
  • 1
TehTris
  • 3,139
  • 1
  • 21
  • 33
0

If you don't want to start with an empty file you could use StringIO to keep the messages in memory and write them to disk at the end but be careful, if something happened and you didn't wrote the messages they will be lost.

Facundo Casco
  • 10,065
  • 8
  • 42
  • 63