Add TRACE log level to Python ...?

In a nutshell: Let's stop

Please read the following as a story.

What kind of request is that in the first place?

log4j (http://ja.wikipedia.org/wiki/Log4j) has a level called TRACE under DEBUG. I think this is an ant function.

For example, at the beginning and end of a function, "started!" And "finished!" If you write in TRACE log level, or `` LOG.trace () `, etc., and write the middle process in DEBUG It's like being able to define multiple stages like -vv (in the case of ssh) for -v at a slightly more meaningful level. When a bug comes, grass is inevitable.

During development, there are cases where it would be nice to know at the log level "which function worked to the end". It's not always possible to run the debugger in the whole story, and somehow I use "printf debug". help.

Setting something like TRACE seems to be "nothing you can't do"

Python log levels are numbers in the first place, and DEBUG, INFO, etc. are actually mapped to numbers.

https://docs.python.org/3.4/library/logging.html#logging-levels

For example, when spitting a log, write as follows

logging.debug ('shouldn't be written this way') logging.log (logging.DEBUG,'So!')

(Actually, you can use Logger)

Since logging.DEBUG is simply 10, the above notation effectively represents the output at the same log level as the following notation.

logging.log (10,'Nmo!')

NOTSET (0) is a bit special, so let's put it aside, and even if you use numbers from 1 to 9, the log function won't complain. On the contrary, DEBUG and INFO are simply treated as aliases to numbers.

As we will see later, some mechanisms currently only accept numbers (eg `logging.log (lvl, msg)` lvl is a number and does not accept'DEBUG' etc. )

So, if you specify a number such as 5 and write `logging.log (5,'wafu')` `, etc., you can write` `setLevel (logging.DEBUG)` Logger. Will not be displayed.

If you do something like TRACE by specifying numerical values, it will look like the following.

from logging import getLogger, StreamHandler, DEBUG
logger = getLogger(__name__)
handler = StreamHandler()
logger.setLevel(DEBUG)
handler.setLevel(DEBUG)
logger.addHandler(handler)

logger.log (5,'I'll start') .. logger.debug ('This is big') .. logger.log (5,'It's over')

In the above example, "Start" and "End" are not displayed. It's just "This is big". As a way to put debug logs that are really only valuable to developers Personally, I don't think it's terrible. Or rather convenient.

I also want logging.trace () and logger.trace ()!

Here, logging has a feature called ```addLevelName ()` ``. (https://docs.python.org/3.4/library/logging.html#logging.addLevelName)

Oh, this is `logger.trace ()`

Not made :-)

logging.trace()And logger.trace()Is not made, let alone logging.log('TRACE', 'Hello')I can't do it. Logging in the first place.log('INFO', 'Let's paste')Not even allowed.



 # You can specify something like ``` logger.setLevel ('INFO')` `` (to be exact, it seems to be only the latest version after 3.2. For some reason, it also includes 2.7). It is also possible to specify ``` --log = DEBUG``` with argparse and directly insert it into `` `setLevel ()` `.

 Probably, this is just a function that `` `Formatter``` displays" TRACE "instead of" Level 5 ", isn't it?

 (like ipython)
    > import logging
    > logger = logging.getLogger('test')
    > logger.setLevel(1)
    > handler = logging.StreamHandler()
    > handler.setLevel(1)
    > formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
    > handler.setFormatter(formatter)
    > logger.addHandler(handler)
    >  logger.debug('hello')
    2014-05-01 11:02:12,743 - DEBUG - hello
    > logger.log(5, 'hoge')
    2014-05-01 11:02:20,599 - Level 5 - hoge
    > logging.addLevelName(5, 'TRACE')
    > logger.log(5, 'hoge')
    2014-05-01 11:02:43,173 - TRACE - hoge

 To be precise, if you mess with the contents of Murikuri logging, you may be able to add `` `logging.trace ()` `` etc. It's Python.

 However, it doesn't exist as a nice and safe implementation by default, and I don't think it's going in that direction in the future.

 Even if I could do it, I can see that it's just super troublesome.
 It can't be said that the logger received by each function or the like always has it. Especially if it is provided as a library, it is visible that loggers who do not know trace come from the outside.
 Sometimes I have a trace or I don't have it, so I wonder if I use it while checking with getattr.
 Convenience is not fine.

# In the first place, the official says something like "don't do it".

https://docs.python.org/2/howto/logging.html#custom-levels

> Defining your own levels is possible, but should not be necessary, as the existing levels have been chosen on the basis of practical experience. However, if you are convinced that you need custom levels, great care should be exercised when doing this, and it is possibly a very bad idea to define custom levels if you are developing a library. That’s because if multiple library authors all define their own custom levels, there is a chance that the logging output from such multiple libraries used together will be difficult for the using developer to control and/or interpret, because a given numeric value might mean different things for different libraries.

https://docs.python.org/3.2/howto/logging.html#custom-levels

> Defining your own levels is possible, but should not be necessary, as the existing levels have been chosen on the basis of practical experience. However, if you are convinced that you need custom levels, great care should be exercised when doing this, and it is possibly a very bad idea to define custom levels if you are developing a library. That’s because if multiple library authors all define their own custom levels, there is a chance that the logging output from such multiple libraries used together will be difficult for the using developer to control and/or interpret, because a given numeric value might mean different things for different libraries.

https://docs.python.org/3.4/howto/logging.html#custom-levels

> Defining your own levels is possible, but should not be necessary, as the existing levels have been chosen on the basis of practical experience. However, if you are convinced that you need custom levels, great care should be exercised when doing this, and it is possibly a very bad idea to define custom levels if you are developing a library. That’s because if multiple library authors all define their own custom levels, there is a chance that the logging output from such multiple libraries used together will be difficult for the using developer to control and/or interpret, because a given numeric value might mean different things for different libraries.

# Conclusion

 Let's stop

 As a "debug" log for bugs that developers just don't understand, prepare one specific handler that spits out a super verbose log, set only that handler to log level 1, and the others are muddy with DEBUG. Is it enough to deal with such multi-steps?

 At the very end of my insistence on "let's stop", I was convinced that "Oh, then I can't forgive", and that's it.


Recommended Posts

Add TRACE log level to Python ...?
Try to calculate Trace in Python
How to change the log level of Azure SDK for Python
Output Python log to console with GAE
Log in to Slack using requests in Python
[Python] Add total rows to Pandas DataFrame
Add Gaussian noise to images with python2.7
How to add python module to anaconda environment
Add a Python virtual environment to VSCode
[Python] Add comments to standard input files
Updated to Python 2.7.9
"Backport" to python 2
Just add the python array to the json data
Add diagonal lines (hatch) to heatmap (python, matplotlib)
How to add a Python module search path
Output python log to both console and file
Speed: Add element to end of Python array
[CentOS8] How to output Python standard output to systemd log
[Python] [Django] How to use ChoiceField and how to add options
How to add help to HDA (with Python script bonus)
Changes from Python 3.0 to Python 3.5
How to install python
python decorator to retry
Introduction to Python language
Note to daemonize python
How to add page numbers to PDF files (in Python)
Introducing Python 2.7 to CentOS 6.6
Connect python to mysql
[Python MinMaxScaler] Normalize to 0 ~ 1
Python logging standard library for file output by log level
[GCP] How to output Cloud Functions log to Cloud Logging (Stackdriver Logging) (Python)
How to log in to AtCoder with Python and submit automatically
Connect to BigQuery with Python
[2020.8 latest] How to install Python
[python] Convert date to string
Post from Python to Slack
How to install Python [Windows]
Post to vim → Python → Slack
Introduction to Python Django (2) Win
To flush stdout in Python
Convert numpy int64 to python int
python3: How to use bottle (2)
Add / remove kernel to JupyterLab
[Python] Convert list to Pandas [Pandas]
Cheating from PHP to Python
A road to intermediate Python
Try to understand Python self
Python notes to forget soon
[Python] How to use list 1
Add a dictionary to MeCab
Login to website in Python
Connect to Wikipedia with Python
How to update Python Tkinter to 8.6
Post to slack with Python 3
Add page number to PDF
Anaconda updated from 4.2.0 to 4.3.0 (python3.5 updated to python3.6)
Sound pressure level FFT (Python)
Post to Twitter using Python
How to use Python argparse
Start to Selenium using python
Introduction to serial communication [Python]