query regarding accessing log files and dumping them

Post questions here relative to DataStage Enterprise/PX Edition for such areas as Parallel job design, Parallel datasets, BuildOps, Wrappers, etc.

Moderators: chulett, rschirm, roy

Post Reply
chiranjeevi
Participant
Posts: 6
Joined: Tue Nov 23, 2004 4:11 am

query regarding accessing log files and dumping them

Post by chiranjeevi »

Hello all and ray.wurlod,



hi,
i have seen the code for the above mentioned subject posted by ray.wurlod.
while going through the code ,i could'nt understand a few lines.


ArchiveLine = LogRecord ; * Timestamp
ArchiveLine := " " : LogRecord : " " ; * severity
code
* [1.0.2]
* FullText = Subr("DSR_MESSAGE", LogID, LogRecord, Raise(LogRecord))
FullText = Subr("*DataStage*DSR_MESSAGE", LogID,
LogRecord, Raise(LogRecord))
* [1.0.1]
* FullText = Ereplace(FullText, @VM, "(A)", -1, -1)
FullText = Ereplace(FullText, @VM, LF, -1, -1)
ArchiveLine := FullText
WriteSeq ArchiveLine To ArchiveLog.Fvar


the above code is a part of what ray.wurlod. have given.
is the above code properly formatted??????.
and if so , the functions
Raise(LogRecord),
Subr("DSR_MESSAGE", LogID, LogRecord, Raise(LogRecord))

are these builtin functions or user defined somewhere????? .
what does @VM signify in the function Ereplace(FullText, @VM, LF, -1, -1)

please help me by replying,
awaiting for ur reply,
chiranjeevi


for ur convenience i have provided the entire code posted by ray.wurlod. below


the code::::::code to archive ur log files

