classification
Title: Support logging.getLogger(style='{')
Type: enhancement Stage: resolved
Components: Library (Lib) Versions: Python 3.5
process
Status: closed Resolution: rejected
Dependencies: Superseder:
Assigned To: vinay.sajip Nosy List: mitar, rhettinger, sdwarwick, vinay.sajip
Priority: normal Keywords:

Created on 2017-07-23 01:29 by mitar, last changed 2017-09-25 07:36 by vinay.sajip. This issue is now closed.

Messages (8)
msg298883 - (view) Author: Mitar (mitar) * Date: 2017-07-23 01:29
Currently, using non-legacy formatting in logging message is really cumbersome. I think a new style could be supported much easier using the following:

logger = logging.getLogger(style='{')
logger.misc('User {} logged in', username}

This is both backwards compatible, and does not interfere with 3rd party packages which might use a different logger with different style. You only have to make sure they do not use this logger without knowing about new format, which can be done in various ways (like prefixing the name of the logger, for example).

See https://bugs.python.org/issue14031 for more information, where this has also been proposed but not really commented upon.
msg299334 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2017-07-27 18:34
> You only have to make sure they do not use this logger without knowing about new format, which can be done in various ways (like prefixing the name of the logger, for example).

That's the problem, right there. I don't think the ways of doing this are bulletproof and require too much cooperation between third-party libraries.

> using non-legacy formatting in logging message is really cumbersome

I don't see how it's "really cumbersome". A simple approach is outlined in

http://plumberjack.blogspot.co.uk/2010/10/supporting-alternative-formatting.html

So that logging using brace formatting could be as simple as 

logger.misc(__('User {} logged in', username))

which is also described in the documentation here:

https://docs.python.org/3.3/howto/logging-cookbook.html#use-of-alternative-formatting-styles
msg299353 - (view) Author: Mitar (mitar) * Date: 2017-07-27 22:31
> That's the problem, right there. I don't think the ways of doing this are bulletproof and require too much cooperation between third-party libraries.

Which third-party libraries? The thing I am proposing works for that particular file you call getLogger with.

In my files I already have:

logger = logging.getLogger(__name__)

Changing that to:

logger = logging.getLogger(__name__, style='{')

seems easy and backwards compatible. How will I break any other 3rd party use by doing this? It is my code in my file.

The only issue is that you have to make sure you are not passing object on. But that again, is your code, so you should know what you are passing on.

We could also add logger.defaultStyle() to return the same logger, with default style, so that you can pass it on to other function which might expect a logger, if you want that. Or, you could define:

defaultLogger = logging.getLogger(__name__)
logger = logging.getLogger(__name__, style='{')

at the beginning of the file, and then use logger in the file, and pass defaultLogger on.

There are so many options to address your concerns.

> I don't see how it's "really cumbersome". A simple approach is outlined in

Simple approach by everywhere in my code having to use __ now? So I have _ for string translations, and __ for logging. This is cumbersome. Because it could be solved by having it only once in the file. Not that I have to call it manually everywhere in the file.

> which is also described in the documentation here:

Yes, I have read it, used it, didn't like it. So I thought about it and it feels pretty easy to provide a capacity to have a default style applied to the whole file. Instead of manually having to call __. It would effectively be the same internally. Just cleaner code. Do not repeat yourself. Repeating __ everywhere is repeating myself a lot. I would like this style. Let this be specified only once.
msg299376 - (view) Author: Vinay Sajip (vinay.sajip) * (Python committer) Date: 2017-07-28 08:30
> Which third-party libraries?

> It is my code in my file.

If a feature is added to logging, anyone can use it. If people put style-specific loggers in libraries they write, and other people then use those libraries, then there may be a need for them to worry about which style the library loggers use. Perhaps you don't log to loggers in other people's modules, but it's something which is allowed in logging, and useful in some scenarios.

> Yes, I have read it, used it, didn't like it.

These things are matters of opinion and taste. It doesn't seem cumbersome to me, but it seems cumbersome to you. Well, you can subclass Logger to add the new functionality and use it in your code. Why don't you try doing that?
msg302872 - (view) Author: Steven Warwick (sdwarwick) Date: 2017-09-24 17:34
you probably have already considered this, but I just wanted to ask if it might be worth considering turning the problem "upside down" to make things easier.

  I'm interpreting the problem that there are variables we'd like to add to the output log that are provided inside the logger, which is why we need to use a specific type of format string to make sure you add them correctly.   If instead, these same variables are simply exposed as logger attributes, we could just create the complete formatted string when we call the logger.  

logger.info( " {:s} {:s} ", logger.name, logger.module ) 

does this make any sense?
msg302883 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-09-24 19:36
[Vinay Sajip]
> I don't think the ways of doing this are bulletproof and 
> require too much cooperation between third-party libraries.

I concur with all of Vinay's comments.  

If logging were being redesigned from scratch, it would likely use new-style formatting everywhere.  But, it is already deployed and widely adopted.  Trying to make it support two-ways-to-do-it would likely create more problems than it solves.

Vinay, do you want to reject and close this proposal?
msg302888 - (view) Author: Steven Warwick (sdwarwick) Date: 2017-09-24 22:14
sorry, I meant the following:

logger.info( " {:s} {:s} ".format(logger.name, logger.module ) )

or 

logger.info( f" {logger.name:s} {logger.module:s} " ) 

this could be supported with full backward compatibility with very little effort.   

Am I missing something?
msg302907 - (view) Author: Raymond Hettinger (rhettinger) * (Python committer) Date: 2017-09-25 02:35
> logger.info( f" {logger.name:s} {logger.module:s} " ) 
>
> this could be supported with full backward compatibility 
> with very little effort.   
>
> Am I missing something?

One issue is that some of that data isn't known until the logging.info() call is made. And accessing the data before the call would bypass the internal locks, potentially causing race conditions.

Another issue is that having to use an attribute lookup for every variable isn't fast and doesn't look very nice (making this feature awkward to use when the whole goal is to improve usability).

FWIW, you can already use f-strings for all of your local data.  The logging internal data tends to be already set upsteam in the configuration format (which is only done once):

    # Formatting is only done once so %-formatting isn't problematic
    logging.basicConfig(
        level = logging.INFO,
        format = '%(levelname)-8s | %(asctime)s | %(message)s',
        filename = 'demo.log',
    )

    # In the body of the code, use f-strings for your local data:
    logging.info(f'There are {active_users} in {session_name}')
History
Date User Action Args
2017-09-25 07:36:18vinay.sajipsetstatus: open -> closed
resolution: rejected
stage: resolved
2017-09-25 02:35:23rhettingersetmessages: + msg302907
2017-09-24 22:14:49sdwarwicksetmessages: + msg302888
2017-09-24 19:36:46rhettingersetassignee: vinay.sajip

messages: + msg302883
nosy: + rhettinger
2017-09-24 17:34:27sdwarwicksetnosy: + sdwarwick
messages: + msg302872
2017-07-28 08:30:26vinay.sajipsetmessages: + msg299376
2017-07-27 22:31:53mitarsetmessages: + msg299353
2017-07-27 18:34:23vinay.sajipsetmessages: + msg299334
2017-07-23 12:25:55pitrousetnosy: + vinay.sajip
2017-07-23 01:29:55mitarcreate