stdlib_logger#
See also the specification page: stdlib_logger.
stdlib_logger (module)#
Module stdlib_logger
This module defines a derived type, procedures, a variable, and constants to be used for logging information and reporting errors in Fortran applications. See also stdlib_logger.
The derived type, logger_type, is to be used to define variables to serve as both local and global loggers. A logger directs its messages to selected I/O units so the user has a record (a log) of major events. For each entity of logger_type the reports go to a list of I/O units represented by the private internal array, log_units. If log_units is empty then output by default goes to output_unit. Otherwise reports go to output_unit only if it has been explicitly added to log_units. Each entity of type logger_type also maintains an internal state controlling the formatting of output.
The procedures are as follows. The logical function log_units_assigned
returns the number of I/O units in log_units. The subroutines
add_log_file and add_log_unit include the specified file
in log_units. remove_log_unit removes the specified logical unit
from the log_units array and optionally closes the file.
configure configures the details of the logging process and
configuration reports the details of that configuration.
The subroutines log_error, log_information,
log_io_error, log_message,
log_text_error, and log_warning
send messages to the log units.
The variable global_logger of type logger_type can be used as a default global logger anywhere in the source code.
The constants are used to report errors by some of the subroutines in their optional stat arguments. The constants are as follows. success indicates that no error has occurred. close_failure indicates that a close statement for an I/O unit failed. index_invalid_error indicates that column was invalid for the given line. open_failure indicates that an open statement failed. read_only_error indicates that an output unit did not have a “write” or “readwrite” action. non_sequential_error indicates that the unit did not have sequential access. unformatted_in_error indicates that the unit did not have a form of “formatted”. unopened_in_error indicates that the unit was not opened. write_failure indicates that at least one of the writes to log_units failed.
public constants used as error flags Variable of type logger_type to be used as a global logger
Variables
- successinteger, parameter, Default = 0
- close_failureinteger, parameter, Default = 1
- index_invalid_errorinteger, parameter, Default = 2
- non_sequential_errorinteger, parameter, Default = 3
- open_failureinteger, parameter, Default = 4
- read_only_errorinteger, parameter, Default = 5
- unformatted_in_errorinteger, parameter, Default = 6
- unopened_in_errorinteger, parameter, Default = 7
- write_failureinteger, parameter, Default = 8
- debug_levelinteger, parameter, Default = 10
- information_levelinteger, parameter, Default = 20
- warning_levelinteger, parameter, Default = 30
- error_levelinteger, parameter, Default = 40
- io_error_levelinteger, parameter, Default = 40
- text_error_levelinteger, parameter, Default = 50
- all_levelinteger, parameter, Default = -10+min(debug_level, information_level, warning_level, error_level, io_error_level, text_error_level)
- none_levelinteger, parameter, Default = 10+max(debug_level, information_level, warning_level, error_level, io_error_level, text_error_level)
- global_loggertype(logger_type)
Types
logger_type (type)#
-
logger_type (type) Public derived type. See stdlib_logger.
Procedures
log_units_assigned (function)#
-
elemental function log_units_assigned(self) -> log_units_assigned Returns the number of units assigned to self % log_units
- Arguments:
- selfclass(logger_type), intent(in)
The logger subject to the inquiry
- Returns:
- log_units_assignedinteger
Example
module example_mod use stdlib_logger ... type(logger_type) :: alogger ... contains ... subroutine example_sub(unit, ...) integer, intent(in) :: unit ... integer, allocatable :: log_units(:) ... if ( alogger % log_units_assigned() == 0 ) then call alogger % add_log_unit( unit ) end if ... end subroutine example_sub ... end module example_mod
add_log_file (subroutine)#
-
subroutine add_log_file(self, filename, unit, action, position, status, stat) Opens a formatted sequential access output file, filename using newunit and adds the resulting unit number to self’s log_units array. action, if present, is the action specifier of the open statement, and has the default value of “write”. position, if present, is the position specifier, and has the default value of “REWIND”. status, if present, is the status specifier of the open statement, and has the default value of “REPLACE”. stat, if present, has the value success if filename could be opened, read_only_error if action is “read”, and open_failure otherwise.
- Arguments:
- selfclass(logger_type), intent(inout)
The logger variable to which the file is to be added
- filenamecharacter(len=*), intent(in)
The name of the file to be added to the logger
- unitinteger, intent(out), optional
The resulting I/O unit number
- actioncharacter(len=*), intent(in), optional
The action specifier for the open statement
- positioncharacter(len=*), intent(in), optional
The position specifier for the open statement
- statuscharacter(len=*), intent(in), optional
The status specifier for the open statement
- statinteger, intent(out), optional
The error status on exit. The possible values are success if no errors are found, read_only_error if action is “read” for an output file, and open_failure if the open statement fails.
Example
program main use stdlib_logger ... integer :: unit, stat ... call global_logger % add_log_file( 'error_log.txt', unit, & position='asis', stat=stat ) if ( stat /= success ) then error stop 'Unable to open "error_log.txt".' end if ... end program main
add_log_unit (subroutine)#
-
subroutine add_log_unit(self, unit, stat) Adds unit to the log file units in log_units. unit must be an open file, of form “formatted”, with “sequential” access, and an action of “write” or “readwrite”, otherwise either stat, if present, has a value other than success and unit is not entered into log_units, or, if stat is not present, processing stops.
- Arguments:
- selfclass(logger_type), intent(inout)
The logger variable to which the I/O unit is to be added
- unitinteger, intent(in)
The input logical unit number
- statinteger, intent(out), optional
An error code. The possible values are success if no problems are found, non_sequential_error if unit does not have sequential access, read_only_error if unit is not writeable, unformatted_in_error if unit is an ‘unformatted’ file, and unopened_in_error if unit is not opened.
Example
program main use stdlib_logger ... character(256) :: iomsg integer :: iostat, unit, stat ... open( newunit=unit, 'error_log.txt', form='formatted', & status='replace', position='rewind', err=999, & action='read', iostat=iostat, iomsg=iomsg ) ... call global_logger % add_log_unit( unit, stat ) select case ( stat ) ... case ( read_only_error ) error stop 'Unable to write to "error_log.txt".' ... end select ... 999 error stop 'Unable to open "error_log.txt".' ... end program main
configuration (subroutine)#
-
pure subroutine configuration(self, add_blank_line, indent, level, max_width, time_stamp, log_units) Reports the logging configuration of self. The following attributes are reported. add_blank_line is a logical flag with .true. implying that output starts with a blank line and .false. implying no blank line. indent is a logical flag with .true. implying that subsequent columns are indented 4 spaces and .false. implying no indentation. level is the lowest level for printing a message. max_width is the maximum number of columns of output text, with max_width == 0 meaning that the output width is unbounded. time_stamp is a logical flag with .true. implying that the output includes a time stamp and .false. implying that there is no time stamp. log_units is an array of the I/O unit numbers to which log output is written.
- Arguments:
- selfclass(logger_type), intent(in)
The logger variable whose configuration is being reported
- add_blank_linelogical, intent(out), optional
A logical flag to add a preceding blank line
- indentlogical, intent(out), optional
A logical flag to indent subsequent lines
- levelinteger, intent(out), optional
The minimum level for printing a message
- max_widthinteger, intent(out), optional
The maximum number of columns for most outputs
- time_stamplogical, intent(out), optional
A logical flag to add a time stamp
- log_unitsinteger, allocatable, intent(out), optional, dimension(:)
The I/O units used in output
Example
module example_mod use stdlib_logger ... contains ... subroutine example_sub(unit, ...) integer, intent(in) :: unit ... integer, allocatable :: log_units(:) ... call global_logger % configuration( log_units=log_units ) if ( size(log_units) == 0 ) then call add_logger_unit( unit ) end if .. end subroutine example_sub ... end module example_mod
configure (subroutine)#
-
pure subroutine configure(self, add_blank_line, indent, level, max_width, time_stamp) Configures the logging process for SELF. The following attributes are configured. add_blank_line is a logical flag with .true. implying that output starts with a blank line and .false. implying no blank line; its startup value is .false.. indent is a logical flag with .true. implying that subsequent lines are indented 4 spaces and .false. implying no indentation; its startup value is .true.. level is the lowest level for printing a message. max_width is the maximum number of columns of output text, with max_width == 0 meaning that the output width is unbounded; its startup value is 0. time_stamp is a logical flag with .true. implying that the output includes a time stamp and .false. implying that there is no time stamp; its startup value is .true..
- Arguments:
- selfclass(logger_type), intent(inout)
- add_blank_linelogical, intent(in), optional
- indentlogical, intent(in), optional
- levelinteger, intent(in), optional
- max_widthinteger, intent(in), optional
- time_stamplogical, intent(in), optional
Example
program main use stdlib_logger ... call global_logger % configure( indent=.false., max_width=72 ) ...
log_debug (subroutine)#
-
subroutine log_debug(self, message, module, procedure) Writes the string message to self % log_units with optional additional text.
- Arguments:
- selfclass(logger_type), intent(in)
The logger used to send the message
- messagecharacter(len=*), intent(in)
A string to be written to log_unit
- modulecharacter(len=*), intent(in), optional
The name of the module containing the current invocation of log_information
- procedurecharacter(len=*), intent(in), optional
The name of the procedure containing the current invocation of log_information
Behavior
If time stamps are active, a time stamp is written, followed by module and procedure if present, and then message is written with the prefix ‘DEBUG: ‘.
Example
module example_mod use stdlib_logger ... real, allocatable :: a(:) ... type(logger_type) :: alogger ... contains ... subroutine example_sub( selection ) integer, intent(out) :: selection integer :: stat write(*,'(a)') "Enter an integer to select a widget" read(*,'(i0)') selection write( message, '(a, i0)' ) & "The user selected ", selection call alogger % log_debug( message, & module = 'EXAMPLE_MOD', & procedure = 'EXAMPLE_SUB' ) ... end subroutine example_sub ... end module example_mod
log_error (subroutine)#
-
subroutine log_error(self, message, module, procedure, stat, errmsg) Writes the string message to self % log_units with optional additional text.
- Arguments:
- selfclass(logger_type), intent(in)
The logger to be used in logging the message
- messagecharacter(len=*), intent(in)
A string to be written to log_unit
- modulecharacter(len=*), intent(in), optional
The name of the module containing the current invocation of log_error
- procedurecharacter(len=*), intent(in), optional
The name of the procedure containing the current invocation of log_error
- statinteger, intent(in), optional
The value of the stat specifier returned by a Fortran statement
- errmsgcharacter(len=*), intent(in), optional
The value of the errmsg specifier returned by a Fortran statement
Behavior
If time stamps are active, a time stamp is written, followed by module and procedure if present, then message is written with the prefix ‘ERROR: ‘, and then if stat or errmsg are present they are written.
Example
module example_mod use stdlib_logger ... real, allocatable :: a(:) ... type(logger_type) :: alogger ... contains ... subroutine example_sub( size ) integer, intent(in) :: size character(128) :: errmsg, message integer :: stat allocate( a(size), stat=stat, errmsg=errmsg ) if ( stat /= 0 ) then write( message, '(a, i0)' ) & "Allocation of A failed with SIZE = ", size call alogger % log_error( message, & module = 'EXAMPLE_MOD', & procedure = 'EXAMPLE_SUB', & stat = stat, & errmsg = errmsg ) end if end subroutine example_sub ... end module example_mod
log_information (subroutine)#
-
subroutine log_information(self, message, module, procedure) Writes the string message to self % log_units with optional additional text.
- Arguments:
- selfclass(logger_type), intent(in)
The logger used to send the message
- messagecharacter(len=*), intent(in)
A string to be written to log_unit
- modulecharacter(len=*), intent(in), optional
The name of the module containing the current invocation of log_information
- procedurecharacter(len=*), intent(in), optional
The name of the procedure containing the current invocation of log_information
Behavior
If time stamps are active, a time stamp is written, followed by module and procedure if present, and then message is written with the prefix ‘INFO: ‘.
Example
module example_mod use stdlib_logger ... real, allocatable :: a(:) ... type(logger_type) :: alogger ... contains ... subroutine example_sub( selection ) integer, intent(out) :: selection integer :: stat write(*,'(a)') "Enter an integer to select a widget" read(*,'(i0)') selection write( message, '(a, i0)' ) & "The user selected ", selection call alogger % log_information( message, & module = 'EXAMPLE_MOD', & procedure = 'EXAMPLE_SUB' ) ... end subroutine example_sub ... end module example_mod
log_io_error (subroutine)#
-
subroutine log_io_error(self, message, module, procedure, iostat, iomsg) Writes the string message to the self % log_units with optional additional text.
- Arguments:
- selfclass(logger_type), intent(in)
The logger variable to receivee the message
- messagecharacter(len=*), intent(in)
A string to be written to LOG_UNIT
- modulecharacter(len=*), intent(in), optional
The name of the module containing the current invocation of REPORT_ERROR
- procedurecharacter(len=*), intent(in), optional
The name of the procedure containing the current invocation of REPORT_ERROR
- iostatinteger, intent(in), optional
The value of the IOSTAT specifier returned by a Fortran I/O statement
- iomsgcharacter(len=*), intent(in), optional
The value of the IOMSG specifier returned by a Fortran I/O statement
Behavior
If time stamps are active, a time stamp is written, followed by module and procedure if present, then message is written with a prefix ‘I/O ERROR: ‘, and then if iostat or iomsg are present they are also written.
Example
program example use stdlib_logger ... character(*), parameter :: filename = 'dummy.txt' integer :: iostat, lun character(128) :: iomsg character(*), parameter :: message = 'Failure in opening "dummy.txt".' open( newunit=lun, file = filename, form='formatted', & status='old', iostat=iostat, iomsg=iomsg ) if ( iostat /= 0 ) then call global_logger % log_io_error( message, procedure = 'EXAMPLE', & iostat=iostat, iomsg = iomsg ) error stop 'Error on opening ' // filename end if ... end program example
log_message (subroutine)#
-
subroutine log_message(self, message, module, procedure, prefix) Writes the string message to the self % log_units with optional additional text.
- Arguments:
- selfclass(logger_type), intent(in)
The logger variable to receive the message
- messagecharacter(len=*), intent(in)
A string to be written to log_unit
- modulecharacter(len=*), intent(in), optional
The name of the module containing the current invocation of log_message
- procedurecharacter(len=*), intent(in), optional
The name of the procedure containing the current invocation of log_message
- prefixcharacter(len=*), intent(in), optional
To be prepended to message as prefix // ‘: ‘ // message.
Behavior
If time stamps are active, a time stamp is written, followed by module and procedure if present, followed by prefix // ‘: ‘ if present, and then message.
Example
module example_mod use stdlib_logger ... real, allocatable :: a(:) ... contains ... subroutine example_sub( selection ) integer, intent(out) :: selection integer :: stat write(*,'(a)') "Enter an integer to select a widget" read(*,'(i0)') selection write( message, '(a, i0)' ) & "The user selected ", selection call global_logger % log_message( message, & module = 'example_mod', & procedure = 'example_sub', & prefix = 'info' ) end subroutine example_sub ... end module example_mod
log_text_error (subroutine)#
-
subroutine log_text_error(self, line, column, summary, filename, line_number, caret, stat) Sends a message to self % log_units describing an error found in a line of text.
- Arguments:
- selfclass(logger_type), intent(in)
The logger variable to receive the message
- linecharacter(len=*), intent(in)
The line of text in which the error was found.
- columninteger, intent(in)
The one’s based column in LINE at which the error starts.
- summarycharacter(len=*), intent(in)
A brief description of the error.
- filenamecharacter(len=*), intent(in), optional
The name of the file, if any, in which the error was found.
- line_numberinteger, intent(in), optional
The one’s based line number in the file where line was found.
- caretcharacter(len=1), intent(in), optional
The symbol used to mark the column wher the error was first detected
- statinteger, intent(out), optional
Integer flag that an error has occurred. Has the value success if no error hass occurred, index_invalid_error if column is less than zero or greater than len(line), and write_failure if any of the write statements has failed.
Behavior
If time stamps are active first a time stamp is written. Then if filename or line_number or column are present they are written. Then line is written. Then the symbol caret is written below line at the column indicated by column. Then summary is written.
Example
program example ... character(*), parameter :: filename = 'dummy.txt' integer :: col_num, line_num, lun character(128) :: line character(*), parameter :: message = 'Bad text found.' open( newunit=lun, file = filename, statu='old', form='formatted' ) line_num = 0 do read( lun, fmt='(a)', end=900 ) line line_num = line_num + 1 call check_line( line, status, col_num ) if ( status /= 0 ) call global_logger % log_text_error( line, col_num, message, & filename, line_num ) error stop 'Error in reading ' // filename end if ... end do 900 continue ... end program example
log_warning (subroutine)#
-
subroutine log_warning(self, message, module, procedure) Writes the string message to self % log_units with optional additional text.
- Arguments:
- selfclass(logger_type), intent(in)
The logger to which the message is written
- messagecharacter(len=*), intent(in)
A string to be written to LOG_UNIT
- modulecharacter(len=*), intent(in), optional
The name of the module containing the current invocation of log_warning
- procedurecharacter(len=*), intent(in), optional
The name of the procedure containing the current invocation of log_warning
Behavior
If time stamps are active, a time stamp is written, followed by module and procedure if present, then message is written with the prefix ‘WARN: ‘.
Example
module example_mod use stdlib_logger ... real, allocatable :: a(:) ... type(logger_type) :: alogger ... contains ... subroutine example_sub( size, stat ) integer, intent(in) :: size integer, intent(out) :: stat allocate( a(size) ) if ( stat /= 0 ) then write( message, '(a, i0)' ) & "Allocation of A failed with SIZE = ", size call alogger % log_warning( message, & module = 'EXAMPLE_MOD', & procedure = 'EXAMPLE_SUB' ) end if end subroutine example_sub ... end module example_mod
remove_log_unit (subroutine)#
-
subroutine remove_log_unit(self, unit, close_unit, stat) Remove the I/O unit from the self % log_units list. If close_unit is present and .true. then the corresponding file is closed. If unit is not in log_units then nothing is done. If stat is present it, by default, has the value success. If closing the unit fails, then if stat is present it has the value close_failure, otherwise processing stops with an informative message.
- Arguments:
- selfclass(logger_type), intent(inout)
The logger variable whose unit is to be removed
- unitinteger, intent(in)
The I/O unit to be removed from self
- close_unitlogical, intent(in), optional
A logical flag to close the unit while removing it from the SELF list
- statinteger, intent(out), optional
An error status. The possible values are success if no problems are found and close_failure if the close statement for unit fails.
Example
module example_mod use stdlib_logger ... type(logger_type) :: alogger contains ... subroutine example_sub(unit, ...) integer, intent(in) :: unit ... call alogger % remove_log_unit( unit ) ... end subroutine example_sub ... end module example_mod