Re: [Tutor] Logger object not passed between modules

2011-07-26 Thread Peter Otten
Luke Thomas Mergner wrote:

> I am very new to Python and programming, basically just a curious
> hobbyist.  I am building a learning app that hopefully will include a
> wxPython GUI.  Right now I am trying to understand my code better by
> including print statements.  Now I know that I could just print to the
> terminal, but I thought 'why not try this nice little logger class.'  And
> it works perfectly in the main class App(wx.App), but I can't seem to pass
> the same logger object to the imported modules.  I'm verifying this by
> printing the logger object to terminal (stdout?).  I've spent close to 6
> hours trying to figure this out, and I need some help.
> 
> The logger object is created within a function in the main app class.  Is
> this wrong? I thought that logger ensured the same object is used by both
> classes.  The logger.getLogger(__name__) doesn't set anything other than
> the name used to describe the source of the message, so how do I make sure
> I'm using the same log object?  

No, the name is used to identify a logger; different names mean different 
loggers.

> I assume the problem is either scope (the
> log has to be in the module, not the class) or passing the object
> properly, neither of which I"m very comfortable with obviously.

Loggers are put into a hierarchy similar to a directory tree with the root 
logger at the top. By default the other loggers pass logging messages up to 
their parent so that all messages (or LogRecords) are eventually seen by the 
root logger. In most cases it is sufficient to handle them there, and the 
easiest way to add a suitable formatter and handler is 
logging.basicConfig():

>>> import logging
>>> class App:
... def __init__(self):
... self.logger = logging.getLogger("main")
...
>>> class Frame:
... def __init__(self):
... self.logger = logging.getLogger("frame")
...
>>> logging.basicConfig(level=logging.DEBUG, filename="tmp.log")
>>> app = App()
>>> frame = Frame()
>>> frame.logger.info("hello from frame")
>>> app.logger.info("hello from app")
>>> with open("tmp.log") as f: print f.read()
...
INFO:frame:hello from frame
INFO:main:hello from app


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


Re: [Tutor] Logger object not passed between modules

2011-07-26 Thread Walter Prins
Hi Luke,

On 26 July 2011 06:58, Luke Thomas Mergner  wrote:

> The logger object is created within a function in the main app class.  Is
> this wrong? I thought that logger ensured the same object is used by both
> classes.  The logger.getLogger(__name__) doesn't set anything other than the
> name used to describe the source of the message, so how do I make sure I'm
> using the same log object?  I assume the problem is either scope (the log
> has to be in the module, not the class) or passing the object properly,
> neither of which I"m very comfortable with obviously.
>


With the caveat that I'm not exactly a logging expert in Python, let me
submit the following observations:
1) You should generally only create logger objects inside modules (whether
main or otherwise) for module specific logging.  Such a created logger
should not be shared with other modules. So yes your current approach at the
very least doesn't go by the the logging module's normal usage pattern(s).

2) If you don't care about module specific logging (and I suggest you do
not, at this stage of your learning), then you should ignore creating your
own logger objects and instead, simply directly log using the logging
*module* (which contains a share loggger object already.)

3) See the section entitled "Logging from multiple modules" here:
http://docs.python.org/howto/logging.html for an example of this.
It demonstrates how you can do some basic configuration of your log in the
main application module and also log from other modules, all without having
to explicitly create your own (module specific) logger objects.

HTH,

Walter
___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor


[Tutor] Logger object not passed between modules

2011-07-25 Thread Luke Thomas Mergner
Hi,

Python 2.7.2
wxPython 2.9.1.1
OS X 10.7

I am very new to Python and programming, basically just a curious hobbyist.  I 
am building a learning app that hopefully will include a wxPython GUI.  Right 
now I am trying to understand my code better by including print statements.  
Now I know that I could just print to the terminal, but I thought 'why not try 
this nice little logger class.'  And it works perfectly in the main class 
App(wx.App), but I can't seem to pass the same logger object to the imported 
modules.  I'm verifying this by printing the logger object to terminal 
(stdout?).  I've spent close to 6 hours trying to figure this out, and I need 
some help.

The logger object is created within a function in the main app class.  Is this 
wrong? I thought that logger ensured the same object is used by both classes.  
The logger.getLogger(__name__) doesn't set anything other than the name used to 
describe the source of the message, so how do I make sure I'm using the same 
log object?  I assume the problem is either scope (the log has to be in the 
module, not the class) or passing the object properly, neither of which I"m 
very comfortable with obviously.

Thanks in advance.  Code snippets and prints follow.
Luke



# File / module one.
import FrameMaker # instantiates the subclassed wx.Frame object and fills it.
class App(wx.App):
def __init__(self)
self.logger = self.Log()

def Log(self):
appName = 'wxNew'  # I thought this line would make it easier 
to 'refactor' I hear people care about that.
logfile = ''.join([appName, '.log']) #Look, I learned to use 
the .join() function!
if not os.path.exists(log file):  # some examples I saw suggest 
logger handles this file check.
f = open(logfile, 'w')
f.close()
logger = logging.getLogger('Main')
logger.setLevel(logging.DEBUG)
fh = logging.FileHandler(logfile)
fh.setLevel(logging.DEBUG) # If I only want one log, do I need 
to create a special handler 'fh'?
format = logging.Formatter("%(asctime)s - %(name)s - 
%(levelname)s - %(message)s")
fh.setFormatter(format)
logger.addHandler(fh)
logger.info('Starting log... ')
return logger


# File / Module two
class myFrame(wx.Frame):
def __init__(self, parent, id=-1, label="", size=(300, 500)):
#set the name of the logger.
self.logger = logging.getLogger('Frame') # The argument shouldn't 
matter, as I follow the examples.
print self.logger
self.logger.info('In frame __init__, the size is : ', self.GetSize) 

$ python app.py



--The log prints --
2011-07-26 01:39:07,642 - Main - INFO - Starting log... 
2011-07-26 01:39:11,078 - Main - INFO - Shutting down main app.


Luke Thomas Mergner
Mechanicsville, MD
lmergner.blogspot.com
lmerg...@gmail.com


___
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor