The issue is present for me too but it isn't due to changes in Autobahn, it's the txaio module that autobahn uses. When txaio creates a wrapper around the std lib logger module, it uses the root logger for everything and doesn't currently allow to specify a name for the logger so that it isn't created as root.
If you use std lib logging before OR after it looks like even though the docs state otherwise, AND your logging level is below the level you have set txaio's logger to (since it's the root logger, the log level you set get overwritten, and txaio uses info as default) then you either will see duplicate messages or none at all.
Naming your logger (and thus making it non-root), doesn't seem to do the trick unfortunately as I tried that too. Maybe I don't understand fully from the txaio docs but I have been trying to find a way to not have dup logging but I can't.
Trying to work my way around this too... I think I'll open a ticket on GitHub under txaio to see if we can have something like the below added:
# Name would allow for _TxaioLogWrapper to not call std lib logging.getLogger with no name thus defaulting to root logging instance
def make_logger(name=None):
logger = _TxaioLogWrapper(logging.getLogger(name))
# remember this so we can set their levels properly once
# start_logging is actually called
_loggers.add(logger)
return logger
def start_logging(name=None, out=_stdout, level='info'):
"""
Begin logging.
:param out: if provided, a file-like object to log to. By default, this is
stdout.
:param level: the maximum log-level to emit (a string)
"""
global _log_level, _loggers, _started_logging ****** I tried setting log level to "none" and that passes this test but isn't implemented and throws another error
if level not in log_levels:
raise RuntimeError(
"Invalid log level '{0}'; valid are: {1}".format(
level, ', '.join(log_levels)
)
)
if _started_logging:
return
_started_logging = True
_log_level = level
handler = _TxaioFileHandler(out)
logging.getLogger(name).addHandler(handler) ****** Name here too so that root logger isn't used
# note: Don't need to call basicConfig() or similar, because we've
# now added at least one handler to the root logger
logging.raiseExceptions = True # FIXME
level_to_stdlib = {
'critical': logging.CRITICAL,
'error': logging.ERROR,
'warn': logging.WARNING,
'info': logging.INFO,
'debug': logging.DEBUG,
'trace': logging.DEBUG,
}
logging.getLogger(name).setLevel(level_to_stdlib[level]) ****** Name here too so that root logger isn't used
# make sure any loggers we created before now have their log-level
# set (any created after now will get it from _log_level
for logger in _loggers:
logger._set_log_level(level)