diff --git a/dicogis/cli/cmd_inventory.py b/dicogis/cli/cmd_inventory.py index 751a5708..d3464357 100644 --- a/dicogis/cli/cmd_inventory.py +++ b/dicogis/cli/cmd_inventory.py @@ -16,14 +16,13 @@ from rich import print # project -from dicogis.__about__ import __package_name__, __title__, __version__ +from dicogis.__about__ import __package_name__, __title__ from dicogis.constants import SUPPORTED_FORMATS, AvailableLocales, OutputFormats from dicogis.export.to_json import MetadatasetSerializerJson from dicogis.export.to_xlsx import MetadatasetSerializerXlsx from dicogis.georeaders.process_files import ProcessingFiles from dicogis.georeaders.read_postgis import ReadPostGIS from dicogis.listing.geodata_listing import check_usable_pg_services, find_geodata_files -from dicogis.utils.environment import get_gdal_version, get_proj_version from dicogis.utils.journalizer import LogManager from dicogis.utils.notifier import send_system_notify from dicogis.utils.texts import TextsManager @@ -163,6 +162,8 @@ def inventory( Defaults to None. verbose: enable verbose mode. Defaults to False. """ + app_dir = typer.get_app_dir(app_name=__title__, force_posix=True) + # start logging if verbose: state["verbose"] = True @@ -170,21 +171,15 @@ def inventory( console_level=logging.DEBUG if verbose else logging.WARNING, file_level=logging.DEBUG if verbose else logging.INFO, label=f"{__package_name__}-cli", + folder=Path(app_dir).joinpath("logs"), ) # add headers logmngr.headers() - + logger.debug(f"DicoGIS working folder: {app_dir}") logger.debug( - f"Passed parameters: {input_folder=} - {formats=} - {pg_services=} - " + f"CLI passed parameters: {input_folder=} - {formats=} - {pg_services=} - " f"{verbose=} -{language=}" ) - app_dir = typer.get_app_dir(__title__) - - # log some context information - logger.info(f"DicoGIS version: {__version__}") - logger.debug(f"DicoGIS working folder: {app_dir}") - logger.info(f"GDAL: {get_gdal_version()}") - logger.info(f"PROJ: {get_proj_version()}") # check minimal parameters # note: pg_services defaults to [] not to None @@ -394,3 +389,5 @@ def inventory( if opt_open_output: Utilities.open_dir_file(target=output_path) + + logger.info(f"Logs stored in {Path(app_dir).joinpath('logs')}") diff --git a/dicogis/cli/main.py b/dicogis/cli/main.py index 75fc2408..4b9d3a4c 100644 --- a/dicogis/cli/main.py +++ b/dicogis/cli/main.py @@ -47,7 +47,11 @@ def version_callback(value: bool): def main( verbose: Annotated[ bool, - typer.Option(is_flag=True, help="Increase verbosity to show debug logs."), + typer.Option( + is_flag=True, + help="Increase verbosity to show debug logs.", + envvar="DICOGIS_DEBUG", + ), ] = False, version: Annotated[ Optional[bool], diff --git a/dicogis/ui/main.py b/dicogis/ui/main.py index 97dfddf9..473f65fc 100644 --- a/dicogis/ui/main.py +++ b/dicogis/ui/main.py @@ -17,22 +17,28 @@ # standard library import logging import sys -from logging.handlers import RotatingFileHandler from os import getenv +from pathlib import Path from sys import platform as opersys # GUI from tkinter import TkVersion +# 3rd party +from typer import get_app_dir + # Project +from dicogis.__about__ import __package_name__, __title__ from dicogis.ui.main_windows import DicoGIS +from dicogis.utils.journalizer import LogManager +from dicogis.utils.str2bool import str2bool # ############################################################################## # ############ Globals ############ # ################################# - -logger = logging.getLogger("DicoGIS") +app_dir = get_app_dir(app_name=__title__, force_posix=True) +logger = logging.getLogger(__name__) # ############################################################################## # ############ Functions ########### @@ -42,17 +48,20 @@ def dicogis_gui(): """Launch DicoGIS GUI.""" # LOG - logging.captureWarnings(True) - logger.setLevel(logging.DEBUG) # all errors will be get - log_form = logging.Formatter( - "%(asctime)s || %(levelname)s " - "|| %(module)s - %(lineno)d ||" - " %(funcName)s || %(message)s" + logmngr = LogManager( + console_level=( + logging.DEBUG + if str2bool(getenv("DICOGIS_DEBUG", False)) + else logging.WARNING + ), + file_level=( + logging.DEBUG if str2bool(getenv("DICOGIS_DEBUG", False)) else logging.INFO + ), + label=f"{__package_name__}-gui", + folder=Path(app_dir).joinpath("logs"), ) - logfile = RotatingFileHandler("LOG_DicoGIS.log", "a", 5000000, 1) - logfile.setLevel(logging.DEBUG) - logfile.setFormatter(log_form) - logger.addHandler(logfile) + # add headers + logmngr.headers() # 3rd party # condition import @@ -60,7 +69,7 @@ def dicogis_gui(): import distro # check Tk version - logger.info(f"{TkVersion=}") + logger.info(f"Tk: {TkVersion}") if TkVersion < 8.6: logger.critical("DicoGIS requires Tkversion >= 8.6.") sys.exit(1) diff --git a/dicogis/ui/main_windows.py b/dicogis/ui/main_windows.py index d605893a..19b1ea3e 100644 --- a/dicogis/ui/main_windows.py +++ b/dicogis/ui/main_windows.py @@ -19,7 +19,6 @@ import locale import logging import platform -from logging.handlers import RotatingFileHandler from sys import exit from sys import platform as opersys from time import strftime @@ -52,7 +51,6 @@ from dicogis.listing.geodata_listing import find_geodata_files from dicogis.ui import MiscButtons, TabCredits, TabFiles, TabSettings, TabSGBD from dicogis.utils.checknorris import CheckNorris -from dicogis.utils.environment import get_gdal_version, get_proj_version from dicogis.utils.notifier import send_system_notify from dicogis.utils.options import OptionsManager from dicogis.utils.texts import TextsManager @@ -66,18 +64,8 @@ utils_global = Utilities() # LOG -logger = logging.getLogger("DicoGIS") -logging.captureWarnings(True) -logger.setLevel(logging.DEBUG) # all errors will be get -log_form = logging.Formatter( - "%(asctime)s || %(levelname)s " - "|| %(module)s - %(lineno)d ||" - " %(funcName)s || %(message)s" -) -logfile = RotatingFileHandler("LOG_DicoGIS.log", "a", 5000000, 1) -logfile.setLevel(logging.DEBUG) -logfile.setFormatter(log_form) -logger.addHandler(logfile) +logger = logging.getLogger(__name__) + # ############################################################################## # ############ Classes ############# @@ -88,24 +76,18 @@ class DicoGIS(ThemedTk): """Main DicoGIS GUI object. Args: - ThemedTk (_type_): themed tk object. + ThemedTk: themed tk object. """ # attributes package_about = __about__ def __init__(self, theme: str = "radiance"): - """Main window constructor - Creates 1 frame and 2 labelled subframes""" - logger.info( - "\t============== {} =============".format( - self.package_about.__title_clean__ - ) - ) - logger.info(f"Version: {self.package_about.__version__}") - logger.info(f"GDAL: {get_gdal_version()}") - logger.info(f"PROJ: {get_proj_version()}") + """Main window constructor. + Args: + theme: _description_. Defaults to "radiance". + """ # store vars as attr self.txt_manager = TextsManager() self.dir_imgs = utils_global.resolve_internal_path(internal_path="bin/img") @@ -121,18 +103,12 @@ def __init__(self, theme: str = "radiance"): self.title(f"DicoGIS {self.package_about.__version__}") self.uzer = getpass.getuser() if opersys == "win32": - logger.info(f"Operating system: {platform.platform()}") self.iconbitmap(self.dir_imgs / "DicoGIS.ico") # windows icon elif opersys.startswith("linux"): - logger.info(f"Operating system: {platform.platform()}") icon = Image("photo", file=self.dir_imgs / "DicoGIS_logo.gif") self.call("wm", "iconphoto", self._w, icon) - - elif opersys == "darwin": - logger.info(f"Operating system: {platform.platform()}") else: - logger.warning("Operating system unknown") - logger.info(f"Operating system: {platform.platform()}") + logger.warning(f"Unknown operating system: {platform.platform()}") self.resizable(width=False, height=False) self.focus_force() diff --git a/dicogis/utils/journalizer.py b/dicogis/utils/journalizer.py index de7b391f..e0c6ef4b 100644 --- a/dicogis/utils/journalizer.py +++ b/dicogis/utils/journalizer.py @@ -14,8 +14,6 @@ # Standard library - -import gettext import logging from getpass import getuser from logging.handlers import RotatingFileHandler @@ -30,13 +28,14 @@ # modules from dicogis.__about__ import __title_clean__ as package_name from dicogis.__about__ import __version__ +from dicogis.utils.environment import get_gdal_version, get_proj_version from dicogis.utils.slugger import sluggy # ############################################################################# # ########## Globals ############### # ################################## -_ = gettext.gettext # i18n + logger = logging.getLogger(__name__) # logs @@ -61,7 +60,14 @@ def __init__( label: str = package_name, folder: Optional[Path] = None, ): - """Instanciation method.""" + """Initialize. + + Args: + console_level: log level for console handler. Defaults to logging.WARNING. + file_level: log level for file handler. Defaults to logging.INFO. + label: log file name. Defaults to package_name. + folder: where to store log files. Defaults to None. + """ # store parameters as attributes self.console_level = console_level self.file_level = file_level @@ -72,27 +78,25 @@ def __init__( try: self.folder.mkdir(exist_ok=True, parents=True) except PermissionError as err: - msg_err = _( - "Impossible to create the logs folder. Does the user '{}' ({}) have " - "write permissions on: {}. Trace: {}" - ).format(environ.get("userdomain"), getuser(), self.folder, err) + msg_err = ( + f"Impossible to create the logs folder. Does the user '{getuser}' have " + f"write permissions on: {self.folder}. Trace: {err}" + ) logger.error(msg_err) # create logger self.initial_logger_config() def initial_logger_config(self) -> logging.Logger: - """Configure root logger. \ - BE CAREFUL: it depends a lot of how click implemented logging facilities. \ - So, sadly, every option is not available. + """Configure root logger. - :return: configured logger - :rtype: logging.Logger + Returns: + configured logger """ # create main logger logging.captureWarnings(False) logger = logging.getLogger() - logger.setLevel(self.console_level) + logger.setLevel(logging.INFO) # create console handler - seems to be ignored by click log_console_handler = logging.StreamHandler() @@ -125,12 +129,14 @@ def initial_logger_config(self) -> logging.Logger: return logger def headers(self): - """Basic information to log before other message.""" + """Log basic information before other message.""" # initialize the log - logger.info(f"\t ========== {package_name} - Version {__version__} ==========") - logger.info(_("Operating System: {}").format(opersys())) - logger.info(_("Architecture: {}").format(architecture()[0])) - logger.info(_("Computer: {}").format(gethostname())) - logger.info(_("Launched by: {}").format(getuser())) - logger.info(_("OS Domain: {}").format(environ.get("userdomain"))) - logger.info(_("Network proxies detected: {}").format(len(getproxies()))) + logger.info(f"{'='*10} {package_name} - Version {__version__} {'='*10}") + logger.info(f"Operating System: {opersys()}") + logger.info(f"Architecture: {architecture()[0]}") + logger.info(f"Computer: {gethostname()}") + logger.info(f"Launched by: {getuser()}") + logger.info(f"OS Domain: {environ.get('userdomain')}") + logger.info(f"Network proxies detected: {len(getproxies())}") + logger.info(f"GDAL: {get_gdal_version()}") + logger.info(f"PROJ: {get_proj_version()}")