3 ms·
The acid test is to see if you can avoid terms like "Writer", "Printer", and whether someone is able to explore your API using the REPL. >>> import log
by teyc 15y ago
The acid test is to see if you can avoid terms like "Writer", "Printer", and whether someone is able to explore your API using the REPL.
>>> import log
>>> log.log(log.CRITICAL, 'PrintModule', 'Printer failure', sys.exc_info())
PrintModule: Printer failure
>>> print log.configuration
[<function printToStdErr as 0xcafebad>]
>>> log.configuration.clear()
>>> print log.configuration
[]
>>> def send_mail(level, module, message, exception):
... import smtplib
... smptlib.SMTP('mail.test.com').send('syslog@test.com',
... 'no-reply@mysystem.com', module + ' ' + message)
...
>>> log.configuration.append(send_mail)
>>> log.log(log.CRITICAL, 'PrintModule', 'Printer failure', sys.exc_info())
etc.
Next, configuration must be straightforward.
>>> import log
>>> log.configuration.extend([
... log.sendmail,
... log.syslog,
... log.rotatinglog])
...
>>> log.sendmail.to = 'admin@test.com'
Notice how this can easily be captured into a file you might name as logconfig.py
You might be wondering how to assign an attribute to a function, like sendmail.to?
In this particular case, sendmail is actually a class that masquerades as a function.
>>> class Sendmail:
... to = None
...
... def __call__(self, level, module, msg, exc):
... # et. c
...
>>> sendmail = Sendmail()
This way, the most common use-case, i.e. to be notified when something happens is easy to apply, while more complicated ones are only a short step away.
- peter_l_downs 15y agoThanks. I like the idea of classes masquerading as functions. And easier configuration. I had actually started writing this 2 days ago as something just for me, but after reading this decided to try something new.
- jacobolus 15y agoWith something that can happen as often as logging, make sure that you test it when accessed from multiple python threads, and pound the crap out of it in various typical configurations. Python’s default logging can be a real dog, and at least in one project I was working on a few years ago turned out to be a real bottleneck.
- teyc 15y agoAlso keep the following in mind. You don't need to use Singletons in Python. The following code smells in Python. log.getLogger() use a module instead.
- kansface 15y agoYou can assign an attribute to a function in Python since functions have a __dict__. for example: def foo(): pass foo.a="asdf" >>> foo.a 'asdf' >>> foo.__dict__ {'a': 'asdf'} or alternatively: >>> def bar(): ... bar.a = "asdf" ... >>> bar.a Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: 'function' object has no attribute 'a' >>> bar() >>> bar.a 'asdf'
- euccastro 15y agoYou can assign arbitrary attributes to a plain function: >>> def f(): ... print f.something ... >>> f.something = 'blah' >>> f() blah