By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
449,220 Members | 1,588 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 449,220 IT Pros & Developers. It's quick & easy.

logging module and trailing newlines

P: n/a
I was just setting up some logging in a make script and decided to
give the built-in logging module a go, but I just found out that the
base StreamHandler always puts a newline at the end of each log.
There is a comment in the code that says "The record is then written
to the stream with a trailing newline [N.B. this may be removed
depending on feedback]"... I guess there wasn't the feedback to drive
the change.

All I'm after is the ability to log things like...

Compiling 'shrubbery.c'... [DONE]

where the "[DONE]" was added later in time than the "Compiling...",
and the output goes to both stdout and to a log file. ie: I want to
tee my print statements and keep the ability to skip the trailing
newline. I had rolled my own primitive version than decided to try
the logging module for kicks.

Anyone have a suggestion on how to get logging to work like this? Or
know of a way to tee in Windows without forcing other users to install
a tee package?

Oct 2 '07 #1
Share this Question
Share on Google+
2 Replies


P: n/a
Russell Warren wrote:
All I'm after is the ability to log things like...

Compiling 'shrubbery.c'... [DONE]

where the "[DONE]" was added later in time than the "Compiling...", and
the output goes to both stdout and to a log file. ie: I want to tee my
print statements and keep the ability to skip the trailing newline. I had
rolled my own primitive version than decided to try the logging module for
kicks.

Anyone have a suggestion on how to get logging to work like this? Or know
of a way to tee in Windows without forcing other users to install a tee
package?
(1) Logging

If you are too lazy to subclass you can monkey-patch:
>>import logging
def emit(self, record):
.... msg = self.format(record)
.... fs = "%s" if getattr(record, "continued", False) else "%s\n"
.... self.stream.write(fs % msg)
.... self.flush()
....
>>logging.StreamHandler.emit = emit
continued = dict(continued=True)
logging.error("Compiling... ", extra=continued); logging.error("[Done]")
ERROR:root:Compiling... ERROR:root:[Done]

(2) Teeing

"Primitive", but should work:
>>class Stream(object):
.... def __init__(self, *streams):
.... self.streams = streams
.... def write(self, s):
.... for stream in self.streams:
.... stream.write(s)
.... def flush(self):
.... for stream in self.streams:
.... stream.flush()
....
>>import sys
stream = Stream(sys.stdout, sys.stderr)
print >stream, "Compiling...",
Compiling...Compiling...>>>

I'd probably go with the latter.

Peter
Oct 3 '07 #2

P: n/a
Both are very good responses... thanks! I had forgotten the ease of
"monkey-patching" in python and the Stream class is certainly cleaner
than the way I had been doing it.

On Oct 3, 3:15 am, Peter Otten <__pete...@web.dewrote:
Russell Warren wrote:
All I'm after is the ability to log things like...
Compiling 'shrubbery.c'... [DONE]
where the "[DONE]" was added later in time than the "Compiling...", and
the output goes to both stdout and to a log file. ie: I want to tee my
print statements and keep the ability to skip the trailing newline. I had
rolled my own primitive version than decided to try the logging module for
kicks.
Anyone have a suggestion on how to get logging to work like this? Or know
of a way to tee in Windows without forcing other users to install a tee
package?

(1) Logging

If you are too lazy to subclass you can monkey-patch:
>import logging
def emit(self, record):

... msg = self.format(record)
... fs = "%s" if getattr(record, "continued", False) else "%s\n"
... self.stream.write(fs % msg)
... self.flush()
...>>logging.StreamHandler.emit = emit
>continued = dict(continued=True)
logging.error("Compiling... ", extra=continued); logging.error("[Done]")

ERROR:root:Compiling... ERROR:root:[Done]

(2) Teeing

"Primitive", but should work:
>class Stream(object):

... def __init__(self, *streams):
... self.streams = streams
... def write(self, s):
... for stream in self.streams:
... stream.write(s)
... def flush(self):
... for stream in self.streams:
... stream.flush()
...>>import sys
>stream = Stream(sys.stdout, sys.stderr)
print >stream, "Compiling...",

Compiling...Compiling...>>>

I'd probably go with the latter.

Peter

Oct 3 '07 #3

This discussion thread is closed

Replies have been disabled for this discussion.