[py-dev] Logging in the py library
holger krekel
hpk at trillke.net
Tue Jun 7 18:51:11 CEST 2005
On Tue, Jun 07, 2005 at 09:46 -0700, Grig Gheorghiu wrote:
> Holger,
>
> I think it makes a lot of sense to split the functionality between a
> very simple 'producer' API that is exposed to end-users and a
> potentially more complicated 'consumer' API that interfaces with the
> logging module. It's pretty clear you spent time thinking about all
> these things :-), so I think it would probably be best if you came up
> with a first cut at the 'producer' API and at how things tie together.
> Then I'd be glad to work on the 'back-end' API that interfaces with the
> logging module. Would that work for you?
Hehe, i guess so. Let me bet - for the fun of it - that the
producer+consumer API implementation roughly described in the
last mail will not exceed 70 lines of code :-)
cheers,
holger
> --- holger krekel <hpk at trillke.net> wrote:
>
> > Hi Grig,
> >
> > On Tue, Jun 07, 2005 at 07:59 -0700, Grig Gheorghiu wrote:
> > > --- holger krekel <hpk at trillke.net> wrote:
> > > > ...
> > > > Basically we could associate
> > > > with each logging message/object [*] a set of keywords.
> > > > severity categorizations would just be a keyword in that idea.
> > > >
> > > > Let me try an example for e.g. tracing in py/execnet/gateway.py:
> > > > ...
> > > > trace("initializing gateway ...")
> > > > ...
> > > > 'trace' may by default add a 'debug' keyword if called like this.
> >
> > > > If we want to print some warning, then we could do something
> > like:
> > > >
> > > > trace.warn("remote gateway side could not be destroyed")
> > > >
> > > > which would add the keyword 'warning' to that particular message.
> >
> > >
> > > So is this association static or dynamic? If I understand
> > correctly,
> > > you'd want it to be dynamic, right?
> >
> > No, the association of keywords with messages can be static.
> >
> > > So for example trace.foo would add
> > > 'foo' to the message. But the severity levels need to be statically
> > > defined, at least if we want to mimic what the logging module does.
> >
> >
> > Yes, 'trace.debug' would return a tracer that has the same keywords
> > as 'trace' + the keyword 'debug'. Any message this tracer then
> > produces would have all the latter keywords associated with it.
> >
> > > In the logging module, you can set a default severity level,
> > > so that the logger will output only those messages that have
> > > greater or equal severity levels.
> >
> > This refers to output filters and such. I think it makes
> > sense to differentiate between a 'producing' API (basically something
> >
> > very simple like above - just one 'tracer' factory function)
> > and a consuming API dealing with how to redirect messages based
> > on keywords to specific backends/formatters.
> >
> > IMO the connection between producing and consuming objects should
> > be runtime re-configurable. So it's really a small event system
> > and may even be generalized into that at some point. The logging
> > module would only come into play on the consuming side an internal
> > backend and we would expose as few details about this as feasible.
> >
> > > > By default, everything would probably go to stdout but an
> > > > application should be able to redirect by keyword to specific
> > > > formatting/output backends (much like the logging module). I
> > > > think it's important to allow this redirection to happen
> > > > _after_ the above example is already imported, so
> > > > redirections-by-keyword should be re-configurable at runtime.
> > >
> > > Yes, it would be nice to have the possibility of sending the
> > messages
> > > to a variety of handlers (stdout, files, sockets, HTTP servers,
> > etc.)
> > > One reservation I have about stdout being the default is that it
> > might
> > > interfere with py.test's own catching of stdout/stderr. I think it
> > > would be better to trace to a file by default (I think that's what
> > the
> > > twisted.log module does too, although I haven't looked at it, I
> > only
> > > saw it mentioned somewhere).
> >
> > don't worry, py.test could reconfigure the tracing accordingly.
> > The idea above is really about an application-independent
> > general mechanism. I believe that the basic tracer should
> > be as close to a mere 'print' statement as possible.
> >
> > Hum, to keep things really minimal we might consider:
> >
> > import py
> > py.trace.debug('hello', 'world')
> >
> > which would by default print something like:
> >
> > [debug] hello world
> >
> > Or, to make it even more obvious:
> >
> > print >>py.trace.debug, "hello", "world"
> >
> > No API is the best API, remember? :-)
> >
> > (the disadvantage is that the str()s are always computed
> > but that is a somewhat unfortunate language implementation
> > detail that could be changed at some point :-).
> >
> > The nice property of the above that it is a really simple
> > idiom which makes it obvious that the tracing statement
> > does not mutate the program state but only has a tracing
> > side effect.
> >
> > > > What do you think of this basic keyword idea? (which cold
> > > > still use the logging module underneath for accessing all
> > > > the backends if it makes sense).
> > > >
> > > > And sorry, but the py lib really aims at exploring
> > > > improvements over current ways of doing things :-)
> > > >
> > >
> > > I think it's a very good idea. In my opinion, it would still be
> > worth
> > > using the logging module underneath, since all the grunt work is
> > > already done there. I hate reinventing wheels.
> >
> > Agreed. However, before worrying about output handlers (where
> > the logging module could really help) i'd like to have a nice
> > pythonic tracing model that allows to connect e.g. print-statements
> > to tracer functions (and we can offer some default set of
> > tracer functions which itself use the logging module).
> >
> > Hum. Here is a thought example of how a _consuming_ tracer
> > function could look like:
> >
> > def mytracer(message):
> > if 'error' in message.keywords:
> > print >>somefile, "error:", str(message)
> > elif ...
> >
> > py.trace[...] = mytracer
> > ^^^ literally :-)
> >
> > or to associate the consuming tracer function more directly:
> >
> > def myerrortracer(message):
> > print >>errorfile, str(message)
> >
> > py.trace['error'] = myerrortracer
> >
> > Wouldn't the meaning of this API be obvious?
> > (I am not explaining it on purpose here :-)
> >
> > Providing adapter-consuming-tracer-functions for using the
> > logging-module's backends should then becomes an orthogonal
> > disconnected issue.
> >
> > > But polishing and simplifying the interface to the logging
> > > module is certainly something to be aimed for -- and your
> > > keyword idea goes a long way towards that goal.
> >
> > great to hear!
> >
> > I have to admit i have thought about the 'tracing problem'
> > quite a bit already and i had some discussion with Vinay at
> > the time (the author of the logging module). Your bringing
> > up of the topic forced me to try express my train of thoughts
> > more clearly.
> >
> > cheers,
> >
> > holger
> >
>
More information about the Pytest-dev
mailing list