[ python-Feature Requests-1190689 ] logging module root logger name
SourceForge.net
noreply at sourceforge.net
Thu Apr 28 09:36:02 CEST 2005
Feature Requests item #1190689, was opened at 2005-04-27 01:19
Message generated for change (Comment added) made by vsajip
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=355470&aid=1190689&group_id=5470
Category: Python Library
Group: None
>Status: Closed
>Resolution: Fixed
Priority: 5
Submitted By: Christopher Dunn (cxdunn)
Assigned to: Vinay Sajip (vsajip)
>Summary: logging module root logger name
Initial Comment:
I would like a trailing '.' to be ignored in names
passed to getLogger(), like a trainling '/' in a Unix path.
In module 'foo':
logfoo = getLogger('.foo.')
# logger '"" should be the parent of ".foo"
Elsewhere, controlled by the user of that module:
import foo
logdefault = getLogger('.')
hdlr = StreamHandler()
fmtr = Formatter("%(name)s:%(msg)s")
hdlr.setFormatter(fmtr)
logdefault.addHandler(hdlr)
Given this change, I would also like the name of the
default logger to be displayed as '.', or even "",
rather than 'root'. The current behavior is odd:
logfoo.info("Foo message")
displays
.foo:Foo message
buf
logdefault.info("Default message")
displays
root:Default message
I NEVER mentioned the word "root" anywhere! And I don't
think it's very descriptive.
I would rather see ANY of these:
:Default message
.:Default message
default:Default message
logging:Default message
These changes would make the system more intuitive.
-cxdunn
----------------------------------------------------------------------
>Comment By: Vinay Sajip (vsajip)
Date: 2005-04-28 07:36
Message:
Logged In: YES
user_id=308438
Logger names are hierarchical with dots separating levels in
the hierarchy. So to me it does not make sense to have
logger names which end in a dot, and you have given no
reason why trailing dots should be supported. However, the
hierarchy is not completely anologous to file system
hierarchies - there is by design no concept of a "default"
or "current" logger. I do not propose to make a change to this.
However, I agree that the name of the root logger being "root"
might be seen as unintuitive by some. Of your alternatives I
think "logging" is best. I propose to add to the documentation
the suggestion that users can define their own name for the
root logger as in the following example:
logging.getLogger().name = "myapp"
People who use the root logger directly typically don't use
other (named) loggers, because the whole point of using
named loggers is to pinpoint areas of the application. Those
users who use the root logger directly are typically not
interested in finer granularity than the application or script
itself.
----------------------------------------------------------------------
Comment By: Christopher Dunn (cxdunn)
Date: 2005-04-28 07:29
Message:
Logged In: YES
user_id=1267419
Oops. Where I wrote abspath.rstrip('.'), I meant
abspath.strip('.')
Drop both leading and trailing dots for the prettified path.
-cdunn
----------------------------------------------------------------------
Comment By: Christopher Dunn (cxdunn)
Date: 2005-04-28 07:21
Message:
Logged In: YES
user_id=1267419
I am attaching a first pass it it.
I've stored the "absolute" names everywhere, including both
leading and trailing '.'
I call this "absolute" by analogy with os.path.abspath(). I
believe that similarities within the Python library help the
user remember key concepts.
What's missing:
* I don't have aliases.
* The "current working logger" is always '.'
* And I haven't added any extra tags for the Formatter.
But those are all very simple changes. The tough part is
getting the path-searching correct. I have a big UnitTest
suite which I can send to you if you'd like.
The most important thing is that the word "root" is
completely gone, but perhaps %(name)s should translate '.'
to 'root' for backwards compatibility.
The second-most important thing is that getLogger('.')
returns the root logger.
Third is that getLogger("Package.Module") is equivalent to
getLogger(".Package.Module.")
As for tags in the Formatter, after some testing I suggest
these:
%(name)s => abspath.rstrip('.'), but "." becomes "root"
%(absname)s => abspath, with leading AND trailing dot, like
a directory, so there is no question about whether the root
displays as "." or "". It is always just dot in absolute
notation.
%(logger)s => abspath.rstrip('.'), maybe the prettiest
I must tell you that, once I figured out how the logging
module works, I really love it!
Other possible additions:
* Some useful, predefined filter classes: Never, OneTime
(which must have a reset() method to clear its cache). I can
send my version if you want.
* A PipedStreamHandler. I'm not sure how to make this work.
The idea is that, in UnitTesting, I want to read from some
stream immediately after an operation, and I want the logged
data to be immediately available, but to disappear as soon
as I've read it. Does that make sense? Right now, I use a
cStringIO object, with s.seek(0); s.truncate() after every read.
-cxdunn
----------------------------------------------------------------------
Comment By: Christopher Dunn (cxdunn)
Date: 2005-04-27 20:37
Message:
Logged In: YES
user_id=1267419
Novices always ask, "Why did it print 'root'? Where did that
come from?
After discussing this with some other "logging" module
users, I think we've come up with a very good idea, which
would maintain BACKWARDS COMPATIBILITY.
Essentially, treat the logging module as a shell and the
logger name as a path. Specifically,
* Let the global logging functions operate on the "current
worrking logger", which by default is "." (Let "root" be an
alias for ".")
* Change getLogger() so that it works on both absolute and
relative logger paths. (Since the default current logger is
"root", we maintain backwards compatibility.)
* Change the format function so that %(name)s shows the
relative path, if the absolute path starts with the current
working logger name.
* Add a format keyword, %(absname)s, which prints the
absolute logger path.
* Add another format keyword, %(logger)s, which prints what
most people expect to see: the absolute logger name, sans
the leading dot. (The "root" or "." logger would display as
"", exactly the way it is usually accessed.)
* Add global functions, change_current_logger() and
get_current_logger().
* Add global function, alias(). Always create an alias for
"root" to "."
Examples::
from logging import *
log = getLogger() #or getLogger(".") or getLogger("root")
h1 = StreamHandler()
f1 = Formatter("[%(name)s]%(message)s")
h1.setFormatter(f1)
log.addHandler(h1)
h2 = StreamHandler()
f2 = Formatter("[%(absname)s]%(message)s")
h2.setFormatter(f2)
log.addHandler(h2)
h3 = StreamHandler()
f3 = Formatter("[%(logger)s]%(message)s")
h3.setFormatter(f3)
log.addHandler(h3)
log.error("First message")
# ...
child = getLogger("child") # or getLogger(".child")
child.error("Bad news")
This should print:
[root]First message
[.]First message
[]First message
[child]Bad news
[.child]Bad news
[child]Bad news
This would create tremendous flexibility, add some clarity
to the meaning of the "root" logger, and still maintain
complete backwards compatibility.
I am willing to make the changes myself, including
UnitTests, if there is agreement that they would be adopted.
(Note that String.before() and String.after() would make the
coding a little easier/clearer, but that's a different
feature request.)
-cxdunn
----------------------------------------------------------------------
You can respond by visiting:
https://sourceforge.net/tracker/?func=detail&atid=355470&aid=1190689&group_id=5470
More information about the Python-bugs-list
mailing list