flibs/m_multilog - Manage multiple log files
The module m_multilog provides a logging type with a set of type bound procedures and other methods to manage one or more log files. The module and its test program are based on the m_logger module (including unit test) which is part of the flibs library. For applications in need of only one log, m_logger is the recommended module.
The goal of this component is to provide a way to write messages both on standard output and on one or more log files, so that a trace of the execution - with desired level of detail - can be read by the user after the execution.
One single statement should be able to write to all open log files with appropriate log level set. Example:
call log_msg ('Log message', WARNING)
will write to logs with log level equal to or lower than WARNING, i.e. WARNING, INFO and FINE.
The module provides methods to
connect a file to a log object
configure the logging process, for example disable the standard output messages or enable time stamps,
log messages,
group log objects,
write log messages to a group of log objects.
Individual logs are started with log_t%startup (filename [,options]). The method takes the log file name as first argument: its main purpose is to connect the log to the file. Optional arguments: log information level, append true/false
Logs can be added to the log group with "add_log". Logs can be removed from the log group using the "remove_log" method, which will also close the file connected to the log.
The messages are sent to one or more of the active logs with the static method "log_msg". Infolevel is an optional argument to log_msg, if left out it's set to ALL which means that the message will be written to all logs.
In the following example, extracted from the unit tests of m_multilog provided with the project, one connects the file "test_m_multilog.log" to the log, two messages of which only the first should be written to file and shut down the logging system.
type (log_t) :: test call test%startup ( 'test_m_multilog.log' , INFO ) call add_log ( test ) call log_msg ( 'First message' , INFO ) call log_msg ( 'Second message', FINE ) call shutdown_log_group ()
By default, the logging is done on all log files with appropriate infolevel and on standard output. The user may want to configure the behaviour of the log_group so that message are not written on standard output.
The static method log_configure(option,value [,log]) is the central point to configure the log group. It takes a character "option" string and a "value" as arguments. In the following example, one writes messages on file and in some cases also to stdout, with and without time stamps.
type (log_t) :: test call test%startup ( 'test_m_multilog.log' ) call add_log ( test ) call log_configure ( "writeonstdout" , .false. ) call log_msg( 'This message is written only on file' ) call log_configure ( "writeonstdout" , .true. ) call log_msg( 'This message is written both on screen and on file' ) call shutdown_log_group ()
Public types and parameters:
Defines a log file to write to. It is opened via the startup method.
Different levels of logging information. Messages are only written to the log file if they have a level equal to or higher than the level for the file. The level "ALL" indicates messages that are written to any file.
Different delimiters for the information in the log files. The routine log_delimiter writes the corresponding delimiting string to the log file(s).
The module provides the following methods per logging object (type(log_t)):
Initialises the log, connect it to the given filename and set default values.
The logging object.
Name of the log file
If present and true, then the messages will be appended to the end of the log file. If present and false, then the initialization of the log overwrites the messages of the previous logging session.
If not provided, the default value is append=.true.
If present, set log_t%infolevel to the provided value If not present, set to default value INFO.
Shotdown the log
Log the given character string to one logging unit. If the logging to standard output is enabled, writes the message on standard output.
If the logging to the log file is enabled, writes the message into the log file.
Before outputting directly the message string, the string is trimmed, that is to say that all trailing blanks are removed from the string.
If the time stamp option is enabled, a time stamp with format "year-month-day hh:mm:ss" is inserted before the message. Note: Before outputting directly the message string, the string is trimmed, that is to say that all trailing blanks are removed from the string.
The logging object.
Log message to be written
If present, set log_t%infolevel to the provided value If not present, set to default value INFO.
The module provides the following routines for the global log handler:
Close all logs connected to the log_group object
] Add a log_t object to the log group. Up to four log objects can be added.
log log_t object (initialized with log_t%startup)
] Remove a log_t object from the log group.
log_t object (initialized with log_t%startup)
Log the given character string to all logging units with relevant info_lvl. If no info_lvl is specified, ALL is used (write to all logs).
If the logging to standard output is enabled, writes the message on standard output as well as to relevant log files. Before outputting directly the message string, the string is trimmed, that is to say that all trailing blanks are removed from the string.
If the time stamp option is enabled, a time stamp with format "year-month-day hh:mm:ss" is inserted before the message.
Log message to be written
Optional: log information level, default = INFO
Set all internal settings to default values.
log to reset, if not provided all logs are reset
Set the logical static option of the component to value. The option is set for the log object if given, otherwise it is set for the log group as a whole.
The option may be one of the following.
option = "timestamp" : Disable or enable the insertion of time stamps. If the time stamp option is enabled, a time stamp with format "year-month-day hh:mm:ss" is inserted before the message.
option = "writeonstdout" : Disable or enable the writing on standard output.
option = "writeonlogfile" : Disable or enable the writing on log file.
option = "stoponerror" : Configure the behaviour of the component whenever an error is met. If stoponerror is true, then the execution stops if an error is encountered. If stoponerror is false, then the execution continues if an error is encountered. In both cases, a message is displayed on standard output.
Configure the integer static option of the component. The option is set for the log object if given, otherwise it is set for the log group as a whole.
The option may be one of the following.
option = "logfileunit" : Force the logical unit for logging to be value. Use this feature with caution, since the original logical unit is lost.
Set the character static "option" of the component to "value". The character options are global, so independent of the log objects.
The "option" may be one of the following.
option = "level_string_volume" Set the string used for volume delimiter.
option = "level_string_chapter" Set the string used for chapter delimiter.
option = "level_string_section" Set the string used for section delimiter.
option = "level_string_subsection" Set the string used for subsection delimiter.
Get the logical static "option" of the component. The option is retrieved for the log object if given, otherwise it is retrieved for the log group as a whole.
The option may be one of the following.
option = "timestamp" : Current value of the option to enable / disable insertion of time stamps.
option = "writeonstdout" : Current value of the option to enable / disable writing on standard output.
option = "writeonlogfile" : Current value of the option to enable / disable writing on log file.
option = "stoponerror" : Current value of the option to enable / disable stopping when an error is met.
Get the integer static "option" of the component. The option is retrieved for the log object if given, otherwise it is retrieved for the log group as a whole.
option = "logfileunit" : Current logical unit connected to the logging system.
Get the character static "option" of the component. The character options are global, so independent of the log objects. The log argument is therefore not used, it has been added for uniformity.
The "option" may be one of the following.
option = "level_string_volume" Get the string used for volume delimiter.
option = "level_string_chapter" Get the string used for chapter delimiter.
option = "level_string_section" Get the string used for section delimiter.
option = "level_string_subsection" Get the string used for subsection delimiter.
The order of the info levels - should it be different?
Possibility to define own info levels and/or re-configure the standard ones?
Copyright © 2012 Karin Nyström knystrom at users.sourceforge.net