Reputation: 9636
Following are the contents of mylogger.py
:
def get_logger(name='my_super_logger'):
log = logging.getLogger(name)
log.setLevel(logging.DEBUG)
formatter = logging.Formatter(fmt='%(asctime)s %(name)s %(message)s',
datefmt='%m/%d/%Y %I:%M:%S %p')
if not len(log.handlers):
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
ch.setFormatter(formatter)
log.addHandler(ch)
# print(id(log))
return log
and following is contents of myscript.py
:
from mylogger import get_logger
_logger = get_logger()
_logger.info('trying info')
_logger.debug('trying debug')
However I am facing two issues. It prints the logs twice and formatter is not working everytime:
09/18/2015 09:59:54 PM my_super_logger trying info
INFO:my_super_logger:trying info
09/18/2015 09:59:54 PM my_super_logger trying debug
DEBUG:my_super_logger:trying debug
What exactly is the issue with my get_logger
code?
I need a custom formatting. However I found out that without adding a handler I cannot add a formatter
. So that's why I have added StreamHandler
. And the reason for if
block is mentioned in this answer. Without that, I would get duplicate log messages printed.
Upvotes: 6
Views: 7466
Reputation: 1233
In my case of a custom handler, I had to call format
manually.
I create a handler here
logger_config = {
"version": 1,
"disable_existing_loggers": False,
"formatters": {
"standard": {"format": "%(asctime)s [%(levelname)s] %(name)s: %(message)s"},
},
"handlers": {
"sns": {
"formatter": "standard",
"class": "app_logging.SnsHandler.SnsHandler",
"log_level": os.environ.get("SNS_LOG_LEVEL") or "WARNING",
"topic_arn": os.environ.get("SNS_LOG_TOPIC") or "hghghjg",
}
},
"level": os.environ.get("LOG_LEVEL") or "DEBUG",
# Root logger
"loggers": {
"": {
"formatter": "standard",
"handlers": ["sns"],
"level": os.environ.get("LOG_LEVEL") or "DEBUG",
},
},
}
dictConfig(logger_config)
My handler class is here
from logging import Handler
import boto3
class SnsHandler(Handler):
def __init__(self, log_level, topic_arn: str, region: str = "us-east-1") -> None:
super().__init__(log_level)
self.topic_arn = topic_arn
self._sns_client = boto3.client("sns", region_name=region)
def emit(self, record):
msg = self.format(record)
return self._sns_client.publish(
TopicArn=self.topic_arn, Message=msg, Subject="Logging from the application"
)
Note the call msg = self.format(record)
in emit
. The built-in handlers do this too.
Upvotes: 0
Reputation: 1122342
The root logger is also emitting the message. Stop propagation up to the root with:
log.propagate = False
If you wanted to format all log output (so messages propagated up to the logger), set the formatter for the root logger.
You can do so with a logging.basicConfig()
call provided nothing has yet been sent to the loggers, or by looping over the logger.handlers
list of the root logger; you could pick out any StreamHandlers
if you so wish:
root_logger = logging.getLogger() # no name
for handler in root_logger.handlers:
if isinstance(handler, logging.Streamhandler):
handler.setFormatter(formatter)
Upvotes: 6