From 3037dd826e5f4ab6e9b89b108d4bd5e87cc3728d Mon Sep 17 00:00:00 2001 From: checktheroads Date: Fri, 3 Jan 2020 03:03:57 -0700 Subject: [PATCH] add logging to file --- hyperglass/configuration/__init__.py | 25 ++++++++++++++++------ hyperglass/configuration/models/general.py | 24 +++++++++++++++++++++ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/hyperglass/configuration/__init__.py b/hyperglass/configuration/__init__.py index 9469e87..33bf364 100644 --- a/hyperglass/configuration/__init__.py +++ b/hyperglass/configuration/__init__.py @@ -14,6 +14,7 @@ from hyperglass.configuration.models import commands as _commands from hyperglass.configuration.models import params as _params from hyperglass.configuration.models import routers as _routers from hyperglass.constants import LOG_HANDLER +from hyperglass.constants import LOG_HANDLER_FILE from hyperglass.constants import LOG_LEVELS from hyperglass.exceptions import ConfigError from hyperglass.exceptions import ConfigInvalid @@ -29,7 +30,7 @@ config_file_devices = working_dir / "devices.yaml" config_file_commands = working_dir / "commands.yaml" -def _set_log_level(debug): +def _set_log_level(debug, log_file=None): """Set log level based on debug state. Arguments: @@ -38,12 +39,24 @@ def _set_log_level(debug): Returns: {bool} -- True """ + stdout_handler = LOG_HANDLER.copy() + file_handler = LOG_HANDLER_FILE.copy() + if debug: log_level = "DEBUG" - LOG_HANDLER["level"] = log_level - log.remove() - log.configure(handlers=[LOG_HANDLER], levels=LOG_LEVELS) - log.debug("Debugging Enabled") + stdout_handler["level"] = log_level + file_handler["level"] = log_level + + if log_file is not None: + file_handler.update({"sink": log_file}) + log_handlers = [stdout_handler, file_handler] + else: + log_handlers = [stdout_handler] + + log.remove() + log.configure(handlers=log_handlers, levels=LOG_LEVELS) + if debug: + log.debug("Debugging enabled") return True @@ -139,7 +152,7 @@ except ValidationError as validation_errors: ) # Re-evaluate debug state after config is validated -_set_log_level(params.general.debug) +_set_log_level(params.general.debug, params.general.log_file) def _build_frontend_networks(): diff --git a/hyperglass/configuration/models/general.py b/hyperglass/configuration/models/general.py index cee50c1..e3ace7c 100644 --- a/hyperglass/configuration/models/general.py +++ b/hyperglass/configuration/models/general.py @@ -1,14 +1,19 @@ """Validate general configuration variables.""" # Standard Library Imports +from datetime import datetime +from pathlib import Path from typing import List +from typing import Optional from typing import Union # Third Party Imports +from pydantic import FilePath from pydantic import IPvAnyAddress from pydantic import StrictBool from pydantic import StrictInt from pydantic import StrictStr +from pydantic import validator # Project Imports from hyperglass.configuration.models._utils import HyperglassModel @@ -27,3 +32,22 @@ class General(HyperglassModel): request_timeout: StrictInt = 30 listen_address: Union[IPvAnyAddress, StrictStr] = "localhost" listen_port: StrictInt = 8001 + log_file: Optional[FilePath] + + @validator("log_file") + def validate_log_file(cls, value): + """Set default logfile location if none is configured. + + Arguments: + value {FilePath} -- Path to log file + + Returns: + {Path} -- Logfile path object + """ + if value is None: + now = datetime.now() + now.isoformat + value = Path( + f'/tmp/hyperglass_{now.strftime(r"%Y%M%d-%H%M%S")}.log' # noqa: S108 + ) + return value