Code:
>
> SUBROUTINE ArchiveLog(InputArg, ErrorCode)
>
> DEFFUN GetJobNumber(Arg1) Calling "DSU.JobNumber"
>
> $INCLUDE UNIVERSE.INCLUDE FILEINFO.H
> EQUATE ArchiveDir To "/u03/dsdata/logarchive"
> EQUATE LF TO "+"
>
> ErrorCode = 0 ; * set this to non-zero to stop
> the stage/job
> RoutineName = "ArchiveLog"
>
> * InputArg is the name of the job whose log file is to be archived.
> JobName$ = InputArg
>
> * Initialize file variables
> ArchiveLog.Fvar = 0
> JobLog.Fvar = 0
>
> * Ensure that job name is given
> If IsNull(JobName$) Or Trim(JobName$) = ""
> Then
> Message = No job name given.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
>
> * Determine job number (and, as a side effect, that the job name
> * is valid for the project)
> JobNo = GetJobNumber(JobName$)
> If IsNull(JobNo)
> Then
> Message = Job name (":JobName$:") is not valid for this
> project.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
>
> * Create archive log file name and open it. Position to end of file
> * if archive log file already exists.
> LogFileName = ArchiveDir : "/" : JobName$
> OpenSeq LogFileName To ArchiveLog.Fvar
> On Error
> Message = Fatal error opening ":LogFileName:" file.
> Message = Error code = :Status()
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> Locked
> Message = Unable to open log file ":LogFileName:".
> Message = It is already in use by DataStage process
> #:Status():.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> Then
> * Position to end of file
> Seek ArchiveLog.Fvar,0,2
> Else
> Message = Unable to position to end-of-file
> in":LogFileName:".
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> End
> Else
> If Status() = 0
> Then
> * File opened OK but does not yet exist. Create it.
> Create ArchiveLog.Fvar
> Else
> Message = Unable to create file ":LogFileName:".
> Call DSLogWarn(Message, RoutineName)
> GoTo MainExit
> End
> End
> Else
> Message = Unable to open log file ":LogFileName:".
> Message = Incorrect file type or non-existent directory.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> End
>
> * Open job log file (this is a hashed file)
> JobLogName = "RT_LOG" : JobNo
> Open JobLogName To JobLog.Fvar
> On Error
> Message = Fatal error opening ":JobLogName:" file.
> Message = Error code = :Status():.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> Then
> End
> Else
> Message = Unable to open log file ":JobLogName:".
> Message = Error code = :Status():.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
>
> * Ensure no other process is using the log file. This is
> * usually indicative that the job is running.
> FileLock JobLog.Fvar
> On Error
> Message = Fatal error attempting to lock ":JobLogName:" file.
> Message = Error code = :Status():.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> Locked
> Message = Unable to lock log file for job :JobName$:.
> Message = Check that job is not running.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
>
> * Whew! Thats all the idiot-proofing done. Now we can archive the
> log.
> * In the log file, field 1 is the message severity (an integer),
> * field 10 is the message text, which can contain printf style
> parameters,
> * and field 5 is a list of parameter values. Fields 10 and 5 are
> multi-
> * valued. Field 3 is a timestamp, already in timestamp format.
>
> * In the output (the archive) we record the timestamp, the severity
> and
> * the full text of the message. Timestamp is in columns 1-19,
> * severity is
> * in column 21, and the message itself begins in column 23. Lines of
> * multiple line messages are separated by (A).
>
> * Form a Select List of log records in logged order. Since the log
> file
> has
> * a generated sequential numeric key, we can use this.
> SSELECT JobLog.Fvar
>
> * Process this list, bypassing any records that do not have a numeric
> key
> * (these are control records, like //PURGE.PARAMS and //SEQUENCE.NO).
> Loop
> While ReadNext LogID
> If Num(LogID)
> Then
> Read LogRecord From JobLog.Fvar,LogID
> On Error
> Message = Fatal error reading record ":LogID:" from
> job log.
> Message = Job name = ":JobName$:", log file
> is":JobLogName:".
> Message = Error code = :Status():.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> Then
> ArchiveLine = LogRecord ; * Timestamp
> ArchiveLine := " " : LogRecord : " " ; * severity
> code
> * [1.0.2]
> * FullText = Subr("DSR_MESSAGE", LogID, LogRecord,
> Raise(LogRecord))
> FullText = Subr("*DataStage*DSR_MESSAGE", LogID,
> LogRecord, Raise(LogRecord))
> * [1.0.1]
> * FullText = Ereplace(FullText, @VM, "(A)", -1, -1)
> FullText = Ereplace(FullText, @VM, LF, -1, -1)
> ArchiveLine := FullText
> WriteSeq ArchiveLine To ArchiveLog.Fvar
> Else
> Message = Unable to append to log
> file":LogFileName:".
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> End
> Else
> Message = Selected record ":LogID:" not found
> in":JobLogName:" file.
> Call DSLogWarn(Message, RoutineName)
> End
> End
> Repeat
> FileUnlock JobLog.Fvar
>
> MainExit:
> * Close any open files
> If FileInfo(ArchiveLog.Fvar, FINFO$IS.FILEVAR)
> Then
> CloseSeq ArchiveLog.Fvar
> End
> If FileInfo(JobLog.Fvar, FINFO$IS.FILEVAR)
> Then
> Close JobLog.Fvar
> End
>
> RETURN
ray.wurlod
Participant
Posts: 54607
Joined: Wed Oct 23, 2002 10:52 pm
Location: Sydney, Australia
Contact:

Post by ray.wurlod »

The code works, and was properly formatted (by being wrapped in Code tags) when originally published.

The routine *DataStage*DSR_MESSAGE is an internal DataStage subroutine that mimics the behaviour of the printf range of functions in C as well as being able to find the "translated" version of the message in the resource table (e.g. DS_RESENU, DS_RESJPN). I found it by examining some of the source code that ships with DataStage and felt it would be a good way to construct message text that needed parameters.

@VM is a system variable. It represents a "value mark", which is the delimiter character in a multi-valued field (list). When FullText is calculated via the subroutine call, each line is delimited from the next by this character. The Ereplace function converts them to conventional line feed characters (for UNIX line termination).
IBM Software Services Group
Any contribution to this forum is my own opinion and does not necessarily reflect any position that IBM may hold.
chiranjeevi
Participant
Posts: 6
Joined: Tue Nov 23, 2004 4:11 am

Post by chiranjeevi »

hi ray,
thanks for replying but in am still confused,
i am not able to understand the code from the following lines.

what significance is that *[1.0.1] and * [1.0.2] having???
are they simple comments.???
i am new to programming inBASIC,so can u explain me what the below code is doing in detail.
if i want to get only the type and the event field from the datastage log then how should i modify the code...
please help me in this regard,
awaiting for ur reply,
chiranjeevi

THE CODE

Loop
> While ReadNext LogID
> If Num(LogID)
> Then
> Read LogRecord From JobLog.Fvar,LogID
> On Error
> Message = Fatal error reading record ":LogID:" from
> job log.
> Message = Job name = ":JobName$:", log file
> is":JobLogName:".
> Message = Error code = :Status():.
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> Then
> ArchiveLine = LogRecord ; * Timestamp
> ArchiveLine := " " : LogRecord : " " ; * severity
> code
> * [1.0.2]
> * FullText = Subr("DSR_MESSAGE", LogID, LogRecord,
> Raise(LogRecord))
> FullText = Subr("*DataStage*DSR_MESSAGE", LogID,
> LogRecord, Raise(LogRecord))
> * [1.0.1]
> * FullText = Ereplace(FullText, @VM, "(A)", -1, -1)
> FullText = Ereplace(FullText, @VM, LF, -1, -1)
> ArchiveLine := FullText
> WriteSeq ArchiveLine To ArchiveLog.Fvar
> Else
> Message = Unable to append to log
> file":LogFileName:".
> Call DSLogWarn(Message, RoutineName)
> ErrorCode = -1
> GoTo MainExit
> End
> End
> Else
> Message = Selected record ":LogID:" not found
> in":JobLogName:" file.
> Call DSLogWarn(Message, RoutineName)
> End
> End
> Repeat
> FileUnlock JobLog.Fvar
ray.wurlod
Participant
Posts: 54607
Joined: Wed Oct 23, 2002 10:52 pm
Location: Sydney, Australia
Contact:

Post by ray.wurlod »

Any statement beginning with an asterisk is a comment. Comments do not generate executable code.

The notation [1.0.2] refer to versions of the code as recorded in the history block at the top of the code, which you elected not to re-post. I always mark changes to code in this way.
IBM Software Services Group
Any contribution to this forum is my own opinion and does not necessarily reflect any position that IBM may hold.
Post Reply