Logging multiple modules/functions with different formats in the simplest way
Question:
I’ve 4 functions:
main.py
Handlers
func1.py
func2.py
func3.py
I want to log every function exceptions with some unique formatting; for example I’ve the below logging
in main.py
import logging
from Handlers.func1 import firstfunc
logging.basicConfig(level=logging.WARNING, filename='./main.log', filemode='a+', encoding='utf-8',
format=f"{' '*50}n %(asctime)s ⚠ #%(levelname)s %(message)s",
datefmt='%Y-%m-%d %H:%M:%S')
def main(param):
try:
mainvar = firstfunc(param)
except Exception as e:
logging.exception(e)
...
I want to have another logging as simple as the above 3-line code like below for each of those functions (func1.py), that saves to the same file (I know that it maybe impossible but I don’t know why!)
import logging
from Handlers.func2 import secondfunc
logging.basicConfig(level=logging.INFO, filename='./main.log', filemode='a+', encoding='utf-8',
format=f"{' '*50}n⚠ #%(levelname)s %(message)s")
def firstfunc(fpar):
try:
firstvar = secondfunc(sfunc)
except Exception as e:
logging.exception(e)
...
is this possible to do so as simple as calling logging.basicConfig
?
if not, how can I write the logger
to do the same?
Final output should be like this:
Answers:
Instantiating from basicConfig
is not as simple as
loggerFunc1 = logging.basicConfig(level=logging.WARNING)...
However it’s possible to log by defining fh
as FileHandler
and passing it as a list’s element to the handlers
function like the following:
func1.py
# Should be added to each file (include main.py).
import logging
from pathlib import Path
# Gets the Absolute path of the main.log
LogFileAPath = Path('./main.log').resolve()
fh = logging.FileHandler(LogFileAPath, encoding='utf-8')
logging.basicConfig(
level=logging.INFO,
format=f"n{' '*50}n%(asctime)s ⚠ #%(levelname)s %(message)s",
datefmt='%Y-%m-%d %H:%M:%S',
handlers=[fh]
)
# use __name__ to automatically detect the module name, or any optional string.
logger = logging.getLogger(__name__)
# Stop getting duplicate logs from both functions
logger.propagate = False
#
def firstfunc(fpar):
try:
firstvar = secondfunc(sfunc)
except Exception as e:
logger.exception(e)
...
Or you should add logger in each file using only one basicConfig
in main.py…
main.py
import logging
logging.basicConfig(
level=logging.WARNING,
filename='./main.log',
filemode='a+',
encoding='utf-8',
format=f"n{' '*50}n %(asctime)s ⚠ #%(levelname)s %(message)s",
datefmt='%Y-%m-%d %H:%M:%S')
func1.py
# Should be added to each function file.
import logging
from pathlib import Path
# Gets the Absolute path of the main.log
LogFileAPath = Path('./main.log').resolve()
fh = logging.FileHandler(LogFileAPath, encoding='utf-8')
fh.setLevel(logging.INFO)
formatter = logging.Formatter(f"{' '*50}n⚠ #%(levelname)s %(message)s")
fh.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.addHandler(fh)
# Prevents getting duplicate logs
logger.propagate = False
#
def firstfunc(fpar):
try:
firstvar = secondfunc(sfunc)
except Exception as e:
logger.exception(e)
...
func2.py
import logging
from pathlib import Path
LogFileAPath = Path('./main.log').resolve()
fh = logging.FileHandler(LogFileAPath, encoding='utf-8')
fh.setLevel(logging.INFO)
formatter = logging.Formatter(f"{' '*50}n⚠ #%(levelname)s %(message)s")
fh.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.addHandler(fh)
logger.propagate = False
def secondfunc(spar):
try:
secondvar = thirdfunc(tfunc)
except Exception as e:
logger.exception(e)
...
⋮
⚠
Pay attention to the file directory, if your main.py
is outside of the Handlers
folder, you should use ./main.log
in FileHandler, if you’re defining the log file inside the Handlers
folder, you should use ../main.log
, (⭐: use Path().resolve()
). otherwise you’ll have two separate log files in two different directories.
I’ve 4 functions:
main.py
Handlers
func1.py
func2.py
func3.py
I want to log every function exceptions with some unique formatting; for example I’ve the below logging
in main.py
import logging
from Handlers.func1 import firstfunc
logging.basicConfig(level=logging.WARNING, filename='./main.log', filemode='a+', encoding='utf-8',
format=f"{' '*50}n %(asctime)s ⚠ #%(levelname)s %(message)s",
datefmt='%Y-%m-%d %H:%M:%S')
def main(param):
try:
mainvar = firstfunc(param)
except Exception as e:
logging.exception(e)
...
I want to have another logging as simple as the above 3-line code like below for each of those functions (func1.py), that saves to the same file (I know that it maybe impossible but I don’t know why!)
import logging
from Handlers.func2 import secondfunc
logging.basicConfig(level=logging.INFO, filename='./main.log', filemode='a+', encoding='utf-8',
format=f"{' '*50}n⚠ #%(levelname)s %(message)s")
def firstfunc(fpar):
try:
firstvar = secondfunc(sfunc)
except Exception as e:
logging.exception(e)
...
is this possible to do so as simple as calling logging.basicConfig
?
if not, how can I write the logger
to do the same?
Final output should be like this:
Instantiating from basicConfig
is not as simple as
loggerFunc1 = logging.basicConfig(level=logging.WARNING)...
However it’s possible to log by defining fh
as FileHandler
and passing it as a list’s element to the handlers
function like the following:
func1.py
# Should be added to each file (include main.py).
import logging
from pathlib import Path
# Gets the Absolute path of the main.log
LogFileAPath = Path('./main.log').resolve()
fh = logging.FileHandler(LogFileAPath, encoding='utf-8')
logging.basicConfig(
level=logging.INFO,
format=f"n{' '*50}n%(asctime)s ⚠ #%(levelname)s %(message)s",
datefmt='%Y-%m-%d %H:%M:%S',
handlers=[fh]
)
# use __name__ to automatically detect the module name, or any optional string.
logger = logging.getLogger(__name__)
# Stop getting duplicate logs from both functions
logger.propagate = False
#
def firstfunc(fpar):
try:
firstvar = secondfunc(sfunc)
except Exception as e:
logger.exception(e)
...
Or you should add logger in each file using only one basicConfig
in main.py…
main.py
import logging
logging.basicConfig(
level=logging.WARNING,
filename='./main.log',
filemode='a+',
encoding='utf-8',
format=f"n{' '*50}n %(asctime)s ⚠ #%(levelname)s %(message)s",
datefmt='%Y-%m-%d %H:%M:%S')
func1.py
# Should be added to each function file.
import logging
from pathlib import Path
# Gets the Absolute path of the main.log
LogFileAPath = Path('./main.log').resolve()
fh = logging.FileHandler(LogFileAPath, encoding='utf-8')
fh.setLevel(logging.INFO)
formatter = logging.Formatter(f"{' '*50}n⚠ #%(levelname)s %(message)s")
fh.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.addHandler(fh)
# Prevents getting duplicate logs
logger.propagate = False
#
def firstfunc(fpar):
try:
firstvar = secondfunc(sfunc)
except Exception as e:
logger.exception(e)
...
func2.py
import logging
from pathlib import Path
LogFileAPath = Path('./main.log').resolve()
fh = logging.FileHandler(LogFileAPath, encoding='utf-8')
fh.setLevel(logging.INFO)
formatter = logging.Formatter(f"{' '*50}n⚠ #%(levelname)s %(message)s")
fh.setFormatter(formatter)
logger = logging.getLogger(__name__)
logger.addHandler(fh)
logger.propagate = False
def secondfunc(spar):
try:
secondvar = thirdfunc(tfunc)
except Exception as e:
logger.exception(e)
...
⋮
⚠
Pay attention to the file directory, if your main.py
is outside of the Handlers
folder, you should use ./main.log
in FileHandler, if you’re defining the log file inside the Handlers
folder, you should use ../main.log
, (⭐: use Path().resolve()
). otherwise you’ll have two separate log files in two different directories.