Managing Deployed Application Output with Message Handlers
Guest blogger Peter Webb returns with another in an occasional series of postings about application deployment.
Contents
Two Output Streams
Programs running in interactive MATLAB send error, warning and informational text messages to the MATLAB command window. By default, deployed applications output text to the standard output and standard error streams.
In many cases, particularly for console applications on Windows and UNIX, this works well enough: the output appears in the DOS window or UNIX terminal. However, non-console applications (and any type of shared library or builder component) may be unable to access either of the standard output streams; messages sent to those streams will be lost. To avoid losing messages when the standard streams are unavailable, deployed applications register output and error message handlers. A message handler directs formatted text messages to a persistent or visible location, typically a log file or an output window.
In this post, I'll show you how to send both error and informational messages to a log file.
A Function with Output
To demonstrate output redirection, I wrote the sendmessages function, which displays an informational message and a warning, and then issues an error:
function sendmessages(info, warn, err) disp(info); warning(warn); error(err);
In order to follow the rest of this posting, you'll need the source code from MATLAB Central, particularly the C main program, log.c. See logREADME in the ZIP file for a complete description of distributed files and step-by-step directions for building the application.
Where are the Handlers?
Create a C shared library from the example function with MATLAB Compiler:
mcc -Ngv -W lib:libmsgfcn -T link:lib sendmessages.m
Open the generated wrapper file, libmsgfcn.c, in a text editor. The wrapper file contains two default handlers, mclDefaultErrorHandler and mclDefaultPrintHandler. The generated code contains two library initialization functions: libmsgfcnInitialize and libmsgfcnInitializeWithHandlers. You redirect program output by passing your custom message handlers to libmsgfcnInitializeWithHandlers. All message handlers conform to the same interface:
static int MessageHandler(const char *message)
You never need to call the message handler directly. The MATLAB Compiler Runtime (MCR) calls your message handler automatically.
Logging Messages to a File
A common use for a message handler is to record messages and the time they occurred in a log file. This type of message handler requires only a few lines of C code:
static FILE *logFile = NULL;
static int LogFileHandler(const char *s) { if (logFile != NULL) { time_t now = time(NULL); fprintf(logFile, "%s", ctime(&now)); fprintf(logFile, "%s\n", s); } }
Your main program needs to open and close the log file, of course. Open the log file before calling the library initialization function and close it after calling mclTerminateApplication. See the full implementation in log.c.
Build the application with mbuild:
(UNIX): mbuild -g log.c -L. -lmsgfcn
(Windows): mbuild -g log.c libmsgfcn.lib
Run it from a DOS shell or UNIX terminal window:
(UNIX): ./log "information" "look out!" "oops."
(Windows): log "information" "look out!" "oops."
The example program creates the log file MessageLog.txt to capture program output.
Fri Aug 19 11:53:32 2011 information
Fri Aug 19 11:53:32 2011 Warning: lookout! > In sendmessages at 3
Fri Aug 19 11:53:32 2011 Error using sendmessages (line 4) oops.
Next time, I'll show you how to display log messages in a persistent window, and how to distinguish between errors and informational messages. In the meantime, let me know how your applications manage output. Does your code need to distinguish between program output and error messages?
- カテゴリ:
- Deployment