How to setup python.logging format using f-string style - python-3.x

I'm writing an app using python 3.7 and want to use only f-strings in it.
I'm using python logging module in order to log my application correctly, and I want to use a specific format but the documentation (and the web) only example how to change the format using %-strings.
I was wondering whether there is an option to set the logger format using f-strings
LOG_FORAMT = ('%(levelname)s -10s %(asctime)s -10s %(message)s') # Known example
f-LOG_FORMAT = (f'{logger.levelname} -10s') # Something like that?

You can initialize logging.Formatter with argument style set to "{".
Example
formatter = logging.Formatter("{processName:<12} {message} ({filename}:{lineno})", style="{")
Available options for style are documented.
After this attach the formatter to a handler and add the handler to your desired logger(s).
If you are using logging.basicConfig you can set it with the following way:
logging.basicConfig(format="{processName:<12} {message} ({filename}:{lineno})", style="{")

Related

Getting rid of print "<IPython.core.display.Markdown object>" when using `display`

I'm trying to create nice slides using jupyter notebook and RISE. One of my objectives is to display a pandas-dataframe in a Markdown cell in order to have some styling flexibility.
I am using the following code to display my dataframe in a Markdown cell:
{{Markdown(display(df_x))}}
After running this line, I get the following result:
image of dataframe displayed
I would like to get rid of the text printed below my dataframe (<IPython.core.display.Markdown object>).
I still haven't found a way to achieve this. Could someone give me a hand?
This is the library I'm working with:
from IPython.display import display
Not familiar with Markdown class so not sure why you need that but this text printed in the output cell is coming from the fact that this Markdown class is returning and object and since you're not assigning it to any variable the default behavior for the notebook is to run something like str(your_object) which correctly returns <IPython.core.display.Markdown object>.
So the easiest workaround would be to just assign it to some variable like this:
dummy_var = Markdown(display(df_x))
# or better yet:
_ = Markdown(display(df_x))

Python logging; [1] cannot set log file dirpath; and [2] datetime formatting problems

I am trying to learn how to use the logging module.
I want to log information to both console and to file.
I confess that I have not completed studying both https://docs.python.org/3/library/logging.html#logging.basicConfig and https://docs.python.org/3/howto/logging.html
It's a little daunting for a novice like me to learn all of it, but I am working on it.
I am trying to use a modified version of the “Logging to multiple destinations” program from https://docs.python.org/3/howto/logging-cookbook.html, to which I refer as “Cookbook_Code”.
The Cookbook_Code appears at that URL under the title "Logging to multiple destinations".
But I have two problems:
The Cookbook Code saves to a file named:
"E:\Zmani\Logging\Logging_to_multiple_destinations_python.org_aaa.py.txt",
and I cannot figure out:
A. Why the Cookbook Code does that, nor
B. How to make the logging module save instead to a the following filepath (which I stored in a var, "logfile_fullname"): "e:\zmani\Logging\2020-10-14_14_14_os.walk_script.log"
I cannot figure out how to have the log file use the following datetime format:
"YYYY-MM-DD_HH-MM-SS - INFO: Sample info."
instead of the following datetime format: "10/14/2020 03:00:22 PM - INFO: Sample info."
I would like the console output include the same datetime prefix:
"YYYY-MM-DD_HH-MM-SS -"
Any suggestions would be much appreciated.
Thank you,
Marc
Here’s the code I have been running:
log_file_fullname = "e:\zmani\Logging\2020-10-14_14_14_os.walk_script.log"
# https://docs.python.org/3/howto/logging-cookbook.html#logging-cookbook
import logging
# set up logging to file - see previous section for more details
logging.basicConfig(level=logging.DEBUG,
format='%(asctime)s %(name)-12s %(levelname)-8s %(message)s',
datefmt='%Y-%m-%d_%H-%M-%S',
filename=log_file_fullname,
filemode='w')
console = logging.StreamHandler()
console.setLevel(logging.INFO)
formatter = logging.Formatter('%(name)-12s: %(levelname)-8s %(message)s')
console.setFormatter(formatter)
logging.getLogger('').addHandler(console)
logging.info('Sample info.')
logger1 = logging.getLogger('myapp.area1')
logger2 = logging.getLogger('myapp.area2')
logger1.debug('Quick zephyrs blow, vexing daft Jim.')
logger1.info('How quickly daft jumping zebras vex.')
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')
A quick run of your code showed that it already does 1.B and 2 of your problems.
Your provided URLs showed nowhere that Logging_to_multiple_destinations_python.org_aaa.py.txt is being used. It doesn't matter anyway. It just a path to a text file provided that its parent folders exist. So 1.A is just merely a demonstration.
If you add %(asctime)s to the console's formatter, it will give you 3.
formatter = logging.Formatter('%(asctime)s %(name)-12s: %(levelname)-8s %(message)s', datefmt='%Y-%m-%d_%H-%M-%S')
You should only use basicConfig if you don't need to add any logger nor doing a complicated setup.
basicConfig will only have an effect if there aren't any handler in the root logger. If you use filename argument, it creates a FileHandler. If you use stream argument, it creates a StreamHandler. And you cannot use both arguments at once.
So you said that you need to output to file and console, just create a handler for each of them.
import logging
log_file_fullname = "2020-10-14_14_14_os.walk_script.log"
# config file handler
file_handler = logging.FileHandler(log_file_fullname)
file_handler.setLevel(logging.DEBUG)
fmt_1 = logging.Formatter('%(asctime)s %(name)-12s: %(levelname)-8s %(message)s',
datefmt='%Y-%m-%d_%H-%M-%S')
file_handler.setFormatter(fmt_1)
# config console handler
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.INFO)
fmt_2 = fmt_1 # you could add console only formatter here
console_handler.setFormatter(fmt_2)
# retrieve a root logger and add handlers
root_logger = logging.getLogger()
root_logger.setLevel(logging.NOTSET) # change from default WARNING to NOTSET,
root_logger.addHandler(file_handler) # this allows root_logger to take all propagated
root_logger.addHandler(console_handler) # messages from other child loggers.
# this line use root logger by default
logging.info('Sample info.')
# create module loggers
logger1 = logging.getLogger('myapp.area1')
logger2 = logging.getLogger('myapp.area2')
# logging by module loggers
logger1.debug('Quick zephyrs blow, vexing daft Jim.')
logger1.info('How quickly daft jumping zebras vex.')
logger2.warning('Jail zesty vixen who grabbed pay from quack.')
logger2.error('The five boxing wizards jump quickly.')

