diff --git a/INSTALL.md b/INSTALL.md index 3d47e453..27fceffa 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -41,6 +41,33 @@ The `namelist.input` file in `/run` includes all the setup and options info you You can examine model output in the `/data/output.nc` file (requires [Panoply](https://www.giss.nasa.gov/tools/panoply/) or other NetCDF viewer). +## Logger + +The Errror Warning and Trapping Systems (EWTS) has been added to this module using a logging schema. All write statements have been converted to `write_log` statements, which saves the ouptut to a log file based on the log level. + +When running within the ngen framework, the log file and log level are handled programatically. When running standalone, logging is defaulted to DISABLED. + +**Running Standalone** + +In order to generate log messages when running standalone, the `NGEN_EWTS_LOGGING` environment variable must be set to `ENABLED`. This is the only required environment variable . Other optional logger environment variables exist for specifying the log file full pathname and setting the log level. If the user only enables logging, the log level will be set to INFO and the filename will be created based on the user and module names. All logger setup details are written to the console when the module is run. +``` +# Case Sensitive +export NGEN_EWTS_LOGGING=ENABLED +export NGEN_LOG_FILE_PATH= +export NOAHOWP_LOGLEVEL= +``` +**Log Levels** +| Level | Description | Typical Use | +|---------|-----------------------------------------------------|-----------------------------------------------| +| DEBUG | Detailed diagnostic info for development/troubleshooting. | Variable values, function entry/exit. | +| FATAL | Critical failure that aborts or makes app unrecoverable. | Crashes, memory errors, invalid state. | +| INFO | General events confirming expected operations. | Startup/shutdown, configs, task completions. | +| SEVERE | Significant problem; app may continue in degraded state. | Failed services, corrupted configs, data loss.| +| WARNING | Potential issue that doesn’t stop execution. | Deprecated APIs, missing files, repeatable errors. | + +Default log level is INFO. The log level is hierarchical. Setting it to INFO, will log INFO, WARNING, SEVERE and FATAL +messages. + ## BMI unit tests To run unit tests, first compile and link the test program from the main-level directory: diff --git a/src/noahowpLogger.f90 b/src/noahowpLogger.f90 index 40f296d4..8145f339 100644 --- a/src/noahowpLogger.f90 +++ b/src/noahowpLogger.f90 @@ -19,6 +19,12 @@ module noahowp_log_module logical :: opened_once = .false. logical :: logger_initialized = .false. ! Flag to track if the logger has been initialized + ! To use Logger while running this module stand-alone, set + ! the following environment variables, case-sensitive: + ! NGEN_EWTS_LOGGING=ENABLED + ! NGEN_LOG_FILE_PATH= + ! NOAHOWP_LOGLEVEL= + ! ! Constants character(len=1), parameter :: DS = "/" character(len=16), parameter :: MODULE_NAME = "Noah-OWP-Modular" character(len=14), parameter :: LOG_DIR_NGENCERF = "/ngencerf/data" @@ -36,8 +42,7 @@ module noahowp_log_module contains subroutine initialize_logger() - character(len=256) :: log_env, log_msg - character(len=8) :: log_str + character(len=256) :: log_env, log_str integer :: save_log_level logger_initialized = .true. @@ -48,7 +53,7 @@ subroutine initialize_logger() call flush(6) else logging_enabled = .false. - print *,trim(MODULE_NAME)," Logging ", trim(log_env) + print *,trim(MODULE_NAME)," Logging NOT enabled. EV_EWTS_LOGGING=", trim(log_env) call flush(6) return end if @@ -68,19 +73,15 @@ subroutine initialize_logger() else if (log_str == "FATAL" ) then log_level = LOG_LEVEL_FATAL else + log_str = "INFO (" // trim(EV_MODULE_LOGLEVEL) // " = '" // trim(log_str) // "' INVALID Log Level) Defaulted to INFO" log_level = LOG_LEVEL_INFO ! Default level end if - print *, trim(MODULE_NAME),"Log level set to ", log_str - call flush(6) ! Get the log file path by calling set_log_file_path call set_log_file_path() - save_log_level = log_level - log_level = LOG_LEVEL_INFO ! Ensure this INFO message is always logged - log_msg = "Log level set to " // log_str - call write_log(log_msg, log_level); - log_level = save_log_level; + print *, trim(MODULE_NAME)," Log level: ", log_str + call flush(6) end subroutine initialize_logger function fit_string(str, target_len) result(fixed_str) @@ -206,7 +207,6 @@ subroutine set_log_file_path() character(len=512) :: log_file_dir character(len=40) :: timestamp integer :: save_log_level - character(len=1100) :: log_msg append_entries = .true. module_log_env_exists = .false. @@ -257,13 +257,8 @@ subroutine set_log_file_path() if (log_file_ready(append_entries)) then if (.not. module_log_env_exists) then call write_env_var(EV_MODULE_LOGFILEPATH, log_file_path) - print *, "Module ", trim(MODULE_NAME), " Log File: ", trim(log_file_path) + print *, trim(MODULE_NAME), " Log File: ", trim(log_file_path) call flush(6) - save_log_level = log_level - log_level = LOG_LEVEL_INFO ! Ensure this INFO message is always logged - log_msg = "Logging started. Log File Path: " // log_file_path - call write_log(log_msg, log_level); - log_level = save_log_level; end if else print *, "Unable to open log file. Log entries will be writen to stdout"