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:

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