4.7 Logging

A simple logging module has been added to the software in order to assist BESTPRED users who encounter problems. This section of the manual describes the use of the logging module and the contents of the logfile; parameters specific to this module are described in Section 5.4.

There are two steps in logging an event: you first create a string that contains the message you want to write to the logfile, and you then call the LogMessage subroutine. (LogMessage will automatically prepend the correct timestamp; it's smart like that.) You will no doubt be tempted to skip creating the string containing the message, supposing that you will just pass it as a string literal in the subroutine call. If you do that each log entry will be padded out to the 80 characters with nulls, and your logfile will be a nightmare to read. Trust me. And don't assume that little feature is documented in most Fortran 90 books, either. Here's a very simple code snippet:

LogMessage = 'The quick brown fox jumped over the lazy dogs.'
call log_message(LOGfile,LogMessage)
LOGfile is the base name for the logfile, and is limited to 64 characters. The date and the string .log are appended to LOGfile to create the file name (e.g. logfile.20080807.log).

Of course, it's not for nothing that we provide the LOGon parameter, which toggles logging on and off, so perhaps we should respect the user's wishes and check it:

if ( LOGon == 1 ) then
  LogMessage = 'The quick brown fox jumped over the lazy dogs.'
  call log_message(LOGfile,LogMessage)
end if
You may want to add your own debugging code to BESTPRED. If you do so, you may want to check the LOGfreq parameter while inside of the bestpred() subroutine. It provides you finer-grained control of logging than on/off by specifying the frequency with which messages should be logged.
if ( LOGon == 1  .and. LOGfreq > 0 ) then
  LogMessage = 'This message is printed every time bestpred() is entered.'
  call log_message(LOGfile,LogMessage)
end if
You can get clever with the MOD() function and print only messages from specific iterations through the subroutine. For example, the following message is printed only the first time the subroutine is entered:
if ( LOGon == 1 .and. LOGfreq > 0 .and. mod(ncall,LOGfreq) == 0 ) then
  LogMessage = 'Allocating arrays in call '//trim(char(ncall+ICHAR('0')))
  call log_message(LOGfile,LogMessage)
end if
This message is logged for every LOGfreq-th record processed:
if ( LOGon == 1 .and. LOGfreq > 0 .and. mod(ncall,LOGfreq) == 0 ) then
  LogMessage = 'Allocating arrays in call '//trim(char(ncall+ICHAR('0')))
  call log_message(LOGfile,LogMessage)
end if
The following logfile is from an actual run of BESTPRED with LOGon = 1 and LOGfreq = 1. The contents are pretty self-explanatory.
[jcole@aipl3850 bestpred_onepass]$ cat example.20080807.log
# example.20080807.log created on 08/07/2008 at 10:31:41
[10:31:41]: Starting BESTPRED 2.0b9
[10:31:41]: Allocating matrices for means, SD, and covariances
[10:31:41]: Allocating arrays in call 0
[10:31:41]: Converting from lbs to kg for interal calculations
[10:31:41]: Calling interpolate with method W and breed 4
[10:31:41]: Calling interpolate with method W and breed 4
[10:31:41]: Calling interpolate with method W and breed 4
[10:31:41]: Calling interpolate with method W and breed 4
[10:31:43]: Calling interpolate with method W and breed 4
[10:31:43]: Calling interpolate with method W and breed 4
[10:31:43]: Calling interpolate with method W and breed 4
[10:31:43]: Calling interpolate with method W and breed 4
The first line of every logfile includes the filename and its date and time of creation. Each log entry is prepended with a timestamp. Messages longer than 80 characters will be truncated to 80 characters, not inclusive of the timestamp.

See About this document... for information on suggesting changes.