|
|
|
The JobLog Service Program
Back in the early 2000's, Bob Cozzi documented an api called Qp0zLprintf which allowed us to write a quick entry to the joblog from our program. I wrote a function wrapper around this api and placed it in a service program so that I could quickly write joblog entries from any program. Now, by simply adding two lines of code, any program can write entries to the joblog.
The first line of code needed is to copy the prototype for the JobLog_Write function into the program.
/copy QrpgleSrc, JobLog_P
Then, issue the JobLog_Write function in your program to write an entry to the joblog:
JobLog_Write( 'Write some data' );
The code is self-documenting, and it's so easy that I don't have to ever look up how to do this. I've placed this service program in my system binding directory so that it's always available to any of my ILE programs.
The function can return a value as well, which is the number of bytes written to the joblog during the operation. For example:
BytesWritten = JobLog_Write( 'Write This' );
The BytesWritten field should return 10, since there are 10 bytes in the passed string.
You can pass this function a 65535a Varying string, so that you can format the data contained within the string ahead of the call. For example:
JobLogInfo = 'Port ' + %char( PortNumber ) + ' is currently unavailable' );
JobLog_Write( JobLogInfo );
Prototype JOBLOG_P
The prototype for the JobLog_Write function is contained in a member called JobLog_P.
**************************************************************************
*
* J O B L O G P R O T O T Y P E S
*
* @copyrite 2004-2010 Michael Catalani
* 901.581.8791
*
**************************************************************************
/if defined( JOBLOG_P )
/eof
/endif
/define JOBLOG_P
D Qp0zLprintf PR 10I 0 ExtProc( 'Qp0zLprintf' )
D szOutputStg * Value Options( *String )
d JobLog_Write PR 10i 0
d JobLogInfo 65535a Varying Const
Not much to that. You can see the Qp0zLprintf prototype in this copy member as well. I never call this api directly, I call the JobLog_Write function to remove the complexity / extraneous code of the api call from my applications.
JOBLOG_S Service Program
**************************************************************************
*
* J O B L O G S E R V I C E P R O G R A M
*
* @copyrite 2004-2010 Michael Catalani
* 901.581.8791
*
* JobLog_Write - Writes a joblog entry.
* example: JobLog_Write( 'Write this data' );
*
**************************************************************************
h NoMain
/copy Qrpglesrc,JobLog_p
p JobLog_Write B Export
d JobLog_Write PI 10i 0
d JobLogInfo 65535a Varying Const
d LogData S 65535a Varying
d ErrorCode S 10i 0
/free
LogData = JobLogInfo + x'25';
ErrorCode = Qp0zLprintf( LogData );
return ErrorCode;
/end-free
p E
There's not a lot to the service program at all. You might notice that the function is appending a line feed (x'25') at the end of the string of data to write to the joblog. That's because, without this, the api will not write data with this api until it receives a linefeed. (If you are just curious, you could write some code that did a couple of calls to the api directly without specifying the linefeed, check the joblog, and see nothing there. Then do one more write with the linefeed, and suddenly it all shows up.) That's one of the reasons I prefer using this wrapper, so I dont have to remember to append the line feed each time I write something to the joblog, as the function takes care of that for me.
Also, being a C api, the string passed to the Qp0zLprintf api needs to be NULL terminated. We do that by specifying Options(*STRING) on the prototype to the api, so that the prototype call will handle placing a NULL character at the end of the string automatically for us.
Here's a sample program that calls the JobLog_Write function. Because my JobLog_S service program has been added to my system binding directory "CF", I simply need to specify that binding directory on the BndDir keyword on the "H" Spec. If you use a different named binding directory (and you probably will), change the BndDir keyword to the correct binding directory name. If you dont have the service program added to a binding directory at all, then remove the BndDir keyword altogether and specify the service program by prompting the compile command.
h DftActGrp( *No ) ActGrp( *NEW ) BndDir( 'CF' )
/copy Qrpglesrc,JobLog_p
/free
JobLog_Write( 'Program Called At ' + %char( %TimeStamp ));
*inlr = *on;
Sure, it's a quick little service program. However, it makes it very easy to add entries to a joblog. Although it works for all programs, I especially like adding this feature to server programs running on my system. If a server program wakes up every so often to perform some task, I can write an entry to the joblog that states what was performed. For example,
JobLog_Write( 'Processed ' + %char( Count ) + ' Order Records Into The History File At ' + %char( TimeStamp ) );