From 90aad614a45ed58dca73c332b0b8af7f657eee54 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Fri, 29 May 2026 14:26:43 +0200 Subject: [PATCH 01/13] Add working example of environment based time zones --- src/daqpytools/logging/formatter.py | 5 ++++- src/daqpytools/utils/config_loader.py | 30 ++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/src/daqpytools/logging/formatter.py b/src/daqpytools/logging/formatter.py index b14324c..aa85b74 100644 --- a/src/daqpytools/logging/formatter.py +++ b/src/daqpytools/logging/formatter.py @@ -24,7 +24,10 @@ DATE_TIME_BASE_FORMAT = config_loader.safe_load_config("logging", "date_time_base") CONSOLE_THEME = Theme(config_loader.safe_load_config("theme")) -timezone_name = config_loader.safe_load_config("logging", "timezone") +# timezone_name = config_loader.safe_load_config("logging", "timezone") +timezone_load = config_loader.load_env("DUNEDAQ_TIMEZONE") +timezone_name = config_loader.safe_load_config("environment", "DUNEDAQ_TIMEZONE") + try: TIME_ZONE = timezone(timezone_name) except UnknownTimeZoneError as e: diff --git a/src/daqpytools/utils/config_loader.py b/src/daqpytools/utils/config_loader.py index 4cfca7b..58953de 100644 --- a/src/daqpytools/utils/config_loader.py +++ b/src/daqpytools/utils/config_loader.py @@ -1,4 +1,4 @@ - +import os import configparser from pathlib import Path from typing import overload @@ -60,6 +60,34 @@ def safe_load_config( ... + # define a thing that lets you parse environment variables + def load_env(self, env_key): + """Read an environment variable and insert it into the + ``environment`` section of the internal ``ConfigParser``. + + If the section does not exist it will be created. The method stores + an empty string when the environment variable is not set so that + subsequent calls to ``safe_load_config('environment', env_key)`` will + raise a ``ConfigurationError`` for missing/empty values (consistent + with the rest of this loader). + + Returns the environment value or ``None`` if the variable is not set. + """ + + env_value = os.environ.get(env_key) + section = "environment" + print(f"getting {env_value}, {env_key}") + if not self.config.has_section(section): + self.config.add_section(section) + + # Store an empty string when env is not set to preserve ConfigParser + # semantics used by `safe_load_config` (empty values are treated as + # errors by that method). + self.config.set(section, env_key, "" if env_value is None else env_value) + + return env_value + + def safe_load_config( self, section: str, From 5410618cd80b3b5375ad07b78cbe2882439a7252 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Fri, 29 May 2026 15:54:57 +0200 Subject: [PATCH 02/13] add better safe loader --- src/daqpytools/logging/formatter.py | 5 +++-- src/daqpytools/utils/config_loader.py | 15 +++++++++++++++ 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/daqpytools/logging/formatter.py b/src/daqpytools/logging/formatter.py index aa85b74..1ef1e9d 100644 --- a/src/daqpytools/logging/formatter.py +++ b/src/daqpytools/logging/formatter.py @@ -24,9 +24,10 @@ DATE_TIME_BASE_FORMAT = config_loader.safe_load_config("logging", "date_time_base") CONSOLE_THEME = Theme(config_loader.safe_load_config("theme")) -# timezone_name = config_loader.safe_load_config("logging", "timezone") timezone_load = config_loader.load_env("DUNEDAQ_TIMEZONE") -timezone_name = config_loader.safe_load_config("environment", "DUNEDAQ_TIMEZONE") +timezone_name = config_loader.safe_load_config("environment", "DUNEDAQ_TIMEZONE", allow_fail = True) +if not timezone_name: + timezone_name = config_loader.safe_load_config("logging", "timezone") try: TIME_ZONE = timezone(timezone_name) diff --git a/src/daqpytools/utils/config_loader.py b/src/daqpytools/utils/config_loader.py index 58953de..4c10a2f 100644 --- a/src/daqpytools/utils/config_loader.py +++ b/src/daqpytools/utils/config_loader.py @@ -92,6 +92,21 @@ def safe_load_config( self, section: str, option: str | None = None, + allow_fail: bool = False + ): + try: + return self.load_config(section, option) + except ConfigurationError as e: + if allow_fail: + return False + else: + raise e + + + def load_config( + self, + section: str, + option: str | None = None, ) -> dict[str, str] | str: """Safely load configuration content from a section or a single option. From f576dd8a55a15d8fff83bfa5cb2f0fe998aa6195 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Fri, 29 May 2026 15:58:43 +0200 Subject: [PATCH 03/13] ruff --- src/daqpytools/logging/formatter.py | 4 +++- src/daqpytools/utils/config_loader.py | 30 ++++++++++++++++++--------- 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/daqpytools/logging/formatter.py b/src/daqpytools/logging/formatter.py index 1ef1e9d..e5fd54b 100644 --- a/src/daqpytools/logging/formatter.py +++ b/src/daqpytools/logging/formatter.py @@ -25,7 +25,9 @@ CONSOLE_THEME = Theme(config_loader.safe_load_config("theme")) timezone_load = config_loader.load_env("DUNEDAQ_TIMEZONE") -timezone_name = config_loader.safe_load_config("environment", "DUNEDAQ_TIMEZONE", allow_fail = True) +timezone_name = config_loader.safe_load_config( + "environment", "DUNEDAQ_TIMEZONE", allow_fail=True +) if not timezone_name: timezone_name = config_loader.safe_load_config("logging", "timezone") diff --git a/src/daqpytools/utils/config_loader.py b/src/daqpytools/utils/config_loader.py index 4c10a2f..c42f8bb 100644 --- a/src/daqpytools/utils/config_loader.py +++ b/src/daqpytools/utils/config_loader.py @@ -1,5 +1,5 @@ -import os import configparser +import os from pathlib import Path from typing import overload @@ -61,7 +61,7 @@ def safe_load_config( # define a thing that lets you parse environment variables - def load_env(self, env_key): + def load_env(self, env_key: str) -> str | None: """Read an environment variable and insert it into the ``environment`` section of the internal ``ConfigParser``. @@ -73,10 +73,8 @@ def load_env(self, env_key): Returns the environment value or ``None`` if the variable is not set. """ - env_value = os.environ.get(env_key) section = "environment" - print(f"getting {env_value}, {env_key}") if not self.config.has_section(section): self.config.add_section(section) @@ -86,21 +84,33 @@ def load_env(self, env_key): self.config.set(section, env_key, "" if env_value is None else env_value) return env_value - + def safe_load_config( self, section: str, option: str | None = None, - allow_fail: bool = False - ): + allow_fail: bool = False, + ) -> dict[str, str] | str | bool: + """Load configuration data or return ``False`` when allowed to fail. + + Args: + section: Configuration section name. + option: Optional option name within ``section``. + allow_fail: If ``True``, return ``False`` instead of raising a + ``ConfigurationError`` when the section/option is missing or + empty. + + Returns: + Either a full section mapping, a single option value, or ``False`` + when failure is allowed. + """ try: return self.load_config(section, option) - except ConfigurationError as e: + except ConfigurationError: if allow_fail: return False - else: - raise e + raise def load_config( From eba6f20e9786c49cf6e216084a8400f0ae748886 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Fri, 29 May 2026 16:58:07 +0200 Subject: [PATCH 04/13] Offload themes to separate theme files --- src/daqpytools/logging/formatter.py | 8 ++++++++ src/daqpytools/logging/log_format.ini | 22 ---------------------- src/daqpytools/logging/themes/black.ini | 21 +++++++++++++++++++++ src/daqpytools/logging/themes/default.ini | 21 +++++++++++++++++++++ src/daqpytools/utils/config_loader.py | 7 +++++-- 5 files changed, 55 insertions(+), 24 deletions(-) create mode 100644 src/daqpytools/logging/themes/black.ini create mode 100644 src/daqpytools/logging/themes/default.ini diff --git a/src/daqpytools/logging/formatter.py b/src/daqpytools/logging/formatter.py index e5fd54b..e77951e 100644 --- a/src/daqpytools/logging/formatter.py +++ b/src/daqpytools/logging/formatter.py @@ -22,6 +22,14 @@ LOG_FORMAT = config_loader.safe_load_config("logging", "record_format") DATE_TIME_FORMAT = config_loader.safe_load_config("logging", "date_time") DATE_TIME_BASE_FORMAT = config_loader.safe_load_config("logging", "date_time_base") + + +#! This bit needs to be sourced out again from somewhere!!!!!! +#? use daq environment variables again? +#? and then we can have a CLI entry point that just sets an env variable +#? so that the daqqy stuff can just piont to it? +THEME_FILE = DAQPYTOOLS_LOGGING_ROOT / "themes/default.ini" +config_loader.read_conf(THEME_FILE) CONSOLE_THEME = Theme(config_loader.safe_load_config("theme")) timezone_load = config_loader.load_env("DUNEDAQ_TIMEZONE") diff --git a/src/daqpytools/logging/log_format.ini b/src/daqpytools/logging/log_format.ini index c7981d7..b6a95b8 100644 --- a/src/daqpytools/logging/log_format.ini +++ b/src/daqpytools/logging/log_format.ini @@ -26,28 +26,6 @@ date_time_base=%%Y/%%m/%%d %%H:%%M:%%S %%Z date_time=[%(date_time_base)s] timezone=UTC -[theme] -# Define the color theme for logging output -# Colors can be set to 'dim', 'bold', or 'bright' variants of the colors -# Available colors: black, red, green, yellow, blue, magenta, cyan -# Background colors can be set with 'on_' prefix - -# === Context elements === -# Available colors: black, red, green, yellow, blue, magenta, cyan, white -# You can also use: bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white -# Styles: dim, bold, italic, underline, reverse, blink, conceal, strike -# Combine styles and colors, e.g., "bold magenta", "dim cyan", "bold white on red" -logging.time = dim blue -logging.location = dim white -logging.logger_name = dim white - -# === Log level colors === -logging.level.debug = dim cyan -logging.level.info = bold green -logging.level.warning = bold yellow -logging.level.error = bold red -logging.level.critical = bold white on red - [cli] # Command-line interface options help_option_names = -h,--help \ No newline at end of file diff --git a/src/daqpytools/logging/themes/black.ini b/src/daqpytools/logging/themes/black.ini new file mode 100644 index 0000000..86da91d --- /dev/null +++ b/src/daqpytools/logging/themes/black.ini @@ -0,0 +1,21 @@ +[theme] +# Define the color theme for logging output +# Colors can be set to 'dim', 'bold', or 'bright' variants of the colors +# Available colors: black, red, green, yellow, blue, magenta, cyan +# Background colors can be set with 'on_' prefix + +# === Context elements === +# Available colors: black, red, green, yellow, blue, magenta, cyan, white +# You can also use: bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white +# Styles: dim, bold, italic, underline, reverse, blink, conceal, strike +# Combine styles and colors, e.g., "bold magenta", "dim cyan", "bold white on red" +logging.time = black +logging.location = black +logging.logger_name = black + +# === Log level colors === +logging.level.debug = black +logging.level.info = black +logging.level.warning = black +logging.level.error = black +logging.level.critical = black \ No newline at end of file diff --git a/src/daqpytools/logging/themes/default.ini b/src/daqpytools/logging/themes/default.ini new file mode 100644 index 0000000..852edaa --- /dev/null +++ b/src/daqpytools/logging/themes/default.ini @@ -0,0 +1,21 @@ +[theme] +# Define the color theme for logging output +# Colors can be set to 'dim', 'bold', or 'bright' variants of the colors +# Available colors: black, red, green, yellow, blue, magenta, cyan +# Background colors can be set with 'on_' prefix + +# === Context elements === +# Available colors: black, red, green, yellow, blue, magenta, cyan, white +# You can also use: bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white +# Styles: dim, bold, italic, underline, reverse, blink, conceal, strike +# Combine styles and colors, e.g., "bold magenta", "dim cyan", "bold white on red" +logging.time = dim blue +logging.location = dim white +logging.logger_name = dim white + +# === Log level colors === +logging.level.debug = dim cyan +logging.level.info = bold green +logging.level.warning = bold yellow +logging.level.error = bold red +logging.level.critical = bold white on red \ No newline at end of file diff --git a/src/daqpytools/utils/config_loader.py b/src/daqpytools/utils/config_loader.py index c42f8bb..2d5a893 100644 --- a/src/daqpytools/utils/config_loader.py +++ b/src/daqpytools/utils/config_loader.py @@ -34,8 +34,11 @@ def __init__(self, config_file: Path | str) -> None: """ self.config_file = config_file self.config: configparser.ConfigParser = configparser.ConfigParser() - - if not self.config.read(self.config_file): + self.read_conf(self.config_file) + + + def read_conf(self, conf): + if not self.config.read(conf): err_msg = ( f"Configuration file '{self.config_file}' " "not found or could not be read." From 461fed7962ad52b69e86dac0bbf0225676859345 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Fri, 29 May 2026 17:03:21 +0200 Subject: [PATCH 05/13] Add basic logic on choosing themes --- src/daqpytools/logging/formatter.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/daqpytools/logging/formatter.py b/src/daqpytools/logging/formatter.py index e77951e..a69967c 100644 --- a/src/daqpytools/logging/formatter.py +++ b/src/daqpytools/logging/formatter.py @@ -28,17 +28,23 @@ #? use daq environment variables again? #? and then we can have a CLI entry point that just sets an env variable #? so that the daqqy stuff can just piont to it? -THEME_FILE = DAQPYTOOLS_LOGGING_ROOT / "themes/default.ini" +config_loader.load_env("DUNEDAQ_LOGGING_THEME") +theme_name = config_loader.safe_load_config( + "environment", "DUNEDAQ_LOGGING_THEME", allow_fail=True +) +theme_name = theme_name if theme_name else "default" +THEME_FILE = DAQPYTOOLS_LOGGING_ROOT / f"themes/{theme_name}.ini" config_loader.read_conf(THEME_FILE) CONSOLE_THEME = Theme(config_loader.safe_load_config("theme")) -timezone_load = config_loader.load_env("DUNEDAQ_TIMEZONE") + + +config_loader.load_env("DUNEDAQ_TIMEZONE") timezone_name = config_loader.safe_load_config( "environment", "DUNEDAQ_TIMEZONE", allow_fail=True ) if not timezone_name: timezone_name = config_loader.safe_load_config("logging", "timezone") - try: TIME_ZONE = timezone(timezone_name) except UnknownTimeZoneError as e: @@ -48,6 +54,8 @@ ) raise LoggerConfigurationError(CONFIGURATION_FILE, err_msg) from e + + help_options_str = config_loader.safe_load_config("cli", "help_option_names") HELP_OPTION_NAMES = [opt.strip() for opt in help_options_str.split(",")] CONTEXT_SETTINGS = {"help_option_names": HELP_OPTION_NAMES} From 7485f58b367c23752cafaa8c34c1153f2f051674 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Fri, 29 May 2026 17:30:24 +0200 Subject: [PATCH 06/13] Improve logic handling of env variables --- src/daqpytools/logging/formatter.py | 25 +++++++------- src/daqpytools/logging/log_format.ini | 9 +++-- src/daqpytools/utils/config_loader.py | 47 +++++++-------------------- 3 files changed, 29 insertions(+), 52 deletions(-) diff --git a/src/daqpytools/logging/formatter.py b/src/daqpytools/logging/formatter.py index a69967c..7d8323f 100644 --- a/src/daqpytools/logging/formatter.py +++ b/src/daqpytools/logging/formatter.py @@ -28,23 +28,20 @@ #? use daq environment variables again? #? and then we can have a CLI entry point that just sets an env variable #? so that the daqqy stuff can just piont to it? -config_loader.load_env("DUNEDAQ_LOGGING_THEME") -theme_name = config_loader.safe_load_config( - "environment", "DUNEDAQ_LOGGING_THEME", allow_fail=True -) -theme_name = theme_name if theme_name else "default" -THEME_FILE = DAQPYTOOLS_LOGGING_ROOT / f"themes/{theme_name}.ini" -config_loader.read_conf(THEME_FILE) -CONSOLE_THEME = Theme(config_loader.safe_load_config("theme")) +def load_and_return(env): + config_loader.load_env(env) + theme_name = config_loader.safe_load_config( + "environment", env + ) + return theme_name + + +config_loader.read_conf(DAQPYTOOLS_LOGGING_ROOT / f"themes/{load_and_return("DUNEDAQ_LOGGING_THEME")}.ini") +CONSOLE_THEME = Theme(config_loader.safe_load_config("theme")) -config_loader.load_env("DUNEDAQ_TIMEZONE") -timezone_name = config_loader.safe_load_config( - "environment", "DUNEDAQ_TIMEZONE", allow_fail=True -) -if not timezone_name: - timezone_name = config_loader.safe_load_config("logging", "timezone") +timezone_name = load_and_return("DUNEDAQ_TIMEZONE") try: TIME_ZONE = timezone(timezone_name) except UnknownTimeZoneError as e: diff --git a/src/daqpytools/logging/log_format.ini b/src/daqpytools/logging/log_format.ini index b6a95b8..1e0c58e 100644 --- a/src/daqpytools/logging/log_format.ini +++ b/src/daqpytools/logging/log_format.ini @@ -24,8 +24,13 @@ logger_name = 50 record_format=%%(asctime)s %%(levelname)s %%(filename)s %%(name)s %%(message)s date_time_base=%%Y/%%m/%%d %%H:%%M:%%S %%Z date_time=[%(date_time_base)s] -timezone=UTC [cli] # Command-line interface options -help_option_names = -h,--help \ No newline at end of file +help_option_names = -h,--help + +[environment] +# These can be overridden from the environment variables +# the current ones here show what the default is +DUNEDAQ_LOGGING_THEME = default +DUNEDAQ_TIMEZONE = UTC \ No newline at end of file diff --git a/src/daqpytools/utils/config_loader.py b/src/daqpytools/utils/config_loader.py index 2d5a893..1142d7f 100644 --- a/src/daqpytools/utils/config_loader.py +++ b/src/daqpytools/utils/config_loader.py @@ -69,22 +69,24 @@ def load_env(self, env_key: str) -> str | None: ``environment`` section of the internal ``ConfigParser``. If the section does not exist it will be created. The method stores - an empty string when the environment variable is not set so that - subsequent calls to ``safe_load_config('environment', env_key)`` will - raise a ``ConfigurationError`` for missing/empty values (consistent - with the rest of this loader). + the variable only when it is set and non-empty; if the variable is + not set (or is an empty string), the config is left unchanged and + the method returns ``None``. This differs from earlier behaviour that + used to write an empty string for unset variables. - Returns the environment value or ``None`` if the variable is not set. + Returns the environment value or ``None`` if the variable is not set + or is empty. """ env_value = os.environ.get(env_key) section = "environment" if not self.config.has_section(section): self.config.add_section(section) - # Store an empty string when env is not set to preserve ConfigParser - # semantics used by `safe_load_config` (empty values are treated as - # errors by that method). - self.config.set(section, env_key, "" if env_value is None else env_value) + # Only store the value when the environment variable is set and + # non-empty. If the variable is unset or empty, leave the config + # unchanged and return None. + if env_value: + self.config.set(section, env_key, env_value) return env_value @@ -93,33 +95,6 @@ def safe_load_config( self, section: str, option: str | None = None, - allow_fail: bool = False, - ) -> dict[str, str] | str | bool: - """Load configuration data or return ``False`` when allowed to fail. - - Args: - section: Configuration section name. - option: Optional option name within ``section``. - allow_fail: If ``True``, return ``False`` instead of raising a - ``ConfigurationError`` when the section/option is missing or - empty. - - Returns: - Either a full section mapping, a single option value, or ``False`` - when failure is allowed. - """ - try: - return self.load_config(section, option) - except ConfigurationError: - if allow_fail: - return False - raise - - - def load_config( - self, - section: str, - option: str | None = None, ) -> dict[str, str] | str: """Safely load configuration content from a section or a single option. From d70df91a9c685337b95130332afc4b0b85d648fc Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Wed, 3 Jun 2026 17:57:51 +0200 Subject: [PATCH 07/13] add dark and light themes --- src/daqpytools/logging/themes/dark.ini | 21 +++++++++++++++++++++ src/daqpytools/logging/themes/light.ini | 21 +++++++++++++++++++++ 2 files changed, 42 insertions(+) create mode 100644 src/daqpytools/logging/themes/dark.ini create mode 100644 src/daqpytools/logging/themes/light.ini diff --git a/src/daqpytools/logging/themes/dark.ini b/src/daqpytools/logging/themes/dark.ini new file mode 100644 index 0000000..00ab058 --- /dev/null +++ b/src/daqpytools/logging/themes/dark.ini @@ -0,0 +1,21 @@ +[theme] +# Define the color theme for logging output +# Colors can be set to 'dim', 'bold', or 'bright' variants of the colors +# Available colors: black, red, green, yellow, blue, magenta, cyan +# Background colors can be set with 'on_' prefix + +# === Context elements === +# Available colors: black, red, green, yellow, blue, magenta, cyan, white +# You can also use: bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white +# Styles: dim, bold, italic, underline, reverse, blink, conceal, strike +# Combine styles and colors, e.g., "bold magenta", "dim cyan", "bold white on red" +logging.time = blue +logging.location = grey74 +logging.logger_name = grey74 + +# === Log level colors === +logging.level.debug = cyan +logging.level.info = bold green +logging.level.warning = bold yellow +logging.level.error = bold red +logging.level.critical = bold white on red \ No newline at end of file diff --git a/src/daqpytools/logging/themes/light.ini b/src/daqpytools/logging/themes/light.ini new file mode 100644 index 0000000..69fff73 --- /dev/null +++ b/src/daqpytools/logging/themes/light.ini @@ -0,0 +1,21 @@ +[theme] +# Define the color theme for logging output +# Colors can be set to 'dim', 'bold', or 'bright' variants of the colors +# Available colors: black, red, green, yellow, blue, magenta, cyan +# Background colors can be set with 'on_' prefix + +# === Context elements === +# Available colors: black, red, green, yellow, blue, magenta, cyan, white +# You can also use: bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white +# Styles: dim, bold, italic, underline, reverse, blink, conceal, strike +# Combine styles and colors, e.g., "bold magenta", "dim cyan", "bold white on red" +logging.time = blue +logging.location = bright_black +logging.logger_name = bright_black + +# === Log level colors === +logging.level.debug = cyan +logging.level.info = bold green +logging.level.warning = bold yellow +logging.level.error = bold red +logging.level.critical = bold white on red \ No newline at end of file From abb4746568b02cded1cad2b15cb4bffbae76baf4 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Thu, 4 Jun 2026 15:30:50 +0200 Subject: [PATCH 08/13] Add a check against unknown theme files --- src/daqpytools/logging/formatter.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/daqpytools/logging/formatter.py b/src/daqpytools/logging/formatter.py index 7d8323f..5155794 100644 --- a/src/daqpytools/logging/formatter.py +++ b/src/daqpytools/logging/formatter.py @@ -37,7 +37,12 @@ def load_and_return(env): return theme_name -config_loader.read_conf(DAQPYTOOLS_LOGGING_ROOT / f"themes/{load_and_return("DUNEDAQ_LOGGING_THEME")}.ini") +theme_path = Path(DAQPYTOOLS_LOGGING_ROOT / f"themes/{load_and_return("DUNEDAQ_LOGGING_THEME")}.ini") +if not theme_path.is_file(): + err_msg = f"{load_and_return("DUNEDAQ_LOGGING_THEME")} is not a valid theme file! Change your DUNEDAQ_LOGGING_THEME variable" + raise ValueError(err_msg) + +config_loader.read_conf(theme_path) CONSOLE_THEME = Theme(config_loader.safe_load_config("theme")) From 5210cadfcba64c54799377a68d346b271f76d8fd Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Thu, 4 Jun 2026 15:35:18 +0200 Subject: [PATCH 09/13] modify theme details for clarity --- src/daqpytools/logging/themes/black.ini | 6 ++++++ src/daqpytools/logging/themes/dark.ini | 6 ++++++ src/daqpytools/logging/themes/default.ini | 6 ++++++ src/daqpytools/logging/themes/light.ini | 6 ++++++ 4 files changed, 24 insertions(+) diff --git a/src/daqpytools/logging/themes/black.ini b/src/daqpytools/logging/themes/black.ini index 86da91d..0dd1a3b 100644 --- a/src/daqpytools/logging/themes/black.ini +++ b/src/daqpytools/logging/themes/black.ini @@ -9,6 +9,12 @@ # You can also use: bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white # Styles: dim, bold, italic, underline, reverse, blink, conceal, strike # Combine styles and colors, e.g., "bold magenta", "dim cyan", "bold white on red" +# Rich color reference: https://rich.readthedocs.io/en/stable/appendix/colors.html +# Rich style reference: https://rich.readthedocs.io/en/latest/style.html + +# Theme specific details +# This one makes everything black, which is a nice colorless default for people to use + logging.time = black logging.location = black logging.logger_name = black diff --git a/src/daqpytools/logging/themes/dark.ini b/src/daqpytools/logging/themes/dark.ini index 00ab058..664b41a 100644 --- a/src/daqpytools/logging/themes/dark.ini +++ b/src/daqpytools/logging/themes/dark.ini @@ -9,6 +9,12 @@ # You can also use: bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white # Styles: dim, bold, italic, underline, reverse, blink, conceal, strike # Combine styles and colors, e.g., "bold magenta", "dim cyan", "bold white on red" +# Rich color reference: https://rich.readthedocs.io/en/stable/appendix/colors.html +# Rich style reference: https://rich.readthedocs.io/en/latest/style.html + +# Theme specific details +# Safe to use on all dark (including black) themes. The colors should still be legible. + logging.time = blue logging.location = grey74 logging.logger_name = grey74 diff --git a/src/daqpytools/logging/themes/default.ini b/src/daqpytools/logging/themes/default.ini index 852edaa..5e39892 100644 --- a/src/daqpytools/logging/themes/default.ini +++ b/src/daqpytools/logging/themes/default.ini @@ -9,6 +9,12 @@ # You can also use: bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white # Styles: dim, bold, italic, underline, reverse, blink, conceal, strike # Combine styles and colors, e.g., "bold magenta", "dim cyan", "bold white on red" +# Rich color reference: https://rich.readthedocs.io/en/stable/appendix/colors.html +# Rich style reference: https://rich.readthedocs.io/en/latest/style.html + +# Theme specific details +# Safe to use on all light (including white) themes. The colors should still be legible. + logging.time = dim blue logging.location = dim white logging.logger_name = dim white diff --git a/src/daqpytools/logging/themes/light.ini b/src/daqpytools/logging/themes/light.ini index 69fff73..7e258b3 100644 --- a/src/daqpytools/logging/themes/light.ini +++ b/src/daqpytools/logging/themes/light.ini @@ -9,6 +9,12 @@ # You can also use: bright_black, bright_red, bright_green, bright_yellow, bright_blue, bright_magenta, bright_cyan, bright_white # Styles: dim, bold, italic, underline, reverse, blink, conceal, strike # Combine styles and colors, e.g., "bold magenta", "dim cyan", "bold white on red" +# Rich color reference: https://rich.readthedocs.io/en/stable/appendix/colors.html +# Rich style reference: https://rich.readthedocs.io/en/latest/style.html + +# Theme specific details +# This one makes everything black, which is a nice colorless default for people to use + logging.time = blue logging.location = bright_black logging.logger_name = bright_black From 9861dacf80c792d6d9b5dd289a9af7f55dcdf153 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Thu, 4 Jun 2026 16:18:40 +0200 Subject: [PATCH 10/13] Add docs --- docs/environment-configs.md | 33 ++++++++++++++++++++++++ docs/img/theme.png | Bin 0 -> 42870 bytes docs/img/timezone.png | Bin 0 -> 53334 bytes docs/index.md | 1 + docs_dev/how-to/update-documentation.md | 2 +- mkdocs.yml | 2 ++ 6 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 docs/environment-configs.md create mode 100644 docs/img/theme.png create mode 100644 docs/img/timezone.png diff --git a/docs/environment-configs.md b/docs/environment-configs.md new file mode 100644 index 0000000..2c6baf3 --- /dev/null +++ b/docs/environment-configs.md @@ -0,0 +1,33 @@ +# Environment configurations + +`daqpytools` has the power for you to configure your current instance of the loggings! This allows each user to change the timezone and the color themes to suit them as the logs come out. + +The way this is configured is by setting environment variables. By default, these are _unset_ in the terminal, which daqpytools will read and resolve to a default value. These default values can be found in `logging/log_format.ini`. + +## Timezones + +To change the timezone, simply do + +`export DUNEDAQ_TIMEZONE="[timezone]"` + +eg. `export DUNEDAQ_TIMEZONE="UTC"` + +Valid values are those that are listed in `pytz.all_timezones`. + +An example with `Europe/London`. + +![timezones](img/timezone.png) + + +## Logging themes + +The themes are defined in daqpytools, in `logging/themes`, where you can see all the different themes available. To change between them, simply do + +`export DUNEDAQ_LOGGING_THEME="[themename]"` + +eg. `export DUNEDAQ_LOGGING_THEME="dark"` + +There are checks in place to ensure that the theme choice is valid before logs are printed. + +An example with `black`. +![themes](img/theme.png) \ No newline at end of file diff --git a/docs/img/theme.png b/docs/img/theme.png new file mode 100644 index 0000000000000000000000000000000000000000..cae3a0258f5ec2fefb85a08da89280423df08236 GIT binary patch literal 42870 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 EKfI*%-T(jq literal 0 HcmV?d00001 diff --git a/docs/index.md b/docs/index.md index 86e7124..fa61cea 100644 --- a/docs/index.md +++ b/docs/index.md @@ -23,4 +23,5 @@ This documentation is split into two sections depending on your role: | [Best practices](./how-to/best-practices.md) | Recommended patterns for structuring logging in your application | | [Troubleshooting](./reference/troubleshooting.md) | Common symptoms, causes, and fixes | | [API reference](../APIref/) | Auto-generated kwargs, types, and defaults for all public APIs (redirects to MKDocs website) | +| [Environment configs](./environment-configs.md) | Extra information on how to configure your local copy of the logging. | diff --git a/docs_dev/how-to/update-documentation.md b/docs_dev/how-to/update-documentation.md index 10c634e..2f46254 100644 --- a/docs_dev/how-to/update-documentation.md +++ b/docs_dev/how-to/update-documentation.md @@ -10,7 +10,7 @@ If you are new to this repo, read this first before editing docs. The docs are assembled from multiple sources at build time: -- `docs/` contains user-facing content +- `docs/` contains user-facing content. **Note that this is also used in the dunedaq readthedocs.** - `docs_dev/` contains developer-facing content - `docs_dev/utils/generate_logging_autodocs.py` generates API reference pages from Python registries - `docs_dev/utils/mirror_docs.py` mirrors everything into a virtual docs tree diff --git a/mkdocs.yml b/mkdocs.yml index 0595fe9..29daebd 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -28,6 +28,8 @@ nav: - How docs work and how to update them: dev/how-to/update-documentation.md - Common patterns: dev/reference/patterns.md - API reference: APIref + - Environment configurations: user/environment-configs.md + theme: name: material palette: From 1767250b7daf505230b00fa33b0038f955b5cedc Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Thu, 4 Jun 2026 16:26:15 +0200 Subject: [PATCH 11/13] ruff --- src/daqpytools/logging/formatter.py | 19 +++++++------------ src/daqpytools/utils/config_loader.py | 3 ++- 2 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/daqpytools/logging/formatter.py b/src/daqpytools/logging/formatter.py index 5155794..7e27fae 100644 --- a/src/daqpytools/logging/formatter.py +++ b/src/daqpytools/logging/formatter.py @@ -24,22 +24,19 @@ DATE_TIME_BASE_FORMAT = config_loader.safe_load_config("logging", "date_time_base") -#! This bit needs to be sourced out again from somewhere!!!!!! -#? use daq environment variables again? -#? and then we can have a CLI entry point that just sets an env variable -#? so that the daqqy stuff can just piont to it? - -def load_and_return(env): +def load_and_return(env: str) -> str: + """Loads the env into the config, and then returns it safely.""" config_loader.load_env(env) - theme_name = config_loader.safe_load_config( + return config_loader.safe_load_config( "environment", env ) - return theme_name -theme_path = Path(DAQPYTOOLS_LOGGING_ROOT / f"themes/{load_and_return("DUNEDAQ_LOGGING_THEME")}.ini") +theme_path = Path(DAQPYTOOLS_LOGGING_ROOT / + f"themes/{load_and_return('DUNEDAQ_LOGGING_THEME')}.ini") if not theme_path.is_file(): - err_msg = f"{load_and_return("DUNEDAQ_LOGGING_THEME")} is not a valid theme file! Change your DUNEDAQ_LOGGING_THEME variable" + err_msg = (f"{load_and_return('DUNEDAQ_LOGGING_THEME')} is not" + "a valid theme file! Change your DUNEDAQ_LOGGING_THEME variable") raise ValueError(err_msg) config_loader.read_conf(theme_path) @@ -56,8 +53,6 @@ def load_and_return(env): ) raise LoggerConfigurationError(CONFIGURATION_FILE, err_msg) from e - - help_options_str = config_loader.safe_load_config("cli", "help_option_names") HELP_OPTION_NAMES = [opt.strip() for opt in help_options_str.split(",")] CONTEXT_SETTINGS = {"help_option_names": HELP_OPTION_NAMES} diff --git a/src/daqpytools/utils/config_loader.py b/src/daqpytools/utils/config_loader.py index 1142d7f..d563a0e 100644 --- a/src/daqpytools/utils/config_loader.py +++ b/src/daqpytools/utils/config_loader.py @@ -37,7 +37,8 @@ def __init__(self, config_file: Path | str) -> None: self.read_conf(self.config_file) - def read_conf(self, conf): + def read_conf(self, conf: str) -> None: + """Reads and loads a given config file.""" if not self.config.read(conf): err_msg = ( f"Configuration file '{self.config_file}' " From a4d844ef027e51184681aee393c44d6adb341840 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Thu, 4 Jun 2026 16:54:45 +0200 Subject: [PATCH 12/13] add better packaging --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 88b9308..30caa70 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,7 +20,7 @@ version = "1.0.0" where = ["src"] [tool.setuptools.package-data] -"daqpytools.logging" = ["log_format.ini"] +"daqpytools.logging" = ["log_format.ini", "themes/*.ini"] "daqpytools.uml" = ["uml_format.ini"] [project.optional-dependencies] From 62fe0479b56d16d7d0551566bfcf076a80447015 Mon Sep 17 00:00:00 2001 From: Emir Muhammad Date: Fri, 5 Jun 2026 15:54:22 +0200 Subject: [PATCH 13/13] add bashrc thing --- docs/environment-configs.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/environment-configs.md b/docs/environment-configs.md index 2c6baf3..f415d93 100644 --- a/docs/environment-configs.md +++ b/docs/environment-configs.md @@ -4,6 +4,8 @@ The way this is configured is by setting environment variables. By default, these are _unset_ in the terminal, which daqpytools will read and resolve to a default value. These default values can be found in `logging/log_format.ini`. +If a non-default time zone/theme is preferred, it is recommended to set the env vars `DUNEDAQ_TIMEZONE` and `DUNEDAQ_LOGGING_THEME` in your `~/.bashrc`. + ## Timezones To change the timezone, simply do