I'm using python logging and I have a formatter that looks like the following:
formatter = logging.Formatter(
'%(asctime)s - %(pathname)86s - %(lineno)4s - %(message)s', '%d %H:%M'
)
As you can see, I like the information in my log files to line up neatly in columns. The reason I have 86 spaces reserved for the pathname is because the full paths to some of the files used in my program are that long. However, all I really need is the actual file name, not the full path. How can I get the logging module to give me just the file name? Better yet, since I have some long filenames, I'd like the first 3 characters of the filename, followed by '~', then the last 16 characters. So
/Users/Jon/important_dir/dev/my_project/latest/testing-tools/test_read_only_scenarios_happily.py
should become
tes~arios_happily.py
getLogger(name) is typically executed. The getLogger() function accepts a single argument - the logger's name. It returns a reference to a logger instance with the specified name if provided, or root if not. Multiple calls to getLogger() with the same name will return a reference to the same logger object.
To log an exception in Python we can use logging module and through that we can log the error. Logging an exception in python with an error can be done in the logging. exception() method. This function logs a message with level ERROR on this logger.
You can set a different logging level for each logging handler but it seems you will have to set the logger's level to the "lowest". In the example below I set the logger to DEBUG, the stream handler to INFO and the TimedRotatingFileHandler to DEBUG. So the file has DEBUG entries and the stream outputs only INFO.
You'll have to implement your own Formatter subclass that truncates the path for you; the formatting string cannot do this:
import logging
import os
class PathTruncatingFormatter(logging.Formatter):
def format(self, record):
if isinstance(record.args, dict) and 'pathname' in record.args:
# truncate the pathname
filename = os.path.basename(record.args['pathname'])
if len(filename) > 20:
filename = '{}~{}'.format(filename[:3], filename[-16:])
record.args['pathname'] = filename
return super(PathTruncatingFormatter, self).format(record)
Use this class instead of the normal logging.Formatter
instance:
formatter = logging.PathTruncatingFormatter(
'%(asctime)s - %(pathname)86s - %(lineno)4s - %(message)s', '%d %H:%M'
)
Like this:
import os
def shorten_filename(filename):
f = os.path.split(filename)[1]
return "%s~%s" % (f[:3], f[-16:]) if len(f) > 19 else f
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With