Original Code Consulting


Log File Component
David Thomson
The Log File
Component is a small set of VI's that can be used for logging errors,
events, alarms, and notes for LabVIEW programs. It is
particularly useful for autonomous, unattended programs.
Additional error handling may (probably should) be included in the
program, but this component is an easy way to make sure that each error
or event gets archived with a time stamp into a common log file.
This document provides some information on how the Log File Component
can be used.
The design of this component is similar to the
design practice outlined in A
Software Engineering Approach to LabVIEW by Conway and
Watts. This implementation was developed mostly in parallel with
the LabVIEW Component Oriented Design (LCOD) proposed by Conway and
Watts, with some later features added directly from their
suggestions. As such, it is very modular and reuseable, and it
should be fairly easy to integrate into existing projects.
The main VI in this component is named the Log File
Component.vi. This VI can be placed throughout your program,
wherever an error or message can be generated, or it can be placed
within an error handling routine where errors from throughout the
program are handled. It has three inputs, Command, Log Message,
and Error To Log. The Command input can often be left unwired, as
it defaults to the Write Error command. Simply wire the error
output of any sub-vi to the Error To Log input and the VI will parse
the error, look up its description, time stamp it, open the log file,
write the error, and close the log file. To write a message,
alarm, event, or note to the log file, wire the Command input with a
Write Message constant, programmatically create the desired alarm,
event, or message string, and wire it to the Log Message input.
Besides Write Error and Write Message, the Command
input has No-Op, Initialize, and Close commands. The No-Op
command takes no action on the log file or the inputs. Besides
writing to the Log File, this component keeps a running memory of the
last 10 entries that it has written. Thus the No-Op command can
be used within a user-interface to acquire and display these
most-recent log file entries without having to access the log file on
disk. The Initialize command determines the name and path of the
log file and initializes the component (e.g. sets the memory of the
last 10 log items to an empty array). This command can be called
explicitely at the beginning of your program. However, this
component is self-initializing, so if it is called with a Write Error
or Write Message command without having been first initialized, it will
run its initialization procedure before executing the desired
command. The Close command should be called when the main program
finishes. This clears the component so that it will be forced to
reinitialize when the program next runs.
The Log File Component Caller.vi is an additional
feature of my component design. This is not an example of how the
component is used, but is a tool that can be incorporated into the main
program if desired. It is used mostly for debugging. It is
intended to be called dynamically as a top-level independent VI from
the main program upon operator request. It provides access to all
the functionality of the component, so that individual commands can be
executed at will. For more complex components that may depend on
other components or on complex inputs, this Caller may have limited
utility, but for the simple Log File Component, it can effectively be
used. Note that due to the way the Log File Component initializes
in this distribution, the Re-Initialize function of this Caller has
little utility.
Several changes should be made to the Log File
Component package before it is used in an application. Most
importantly, the initialization has been simplified from how it should
be handled for a real application. In this example distribution,
the parameters (Simulate/Use and Log File Path) are determined
programmatically or statically in the Log File Component diagram.
(The Log File Path is a date-stamped folder in the root directory of
C:.) This is merely for ease of distribution. Normally,
these parameters would be read from a configuration file. (See
the Configuration Files section on my website (www.originalcode.com,
under Programs) for an example of a flexible, robust configuration file
architecture.)
Another item to update before using these VI's is
how the Log File Component Caller is terminated. It has it's own
Done button that will cause it to close. It is also recommended
that it close automatically if the main program quits. The main
program could communicate this to all such Callers via a global, shared
variable, or some other mechanism.
The Simulate/Use parameter is of little
functionality in this Component, but is a general feature I include in
all my components. If it is set to Simulate, many of the commands
that would normally operate on the component's hardware (for a hardware
driver component, e.g.) would be either re-routed to the No-Op command
or would execute a subset of the functionality that did not attempt to
communicate with the hardware. This can be useful for testing the
component or even the larger application with the specific hardware
used by the component is not available.
The Custom Error Parser.vi included with this
distribution is used to parse the status, error code, source, and
description into a single string that can be written to the log
file. This VI uses the same error code database that General
Error Handler uses. It does not incorporate exception
handling. Custom error codes and descriptions can be added to the
Custom Error Parser.vi by putting them into the related front panel
controls and then saving those contents as defaults.
The Initialize command of the Log File Component
uses the Create Directory Structure.vi (also available separately on my
website) to ensure that the desired path for the log file actually
exists before the log file is created or written to. Also note
that each time this component writes to the log file, it opens the
file, writes, and closes the file. This is relatively
inefficient, but in most cases, the performance hit is
negligible. (Your mileage may vary, especially if you start
logging lots of errors or tend to log many, many messages.) The
reason for always opening and closing the file is to help ensure that
the log file is as up-to-date as possible in the case of a system
crash. One of the main reasons for logging errors is to diagnose
problems after they occur, so losing all or part of the log file during
a system crash would be less than ideal. Also note that if this
VI is called after another VI that can potentially generate errors, but
no error has been generated, then the Write Error command is
automatically diverted to the No-Op command. The No-Op command
does not access the log file, so in the (frequent) case where no error
was generated, there is no significant performance penalty incurred by
this component.
Please
report any bad links, other problems, or comments to:

|

|