Colorlog windows fix (#13929)
* Fix colorlog on windows Modified the way logging is initialized to fix two things. 1. If the import of `colorlog` fails the logs will still be formatted using the expected HASS log format. 2. Ensure that `logging.basicConfig` is called AFTER `colorlog` is imported so that the default handler generated will be writing to the wrapped stream generated when `colorama` is initialized. This allows colored logging to work on Windows. Added support for a `--log-no-color` command line switch in the event that someone just wants to disable colored log output entirely. * Fix line lengths * Switch default value
This commit is contained in:
parent
b589dbf26c
commit
7d43ad6a37
3 changed files with 54 additions and 33 deletions
|
@ -126,6 +126,10 @@ def get_arguments() -> argparse.Namespace:
|
||||||
default=None,
|
default=None,
|
||||||
help='Log file to write to. If not set, CONFIG/home-assistant.log '
|
help='Log file to write to. If not set, CONFIG/home-assistant.log '
|
||||||
'is used')
|
'is used')
|
||||||
|
parser.add_argument(
|
||||||
|
'--log-no-color',
|
||||||
|
action='store_true',
|
||||||
|
help="Disable color logs")
|
||||||
parser.add_argument(
|
parser.add_argument(
|
||||||
'--runner',
|
'--runner',
|
||||||
action='store_true',
|
action='store_true',
|
||||||
|
@ -259,13 +263,14 @@ def setup_and_run_hass(config_dir: str,
|
||||||
hass = bootstrap.from_config_dict(
|
hass = bootstrap.from_config_dict(
|
||||||
config, config_dir=config_dir, verbose=args.verbose,
|
config, config_dir=config_dir, verbose=args.verbose,
|
||||||
skip_pip=args.skip_pip, log_rotate_days=args.log_rotate_days,
|
skip_pip=args.skip_pip, log_rotate_days=args.log_rotate_days,
|
||||||
log_file=args.log_file)
|
log_file=args.log_file, log_no_color=args.log_no_color)
|
||||||
else:
|
else:
|
||||||
config_file = ensure_config_file(config_dir)
|
config_file = ensure_config_file(config_dir)
|
||||||
print('Config directory:', config_dir)
|
print('Config directory:', config_dir)
|
||||||
hass = bootstrap.from_config_file(
|
hass = bootstrap.from_config_file(
|
||||||
config_file, verbose=args.verbose, skip_pip=args.skip_pip,
|
config_file, verbose=args.verbose, skip_pip=args.skip_pip,
|
||||||
log_rotate_days=args.log_rotate_days, log_file=args.log_file)
|
log_rotate_days=args.log_rotate_days, log_file=args.log_file,
|
||||||
|
log_no_color=args.log_no_color)
|
||||||
|
|
||||||
if hass is None:
|
if hass is None:
|
||||||
return None
|
return None
|
||||||
|
|
|
@ -42,7 +42,8 @@ def from_config_dict(config: Dict[str, Any],
|
||||||
verbose: bool = False,
|
verbose: bool = False,
|
||||||
skip_pip: bool = False,
|
skip_pip: bool = False,
|
||||||
log_rotate_days: Any = None,
|
log_rotate_days: Any = None,
|
||||||
log_file: Any = None) \
|
log_file: Any = None,
|
||||||
|
log_no_color: bool = False) \
|
||||||
-> Optional[core.HomeAssistant]:
|
-> Optional[core.HomeAssistant]:
|
||||||
"""Try to configure Home Assistant from a configuration dictionary.
|
"""Try to configure Home Assistant from a configuration dictionary.
|
||||||
|
|
||||||
|
@ -60,7 +61,7 @@ def from_config_dict(config: Dict[str, Any],
|
||||||
hass = hass.loop.run_until_complete(
|
hass = hass.loop.run_until_complete(
|
||||||
async_from_config_dict(
|
async_from_config_dict(
|
||||||
config, hass, config_dir, enable_log, verbose, skip_pip,
|
config, hass, config_dir, enable_log, verbose, skip_pip,
|
||||||
log_rotate_days, log_file)
|
log_rotate_days, log_file, log_no_color)
|
||||||
)
|
)
|
||||||
|
|
||||||
return hass
|
return hass
|
||||||
|
@ -74,7 +75,8 @@ def async_from_config_dict(config: Dict[str, Any],
|
||||||
verbose: bool = False,
|
verbose: bool = False,
|
||||||
skip_pip: bool = False,
|
skip_pip: bool = False,
|
||||||
log_rotate_days: Any = None,
|
log_rotate_days: Any = None,
|
||||||
log_file: Any = None) \
|
log_file: Any = None,
|
||||||
|
log_no_color: bool = False) \
|
||||||
-> Optional[core.HomeAssistant]:
|
-> Optional[core.HomeAssistant]:
|
||||||
"""Try to configure Home Assistant from a configuration dictionary.
|
"""Try to configure Home Assistant from a configuration dictionary.
|
||||||
|
|
||||||
|
@ -84,7 +86,8 @@ def async_from_config_dict(config: Dict[str, Any],
|
||||||
start = time()
|
start = time()
|
||||||
|
|
||||||
if enable_log:
|
if enable_log:
|
||||||
async_enable_logging(hass, verbose, log_rotate_days, log_file)
|
async_enable_logging(hass, verbose, log_rotate_days, log_file,
|
||||||
|
log_no_color)
|
||||||
|
|
||||||
core_config = config.get(core.DOMAIN, {})
|
core_config = config.get(core.DOMAIN, {})
|
||||||
|
|
||||||
|
@ -164,7 +167,8 @@ def from_config_file(config_path: str,
|
||||||
verbose: bool = False,
|
verbose: bool = False,
|
||||||
skip_pip: bool = True,
|
skip_pip: bool = True,
|
||||||
log_rotate_days: Any = None,
|
log_rotate_days: Any = None,
|
||||||
log_file: Any = None):
|
log_file: Any = None,
|
||||||
|
log_no_color: bool = False):
|
||||||
"""Read the configuration file and try to start all the functionality.
|
"""Read the configuration file and try to start all the functionality.
|
||||||
|
|
||||||
Will add functionality to 'hass' parameter if given,
|
Will add functionality to 'hass' parameter if given,
|
||||||
|
@ -176,7 +180,8 @@ def from_config_file(config_path: str,
|
||||||
# run task
|
# run task
|
||||||
hass = hass.loop.run_until_complete(
|
hass = hass.loop.run_until_complete(
|
||||||
async_from_config_file(
|
async_from_config_file(
|
||||||
config_path, hass, verbose, skip_pip, log_rotate_days, log_file)
|
config_path, hass, verbose, skip_pip,
|
||||||
|
log_rotate_days, log_file, log_no_color)
|
||||||
)
|
)
|
||||||
|
|
||||||
return hass
|
return hass
|
||||||
|
@ -188,7 +193,8 @@ def async_from_config_file(config_path: str,
|
||||||
verbose: bool = False,
|
verbose: bool = False,
|
||||||
skip_pip: bool = True,
|
skip_pip: bool = True,
|
||||||
log_rotate_days: Any = None,
|
log_rotate_days: Any = None,
|
||||||
log_file: Any = None):
|
log_file: Any = None,
|
||||||
|
log_no_color: bool = False):
|
||||||
"""Read the configuration file and try to start all the functionality.
|
"""Read the configuration file and try to start all the functionality.
|
||||||
|
|
||||||
Will add functionality to 'hass' parameter.
|
Will add functionality to 'hass' parameter.
|
||||||
|
@ -199,7 +205,8 @@ def async_from_config_file(config_path: str,
|
||||||
hass.config.config_dir = config_dir
|
hass.config.config_dir = config_dir
|
||||||
yield from async_mount_local_lib_path(config_dir, hass.loop)
|
yield from async_mount_local_lib_path(config_dir, hass.loop)
|
||||||
|
|
||||||
async_enable_logging(hass, verbose, log_rotate_days, log_file)
|
async_enable_logging(hass, verbose, log_rotate_days, log_file,
|
||||||
|
log_no_color)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
config_dict = yield from hass.async_add_job(
|
config_dict = yield from hass.async_add_job(
|
||||||
|
@ -216,40 +223,51 @@ def async_from_config_file(config_path: str,
|
||||||
|
|
||||||
|
|
||||||
@core.callback
|
@core.callback
|
||||||
def async_enable_logging(hass: core.HomeAssistant, verbose: bool = False,
|
def async_enable_logging(hass: core.HomeAssistant,
|
||||||
log_rotate_days=None, log_file=None) -> None:
|
verbose: bool = False,
|
||||||
|
log_rotate_days=None,
|
||||||
|
log_file=None,
|
||||||
|
log_no_color: bool = False) -> None:
|
||||||
"""Set up the logging.
|
"""Set up the logging.
|
||||||
|
|
||||||
This method must be run in the event loop.
|
This method must be run in the event loop.
|
||||||
"""
|
"""
|
||||||
logging.basicConfig(level=logging.INFO)
|
|
||||||
fmt = ("%(asctime)s %(levelname)s (%(threadName)s) "
|
fmt = ("%(asctime)s %(levelname)s (%(threadName)s) "
|
||||||
"[%(name)s] %(message)s")
|
"[%(name)s] %(message)s")
|
||||||
colorfmt = "%(log_color)s{}%(reset)s".format(fmt)
|
|
||||||
datefmt = '%Y-%m-%d %H:%M:%S'
|
datefmt = '%Y-%m-%d %H:%M:%S'
|
||||||
|
|
||||||
|
if not log_no_color:
|
||||||
|
try:
|
||||||
|
from colorlog import ColoredFormatter
|
||||||
|
# basicConfig must be called after importing colorlog in order to
|
||||||
|
# ensure that the handlers it sets up wraps the correct streams.
|
||||||
|
logging.basicConfig(level=logging.INFO)
|
||||||
|
|
||||||
|
colorfmt = "%(log_color)s{}%(reset)s".format(fmt)
|
||||||
|
logging.getLogger().handlers[0].setFormatter(ColoredFormatter(
|
||||||
|
colorfmt,
|
||||||
|
datefmt=datefmt,
|
||||||
|
reset=True,
|
||||||
|
log_colors={
|
||||||
|
'DEBUG': 'cyan',
|
||||||
|
'INFO': 'green',
|
||||||
|
'WARNING': 'yellow',
|
||||||
|
'ERROR': 'red',
|
||||||
|
'CRITICAL': 'red',
|
||||||
|
}
|
||||||
|
))
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
# If the above initialization failed for any reason, setup the default
|
||||||
|
# formatting. If the above succeeds, this wil result in a no-op.
|
||||||
|
logging.basicConfig(format=fmt, datefmt=datefmt, level=logging.INFO)
|
||||||
|
|
||||||
# Suppress overly verbose logs from libraries that aren't helpful
|
# Suppress overly verbose logs from libraries that aren't helpful
|
||||||
logging.getLogger('requests').setLevel(logging.WARNING)
|
logging.getLogger('requests').setLevel(logging.WARNING)
|
||||||
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
logging.getLogger('urllib3').setLevel(logging.WARNING)
|
||||||
logging.getLogger('aiohttp.access').setLevel(logging.WARNING)
|
logging.getLogger('aiohttp.access').setLevel(logging.WARNING)
|
||||||
|
|
||||||
try:
|
|
||||||
from colorlog import ColoredFormatter
|
|
||||||
logging.getLogger().handlers[0].setFormatter(ColoredFormatter(
|
|
||||||
colorfmt,
|
|
||||||
datefmt=datefmt,
|
|
||||||
reset=True,
|
|
||||||
log_colors={
|
|
||||||
'DEBUG': 'cyan',
|
|
||||||
'INFO': 'green',
|
|
||||||
'WARNING': 'yellow',
|
|
||||||
'ERROR': 'red',
|
|
||||||
'CRITICAL': 'red',
|
|
||||||
}
|
|
||||||
))
|
|
||||||
except ImportError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
# Log errors to a file if we have write access to file or config dir
|
# Log errors to a file if we have write access to file or config dir
|
||||||
if log_file is None:
|
if log_file is None:
|
||||||
err_log_path = hass.config.path(ERROR_LOG_FILENAME)
|
err_log_path = hass.config.path(ERROR_LOG_FILENAME)
|
||||||
|
|
|
@ -76,8 +76,6 @@ def send_message(sender, password, recipient, use_tls,
|
||||||
"""Initialize the Jabber Bot."""
|
"""Initialize the Jabber Bot."""
|
||||||
super(SendNotificationBot, self).__init__(sender, password)
|
super(SendNotificationBot, self).__init__(sender, password)
|
||||||
|
|
||||||
logging.basicConfig(level=logging.ERROR)
|
|
||||||
|
|
||||||
self.use_tls = use_tls
|
self.use_tls = use_tls
|
||||||
self.use_ipv6 = False
|
self.use_ipv6 = False
|
||||||
self.add_event_handler('failed_auth', self.check_credentials)
|
self.add_event_handler('failed_auth', self.check_credentials)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue