Skip to content
Snippets Groups Projects

Restructure log location

Merged Ashwin Kumar Karnad requested to merge restructure-log-location into main
2 files
+ 46
2
Compare changes
  • Side-by-side
  • Inline
Files
2
+ 118
33
@@ -31,19 +31,75 @@ for given system architecture and MPSD software stack version.\n
@@ -31,19 +31,75 @@ for given system architecture and MPSD software stack version.\n
The toolchains
The toolchains
are built using the bash script spack_setup.sh, and the results are logged. """
are built using the bash script spack_setup.sh, and the results are logged. """
 
call_date_iso = (
 
datetime.datetime.now().replace(microsecond=0).isoformat().replace(":", "-")
 
)
config_vars = {
config_vars = {
"cmd_log_file": "install.log",
# kept inside the mpsd_release folder
"build_log_file": (
"cmd_log_file": "script_execution_summary.log",
"logs/mpsd_spack_ver_toolchains_"
# Metadata tags
f"{datetime.datetime.now().replace(microsecond=0).isoformat()}.log"
),
"metadata_tag_open": "!<meta>",
"metadata_tag_open": "!<meta>",
"metadata_tag_close": "</meta>!",
"metadata_tag_close": "</meta>!",
# TODO: modify toolchains,mpsd_spack_ver when the variable is available
"spack_environments_repo": "https://gitlab.gwdg.de/mpsd-cs/spack-environments.git",
"spack_environments_repo": "https://gitlab.gwdg.de/mpsd-cs/spack-environments.git",
}
}
 
def create_log_file_names(
 
mpsd_release: str,
 
mpsd_microarch: str,
 
action: str,
 
date: str = call_date_iso,
 
toolchain: str = None,
 
) -> Union[str, None]:
 
"""Create log file names.
 
 
This function creates the log file names for either the installer or
 
the build log files.
 
 
If a toolchain is given, then the build log file name is created.
 
if no toolchain is given, then the installer log file name is created.
 
The installer log file hosts the logs of the installer script, while
 
the build log file hosts the logs of the build process as generated by the
 
spack_setup.sh script.
 
 
Parameters
 
----------
 
mpsd_release : str
 
MPSD software stack version
 
mpsd_microarch : str
 
system architecture
 
date : str
 
date of the call ins iso format
 
action : str
 
action performed (install,remove,reinstall,prepare,status)
 
only install and remove are valid for build log file.
 
toolchain : str
 
toolchain name (only for build log file)
 
 
Returns
 
-------
 
str or None
 
log file name
 
installer_log_file_name or build_log_file_name depending on the
 
parameters given.
 
If the action is not one that changes the files on disk ( info only actions)
 
then None is returned.
 
"""
 
if toolchain:
 
# if toolchain is given, then we build the build_log_file_name
 
if action in ["install", "remove"]:
 
log_file_name = (
 
f"{mpsd_release}_{mpsd_microarch}_{date}_BUILD_{toolchain}_{action}.log"
 
)
 
else:
 
return None
 
else:
 
# if toolchain is not given, then we build the installer_log_file_name
 
log_file_name = f"{mpsd_release}_{mpsd_microarch}_{date}_APEX_{action}.log"
 
 
return log_file_name
 
 
def log_metadata(key: str, value: str) -> None:
def log_metadata(key: str, value: str) -> None:
"""Log metadata to the log file.
"""Log metadata to the log file.
@@ -91,7 +147,29 @@ def read_metadata_from_logfile(logfile: Union[str, Path]) -> dict:
@@ -91,7 +147,29 @@ def read_metadata_from_logfile(logfile: Union[str, Path]) -> dict:
}
}
def set_up_logging(loglevel="warning", filename=None):
def get_installer_log_file_path(mpsd_release: str, cmd: str, script_dir: str) -> str:
 
"""Get installer log file path."""
 
# Get machine configs
 
os.environ.get("MPSD_OS", "UNKNOWN_OS")
 
mpsd_microarch = get_native_microarchitecture()
 
# parse logging first
 
# decide the log_file_name
 
installer_log_name = create_log_file_names(
 
mpsd_release=mpsd_release, mpsd_microarch=mpsd_microarch, action=cmd
 
)
 
log_folder = script_dir / mpsd_release / "logs"
 
# if the log_folder dosent exist, dont log this message if
 
# the command is a info-only command
 
if cmd not in ["status", "available"]:
 
if not os.path.exists(log_folder):
 
os.makedirs(log_folder)
 
installer_log_file = log_folder / installer_log_name
 
else:
 
installer_log_file = None
 
return installer_log_file
 
 
 
def set_up_logging(loglevel="warning", file_path=None):
"""Set up logging.
"""Set up logging.
This function sets up the logging configuration for the script.
This function sets up the logging configuration for the script.
@@ -106,7 +184,7 @@ def set_up_logging(loglevel="warning", filename=None):
@@ -106,7 +184,7 @@ def set_up_logging(loglevel="warning", filename=None):
- warning (default): only print statements if something is unexpected
- warning (default): only print statements if something is unexpected
- info (show more detailed progress)
- info (show more detailed progress)
- debug (show very detailed output)
- debug (show very detailed output)
filename : str
file_path : str
- filename to save logging messages into
- filename to save logging messages into
If loglevel is 'debug', save line numbers in log messages.
If loglevel is 'debug', save line numbers in log messages.
@@ -188,11 +266,16 @@ def set_up_logging(loglevel="warning", filename=None):
@@ -188,11 +266,16 @@ def set_up_logging(loglevel="warning", filename=None):
shell_handler.setFormatter(shell_formatter)
shell_handler.setFormatter(shell_formatter)
# use the log_level_numeric to decide how much logging is sent to shell
# use the log_level_numeric to decide how much logging is sent to shell
shell_handler.setLevel(log_level_numeric)
shell_handler.setLevel(log_level_numeric)
logger.addHandler(shell_handler)
 
# Here we set the handlers of the RootLogger to be just the one we want.
 
# The reason is that the logging module will add a <StreamHandler <stderr>
 
# (NOTSET)> handler if logging.info/logging.debug/... is used before we
 
# come across this line. And we do not want that additional handler.
 
logger.handlers = [shell_handler]
# if filename provided, write log messages to that file, too.
# if filename provided, write log messages to that file, too.
if filename:
if file_path:
file_handler = logging.FileHandler(filename)
file_handler = logging.FileHandler(file_path)
# if we have a file, we write all information in there.
# if we have a file, we write all information in there.
# We could change the level, for example restrict to only DEBUG and above with
# We could change the level, for example restrict to only DEBUG and above with
# file_handler.setLevel(logging.DEBUG)
# file_handler.setLevel(logging.DEBUG)
@@ -216,9 +299,9 @@ def set_up_logging(loglevel="warning", filename=None):
@@ -216,9 +299,9 @@ def set_up_logging(loglevel="warning", filename=None):
print_log.addHandler(ch)
print_log.addHandler(ch)
# if filename provided, write output of print_log to that file, too
# if filename provided, write output of print_log to that file, too
if filename:
if file_path:
# create, format and add file handler
# create, format and add file handler
fh = logging.FileHandler(filename)
fh = logging.FileHandler(file_path)
fh.setFormatter(formatter)
fh.setFormatter(formatter)
print_log.addHandler(fh)
print_log.addHandler(fh)
@@ -226,8 +309,8 @@ def set_up_logging(loglevel="warning", filename=None):
@@ -226,8 +309,8 @@ def set_up_logging(loglevel="warning", filename=None):
# short message
# short message
#
#
logging.debug(
logging.debug(
f"Logging has been setup, loglevel={loglevel.upper()}"
f"Logging has been setup, loglevel={loglevel.upper()} "
+ f"{filename=} {rich_available=}"
+ f"{file_path=} {rich_available=}"
)
)
@@ -658,8 +741,7 @@ def install_environment(
@@ -658,8 +741,7 @@ def install_environment(
# Set required variables
# Set required variables
release_base_dir = script_dir / mpsd_release
release_base_dir = script_dir / mpsd_release
os.environ.get("MPSD_OS", "UNKNOWN_OS")
mpsd_microarch = get_native_microarchitecture()
mpsd_microarch = os.environ.get("MPSD_MICROARCH", "UNKNOWN_MICROARCH")
toolchain_dir = release_base_dir / mpsd_microarch
toolchain_dir = release_base_dir / mpsd_microarch
toolchain_dir.mkdir(parents=True, exist_ok=True)
toolchain_dir.mkdir(parents=True, exist_ok=True)
spack_setup_script = release_base_dir / "spack-environments" / "spack_setup.sh"
spack_setup_script = release_base_dir / "spack-environments" / "spack_setup.sh"
@@ -697,33 +779,35 @@ def install_environment(
@@ -697,33 +779,35 @@ def install_environment(
if not os.path.exists("logs"):
if not os.path.exists("logs"):
os.mkdir("logs")
os.mkdir("logs")
for toolchain in toolchains:
for toolchain in toolchains:
# Set the install log file name to config_vars["install_log_file"]
# Set the install log file name from create_log_file_names
# and replace _toolchains_ with the toolchain name and
build_log_file_name = create_log_file_names(
# _mpsd_spack_ver_ with mpsd_release
mpsd_release, mpsd_microarch, "install", toolchain=toolchain
 
)
 
build_log_folder = release_base_dir / "logs"
 
build_log_path = build_log_folder / build_log_file_name
 
# if logs folder dosent exist, create it
 
if not os.path.exists(build_log_folder):
 
os.makedirs(build_log_folder)
logging.info(f"Installing toolchain {toolchain} to {toolchain_dir}")
logging.info(f"Installing toolchain {toolchain} to {toolchain_dir}")
install_log_file = (
config_vars["build_log_file"]
.replace("mpsd_spack_ver_", f"{mpsd_release}_")
.replace("_toolchains_", f"_{toolchain}_")
)
# log the command
# log the command
setup_log_cmd(
setup_log_cmd(
mpsd_release,
mpsd_release,
script_dir,
script_dir,
msg=f"installing {toolchain} and logging at {install_log_file}",
msg=f"installing {toolchain} and logging at {build_log_path}",
)
)
setup_log_cmd(
setup_log_cmd(
mpsd_release,
mpsd_release,
script_dir,
script_dir,
msg=(
msg=(
f"CMD: bash {spack_setup_script} {' '.join(install_flags)}"
f"CMD: bash {spack_setup_script} {' '.join(install_flags)} "
"{toolchain}"
f"{toolchain}"
),
),
)
)
run(
run(
f"bash {spack_setup_script} {' '.join(install_flags)} {toolchain} 2>&1 "
f"bash {spack_setup_script} {' '.join(install_flags)} {toolchain} 2>&1 "
f"| tee -a {install_log_file} ",
f"| tee -a {build_log_path} ",
shell=True,
shell=True,
check=True,
check=True,
)
)
@@ -824,13 +908,14 @@ def main():
@@ -824,13 +908,14 @@ def main():
# Carry out the action
# Carry out the action
args = parser.parse_args()
args = parser.parse_args()
# parse logging first
set_up_logging(args.loglevel)
# target dir is the place where this script exists. the
# target dir is the place where this script exists. the
# release `dev` in script_dir/dev-23a
script_dir = Path(os.path.dirname(os.path.realpath(__file__)))
script_dir = Path(os.path.dirname(os.path.realpath(__file__)))
 
set_up_logging(
 
args.loglevel,
 
get_installer_log_file_path(args.release, args.action, script_dir),
 
)
 
# Check the command and run related function
# Check the command and run related function
if args.action == "remove":
if args.action == "remove":
remove_environment(args.release, args.toolchains, script_dir)
remove_environment(args.release, args.toolchains, script_dir)
Loading