Advise on using logging.getLogger needed.

S

Steven W. Orr

I hope I don't sound like I'm ranting :-(

I have created a module (called xlogging) which sets up logging the way I want
it. I found out that if I set up my logger without a name, then it gets
applied to every logger that is referenced by every module that ever gets
imported.

The problem is that I must call xlogging.getLogger or logging.getLogger in all
other modules using the name of the root logger, and I don't know what that
name is.

I want the name of the root logger to be the name of the running program, so
in my setup, I say

pname = sys.argv[0]
try:
rslash = pname.rindex('/')
except ValueError:
pass
else:
pname = pname[rslash + 1:]

try:
dot_py = pname.rindex('.py')
except ValueError:
pass
else:
pname = pname[0:dot_py]

and then I say

logger = logging.getLogger(pname)

My problem is that I just want the modules that I write, to be able to get the
named root logger and still be able to refer to possible sub-loggers.

So, let's say I run program foo. At some point in my mail setup, I set the
configuration for the foo logger. I'd like my xlogging module to supply a
getLogger function such that if I don't supply any arguments, it will return
the logger that would normally be returned by logging.getLogger(pname).

Also, part of the reason I'm confused is because foo calls m1 and m2 and they
want to say

logger = xlogging.getLogger(MaybeWithAnArg?)

at the top of their code. This means that the import statement for m1 and m2
are getting the calls to getLogger executed before I get the chance to set
things up.

I am running 2.6, so I don't have access to logging.getChild, but I'm not
clear that I even want that.

My modules are used by multiple programs. Does this mean that I should simply
use __name__ all the time? (That seems inelegant, no?)

If I'm making sense, is there a way to do this?


--
Time flies like the wind. Fruit flies like a banana. Stranger things have .0.
happened but none stranger than this. Does your driver's license say Organ ..0
Donor?Black holes are where God divided by zero. Listen to me! We are all- 000
individuals! What if this weren't a hypothetical question?
steveo at syslang.net
 
V

Vinay Sajip

I hope I don't sound like I'm ranting :-(

You don't, but neither is it absolutely clear what you're trying to
achieve. BTW the term "root logger" in the logging docs refers to a
logger internal to the logging package, and not to a logger that you
create. For that, it's best to refer to "top level logger for my
application/library".

Supposing you want your top-level logger always to be the name of your
main script, and you want other loggers to live below this logger. In
your main script module, therefore, you do the equivalent of

pname = compute_program_name(sys.argv[0])
logger = logging.getLogger(pname)
# configure logging handlers, filters etc. for your application

In your library modules, if you want them to live under that top-level
logger, then you can do something like

pname = compute_program_name(sys.argv[0])
logger = logging.getLogger('%s.%s' % pname, __name__)

where you can use something other than __name__ for the logger name
suffix, if you want.
My problem is that I just want the modules that I write, to be able to get the
 named root logger and still be able to refer to possible sub-loggers.

According to the scheme I describe, if you have two scripts called
"foo" and "bar" which make use of a common module "baz", then events
in the foo module would appear under logger "foo", and events in the
baz module when run from foo would be logged under logger "foo.baz".
When running "bar", events in the bar module would appear under logger
"bar", whereas events in the baz module when run from bar would be
logged under logger "bar.baz". This seems to be what you're asking
for, but I may have misunderstood.
I am running 2.6, so I don't have access to logging.getChild, but I'm not
clear that I even want that.

getChild is just a convenience method, you don't need it - you can
just build the logger name as in my example above.
My modules are used by multiple programs. Does this mean that I should simply
use __name__ all the time? (That seems inelegant, no?)

Actually __name__ is very elegant, as it is impervious to you moving
your code around and follows the Python package hierarchy. Also, if
you are using third party code (especially from various sources),
using __name__ will make things unambiguous about where exactly events
are being logged from. Third party code typically won't know about
your top-level logger, and __name__ is the one scheme that everything
can agree on - the point about logger names being that they're
supposed to codify "where" in your application events occur, and the
package hierarchy is the canonical representation of source locations
in an application.

Regards,

Vinay Sajip
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,733
Messages
2,569,440
Members
44,829
Latest member
PIXThurman

Latest Threads

Top