debug python code and change variables at runtime in pyCharm

I am using pycharm to 2018.3.4 to develop python scripts and I am still pretty new in this language, I normally write PowerShell code. I have a question concerning debugging. Take this unfinished code as an example.
#! python3
# phoneAndEmail.py - Finds phone numbers and email addresses on the clipboard.
import pyperclip, re, sys
phoneRegex = re.compile(r'''(
(\(?([\d \-\)\–\+\/\(]+)\)?([ .-–\/]?)([\d]+))
)''', re.VERBOSE)
mailRegex = re.compile(r'''(
\w+#\w+\.\w+
)''', re.VERBOSE)
text = pyperclip.paste()
def getMatches(text, regex) :
return regex.findall(text)
Emails = getMatches(text,mailRegex) #I want to play with this variable at runtime
phone = getMatches(text,phoneRegex)
I am at the stage where I want to analyze the variable Emails at runtime. So I set a breakpoint and can view the contents of the varieble just fine. However I also want to run some methods and play with their input parameters at runtime. Does someone know how this is possible? If this is possible with another IDE then this would be fine too.
In Pycharm 2018.3.4 you simply do this by clicking on the console tab and then on the show command prompt button.
Now you can type in Emails or Emails.pop() for example in order to manipulate variables:
You can also refer to this post, where this was discussed for an older version: change variable in Pycharm debugger

Python logging set handlers to different levels

I am trying to set python logger which always writes INFO level to the stdout and at DEBUG level to a file. Something similar to
https://stackoverflow.com/a/11111212/3516550
but without creating anotherlogger object. I tried this, but both of them get the default level of logging.WARNING. Is there someway for me to set both to the original logging object? The rest of the code uses logging, I'd like to preserve that, if possible.
stream_handler = logging.StreamHandler()
stream_handler.setLevel(logging.INFO)
file_handler = logging.FileHandler("my_log.log")
file_handler.setLevel(logging.DEBUG)
logging.basicConfig(handlers=[file_handler, stream_handler])
The python version I am using is
Python 3.6.3 :: Anaconda custom (64-bit)

Handling logs and writing to a file in python?

I have a module name acms and inside that have number of python files.The main.py has calls to other python files.I have added logs in those files, which are displayed on console but i also want to write these logs in a file called all.log, i tried with setting log levels and logger in a file called log.py but didnt get the expected format,since am new to python am getting difficulty in handling logs
Use the logging module and use logger = logging.getLogger(__name__). Then it will use the correct logger with the options that you have set up.
See the thinkpad-scripts project for its logging. Also the logging cookbook has a section for logging to multiple locations.
We use the following to log to the console and the syslog:
kwargs = {}
dev_log = '/dev/log'
if os.path.exists(dev_log):
kwargs['address'] = dev_log
syslog = logging.handlers.SysLogHandler(**kwargs)
syslog.setLevel(logging.DEBUG)
formatter = logging.Formatter(syslog_format)
syslog.setFormatter(formatter)
logging.getLogger('').addHandler(syslog)

Resources