It is difficult to put what I need in a sentence but the code below pretty much explains it:
I have my logging class in a separate file (log_file) as below, and a logger object defined there:
from io import StringIO
import logging
class NetddLog():
def __init__(self, name, format="%(asctime)s %(levelname)s %(message)s", level=logging.INFO):
self.name = name
self.level = level
self.format = format
#Logger configuration.
self.formatter = logging.Formatter(self.format)
self.logger = logging.getLogger(name)#name
self.logger.setLevel(self.level)
#Logging to memory
self.log_capture_string = StringIO()
self.ch_logger = logging.StreamHandler(self.log_capture_string)
self.ch_logger.setFormatter(self.formatter)
self.logger.addHandler(self.ch_logger)
def debug(self, msg, extra=None):
self.logger.debug(msg, extra=extra)
ip_logger = NetddLog("IP_LOG")
In another file (ip_file), I have my ping function as below:
from log_file import ip_logger
from icmplib import ping
def ping_ip(ip_num, ip):
try:
ip_logger.info(f"{ip_num}: Pinging {ip} started")
host = ping(ip, count=4, interval=1, timeout=2, payload_size=64, privileged=True)
if host.is_alive:
ip_logger.info(f"{ip_num}: Pinging {ip} succeded")
else:
raise Exception
except Exception as err:
ip_logger.error(f"{ip_num}: Pinging {ip} failed {err}")
The ip_num is the number of the IP address(ip) in a IP addr list, in another file (main_file), from which I call ping_ip(ip_num, ip)
The log messages prints just fine, but I'm putting ip_num inside the actual log message, each time. What I want to do is, having included in the format of the logger when the logger is created in the class, and probably just call the function with ping_ip(ip)
So the format in the init class method will look something like this: format=f"%(asctime)s %(levelname)s {ip_num}: %(message)s"
, this way I don't have to include ip_num inside every log message I create. Is there a way to achieve this within the current class configuration or an alternative way? (I want to keep things separated as much as possible and not put everything in the main_file)
Update: Based on a previous answer I just redefined the logging methods inside the class to add an extra parameter in the format. For instance info function would change like below, and %(ip_num)s can be added to the format.
def info(self, ip_num, msg):
self.d = {'ip_num': f"{ip_num}"}
self.logger.info(msg, extra=self.d)
CodePudding user response:
Yes, you can achieve what you want, actually is well documented under: https://docs.python.org/3/howto/logging.html
There is a parameter where you can provide a dictionary with additional values to your log format.
Below you can find the snippet which does the job:
import logging
def config_log(FORMAT = '%(asctime)s %(levelname)s IP:%(ip_num)s %(message)s'):
logging.basicConfig(filename='example.log', encoding='utf-8',format=FORMAT, level=logging.INFO)
def log_something(ipnum, mymessage):
d = {'ip_num': f"{ipnum}"}
logging.info(mymessage, extra=d)
if __name__ == "__main__":
config_log()
log_something("127.0.0.1",'Here is your message log')