Benefits of journaling and printing () + best journal practices

I am currently working on the 1.0a pyftpdlib release. In this new release, some lagging incompatible changes will be made in that some APIs will no longer accept bytes, but unicode. While I am in this, as part of this burden, I have been thinking about being able to get rid of my registration functions, which currently use print, and use the logging module instead.

Pyftpdlib is currently delegating an entry into 3 functions:

def log(s): """Log messages intended for the end user.""" print s def logline(s): """Log commands and responses passing through the command channel.""" print s def logerror(s): """Log traceback outputs occurring in case of errors.""" print >> sys.stderr, s 

A user who wants to configure the logs (for example, write them to a file) should simply overwrite these 3 functions, as in:

 >>> from pyftpdlib import ftpserver >>> >>> def log2file(s): ... open('ftpd.log', 'a').write(s) ... >>> ftpserver.log = ftpserver.logline = ftpserver.logerror = log2file 

Now I'm wondering: what benefits would it mean to get rid of this approach and use the logging module instead? From the perspective of the module provider, how exactly should I open the registration functions in my module? I must do it:

 import logging logger = logging.getLogger("pyftpdlib") 

... and indicate in my document that the “registrar” is the object that is supposed to be used if the user wants to configure the behavior of the logs? Is deliberate assignment of a predetermined output format legal, as in:

 FORMAT = '[%(asctime)] %(message)s' logging.basicConfig(format=FORMAT) logger = logging.getLogger('pyftpdlib') 

...

Can you think of a third-party module, I can take signals from where the logging functions are open and integrated as part of a public API?

Thanks in advance.

+7
source share
4 answers
Libraries

(ftp server or client library) should never initialize the logging system. Thus, it’s normal to create an instance of the registrar object and point to logging.basicConfig in the documentation (or provide a function along the lines of basicConfig with fancier output and let the user choose among his strategy a logging configuration, a simple basicConfig or the provided library)

(for example, django) or servers (ftp server daemon) should initialize the logging system to a reasonable default and enable logging system configuration.

+3
source

Typically, libraries should simply create a NullHandler handler that simply does not execute the handler. The end user or application developer who uses your library can then configure the logging system. For more information, see Configure logging for a library in the logging documentation. In particular, see the note that begins

It is highly recommended that you do not add any handlers other than NullHandler to your library registrars.

In your case, I just create a logging handler, according to the logging documentation,

 import logging logging.getLogger('pyftpdlib').addHandler(logging.NullHandler()) 

Edit The implementation of the journal outlined in the question seems to be quite reasonable. In your documentation, simply specify logger and discuss or specify users in the logging.setLevel and logging.setFormatter to configure output from your library. Instead of using logging.basicConfig(format=FORMAT) you can use logging.config.fileConfig to control your output settings and document the configuration file somewhere in your documentation, again pointing the user to the documentation of the logging module for the format expected in this file.

+2
source

Here is the resource I used to create a custom logger . I have not changed much, I just added an if statement and pass on whether I want to register in a file or just in the console.

Check this one . This is very nice for coloring the output, so DEBUG looks different than WARN, which looks different than INFO.

The logging module bundles many good features, such as SMTP logging, file rotation logging (so you can save a couple of old log files, but not create 100 of them every time something goes wrong).

If you ever want to upgrade to Python 3, using the logging module will eliminate the need to modify your print statements.

Logging is amazing depending on what you are doing, I only used it a bit earlier to see where I am in the program (if you use this function, the color is that way), but it has significantly more power than the regular print statement . A.

0
source

You can look at Django (just create a sample project) and see how it initializes the registration subsystem.

There is also a context registrar assistant , which I wrote some time ago - this registrar automatically accepts the name of the module / class / function from which it was initialized. This is very useful for debugging messages, where you can see that messages are being streamed through this module and how the call flow goes.

0
source

All Articles