;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; ;
; Copyright 2013 Fidelity Information Services, Inc ;
; ;
; This source code contains the intellectual property ;
; of its copyright holder(s), and is made available ;
; under a license. If you do not know the terms of ;
; the license, please stop and do not read further. ;
; ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONFIGURATION START ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; InfoHub paths to include in the key of the returned string; should be in the order in which they are to
; be appended to the resultant string.
AllMessagePath ; 314
GtmMessagePath ; 159
FatalMessagePath ; 265
GtmsecshrMessagePath ; 358
KillMessagePath ; 979
FailMessagePath ; 323
IndividualMessagePath ; 0
; Delimiter string between the key and the value in the returned data.
; ...
Delimiter ; $char(30)
; Delimiter string between the fields within the returned value.
; is delimited by FieldDelimiter, for IndividualMessagePath and error messages
FieldDelimiter ; $char(31)
; Substitution characters for a tab and a newline in the syslog on the current platform.
Tab ; $char(9)
Newline ; ", "
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; CONFIGURATION END ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Invoked prior to a new file getting processed, this function picks up a few configuration options and sets the ;
; suppplementary information for message processing and argument extraction in particular. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
PreExpr(%l)
do doWrite^InfoHubUtils("In PreExpr") ;#
; We only want PreExpr to be invoked once, so quit on subsequent file rotations.
quit:($get(^flgInitialized,0)) ""
set ^flgInitialized=1
; New used variables for scope separation.
new foundBeginning,filterPosition,line,i,label,setCommand
; Read in the configuration from the top of this module. For that go over every line and process it depending on whether it is a
; path-related setting or not. For path-related settings the order in which they appear is the order in which they are appended
; to the string this gleaner returns in InfoExpr.
set (foundBeginning,filterPosition)=0
for i=1:1 set line=$text(@("+"_i)) quit:(line["CONFIGURATION END") set:(line["CONFIGURATION START") foundBeginning=1 do:foundBeginning
. set label=$$getLabel^InfoHubUtils(line)
. do doWrite^InfoHubUtils(" label is "_label) ;#
. quit:(""=label)
.
. if (label["Path") do
. . set setCommand="^flg"_label_"=+"_$$getCommentArg^InfoHubUtils(line)
. . do doWrite^InfoHubUtils(" path setCommand1 is "_setCommand) ;#
. . set @setCommand
. .
. . set setCommand="^flg"_label_"(""pos"")="_$increment(filterPosition)
. . do doWrite^InfoHubUtils(" path setCommand2 is "_setCommand) ;#
. . set @setCommand
. else do
. . set setCommand="^flg"_label_"="_$$getCommentArg^InfoHubUtils(line)
. . do doWrite^InfoHubUtils(" path setCommand is "_setCommand) ;#
. . set @setCommand
set ^flgNumOfPaths=filterPosition
; Prepare message-processing clues.
do setMsgInfo^messages
quit ""
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Invoked for every line read, this function returns a string that encodes various information about the syslog ;
; message, such as whether it is from GT.M or not, the originating facility and address, mnemonic, severity, number ;
; of arguments, and the value of each argument. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
InfoExpr(%l)
do doWrite^InfoHubUtils("In InfoExpr") ;#
; New used variables for scope separation.
new fullMessage,i,j,length,allGtm,timeBlock,time,part,pos,pid,quit,isGtmMessage,posStart,posEnd,mnemonic
new prefix,postfix,from,start,pos,count,message,failure,delimiter,returnValue
; Find out whether this message is coming from GT.M.
set isGtmMessage=%l?.E1"GTM".2(1"-"1.10U).10U.5N1"["1.10N1"]: %".E
; Reporting is very simple for non-GT.M messages.
quit:('isGtmMessage) ^flgAllMessagePath_^flgDelimiter_%l
; Copy the full message because of the subsequent mangling.
set fullMessage=%l
; If there is more than one '%GTM-'-delimited part, we might be dealing with a multi-line message,
; so make sure to break the message down into individual parts correctly.
set length=$length(%l,": %GTM-")+$select((": "'=^flgNewline):($length(%l,^flgNewline_"%GTM-")-1),1:0)
set allGtm=(length>1)
do doWrite^InfoHubUtils(" allGtm: "_allGtm_"; length: "_length) ;#
; Try to extract the timestamp.
set time=""
for i=3:1:4 set timeBlock=$piece(%l," ",1,i) set:(timeBlock?1U2L1.2" "1.2N1" "2N1":"2N1":"2N) time=timeBlock
;if (""=time) do IHError^FileLine("Not able to find the timestamp.")
quit:(""=time) ^flgFailMessagePath_^flgDelimiter_%fullMessage_^flgFieldDelimiter_"Not able to find the timestamp."
; Try to extract the process ID.
set (start,posStart)=$find(%l,"[")
;if ('posStart) do IHError^FileLine("Not able to find the process ID.")
quit:('posStart) ^flgFailMessagePath_^flgDelimiter_%fullMessage_^flgFieldDelimiter_"Not able to find the process ID."
set posStart=$find(%l,"]: %",posStart)
;do:('posStart) IHError^FileLine("Not able to find the beginning of a GT.M message.")
quit:('posStart) ^flgFailMessagePath_^flgDelimiter_%fullMessage_^flgFieldDelimiter_"Not able to find the beginning of a GT.M message."
set pid=+$extract(%l,start,posStart)
set prefix=$extract(%l,0,posStart-2)
set %l=$extract(%l,posStart-1,$length(%l))
set:allGtm %l=^flgNewline_%l
; Get the "generated from ..." part and remove it from the message.
set from=" -- generated from "
set postfix=""
set quit=0
for start=$length(%l):-1:1 do quit:quit
. set pos=$find(%l,from,start)
. set:pos message("from")=$extract(%l,pos,$length(%l)),%l=$extract(%l,1,start-1),postfix=from_message("from"),quit=1
; Before starting to concatenate the return value, set it to an empty string.
set returnValue=""
for i=1:1:length do
. set quit=0
.
. ; In case this message contains only '%GTM-'-type part(s), skip the first (empty) part.
. quit:(allGtm&(1=i))
.
. ; Get the current message part.
. set part=$piece(%l,(^flgNewline_"%GTM-"),i)
.
. ; Start with empty return value parts.
. for j=1:1:^flgNumOfPaths set returnValue(j)=""
.
. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
. ; The following block is to report any message in its entirety. ;
. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.
. ; In case we have delimited the message by '%GTM-', we need to prepend the delimiter. Also start
. ; setting the returnValue by including the key and the full message.
. set pos=^flgAllMessagePath("pos")
. set:(allGtm) returnValue(pos)="%GTM-"
. set returnValue(pos)=^flgAllMessagePath_^flgDelimiter_prefix_returnValue(pos)_part_postfix
.
. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
. ; The following block is to report any GT.M message in its entirety. ;
. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.
. ; In case we have delimited the message by '%GTM-', we need to prepend the delimiter. Also start
. ; setting the returnValue by including the key and the full message.
. set pos=^flgGtmMessagePath("pos")
. set:(allGtm) returnValue(pos)="%GTM-"
. set returnValue(pos)=^flgGtmMessagePath_^flgDelimiter_prefix_returnValue(pos)_part_postfix
.
. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
. ; The following block is to report a processed GT.M message, which might be of interest to the ;
. ; receiving party, depending on the current InfoHub configuration. ;
. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
.
. ; Advance to the severity bit.
. set posStart=$find(part,"-")
. ;do:('posStart) IHError^FileLine("Severity bit not found in a GT.M message.")
. if ('posStart) do
. . set pos=^flgFailMessagePath("pos")
. . set returnValue(pos)=^flgFailMessagePath_^flgDelimiter_%fullMessage_^flgFieldDelimiter_"Severity bit not found in a GT.M message."
. . set quit=1
. ; do doWrite^InfoHubUtils(" first hyphen found") ;##
. quit:quit
.
. ; Find the end position of the mnemonic block.
. set posEnd=$find(part,", ",posStart)
. ;do:('posEnd) IHError^FileLine("Textual part not found in a GT.M message.")
. if ('posEnd) do
. . set pos=^flgFailMessagePath("pos")
. . set returnValue(pos)=^flgFailMessagePath_^flgDelimiter_%l_^flgFieldDelimiter_"Textual part not found in a GT.M message."
. . set quit=1
. ; do doWrite^InfoHubUtils(" end of mnemonic block found") ;##
. quit:quit
.
. ; Get the mnemonic.
. set mnemonic=$extract(part,posStart,posEnd-3)
. ; do doWrite^InfoHubUtils(" mnemonic is "_mnemonic) ;##
.
. ; If we have preset info on the message, process it, also extracting individual arguments.
. set count=0,quit=0
. if ($data(^flgMessages(mnemonic))) do
. . merge message=^flgMessages(mnemonic)
. . set count=^flgMessages(mnemonic,"args")
. . if (0'=count) do
. . . ; Extract arguments out of the message part sans the mnemonic piece.
. . . set failure=$$parseArgs($extract(part,posEnd,$length(part)),mnemonic,count,.message)
. . . ;do:failure IHError^FileLine("Failed to parse message arguments for '"_part_"'.")
. . . if (failure) do
. . . . set pos=^flgFailMessagePath("pos")
. . . . set returnValue(pos)=^flgFailMessagePath_^flgDelimiter_%l_^flgFieldDelimiter_"Failed to parse messages arguments for '"_part_"'."
. . . . set quit=1
. if ('$data(^flgMessages(mnemonic))) do
. . set pos=^flgFailMessagePath("pos")
. . set returnValue(pos)=^flgFailMessagePath_^flgDelimiter_%l_^flgFieldDelimiter_"Unrecognized mnemonic "_mnemonic_"."
. . set quit=1
. ;else do IHError^FileLine("Unrecognized mnemonic '"_mnemonic_"'.")
.
. quit:quit
.
. ; In case we have delimited the message by '%GTM-', we need to prepend the delimiter. Also start
. ; setting the returnValue by including the key and the full message.
. set pos=^flgIndividualMessagePath("pos")
. set:(allGtm) returnValue(pos)="%GTM-"
. set returnValue(pos)=returnValue(pos)_part_postfix
.
. ; Set the extracted information about the message.
. set returnValue(pos)=returnValue(pos)_^flgFieldDelimiter_time
. set returnValue(pos)=returnValue(pos)_^flgFieldDelimiter_$get(message("facility"))
. set returnValue(pos)=returnValue(pos)_^flgFieldDelimiter_mnemonic
. set returnValue(pos)=returnValue(pos)_^flgFieldDelimiter_$get(message("severity"))
. set returnValue(pos)=returnValue(pos)_^flgFieldDelimiter_$get(message("from"))
. set returnValue(pos)=returnValue(pos)_^flgFieldDelimiter_$get(pid)
. set returnValue(pos)=returnValue(pos)_^flgFieldDelimiter_count
. if (0"=postChars)) set endPos=$length(message)
. else do
. . set endFound=0
. . for searchStart=searchStart:-1:1 quit:endFound do
. . . ; do doWrite^InfoHubUtils(" @"_searchStart_"...") ;##
. . . set endPos=$find(message,postChars,searchStart)
. . . set:(endPos&(endPos<=searchLimit)) endPos=searchStart-1,endFound=1
. . . ; do:endFound doWrite^InfoHubUtils(" found arg end: "_endPos) ;##
. . if ('endFound) set quit=1
. . else set searchLimit=endPos+1
. quit:quit
.
. ; do doWrite^InfoHubUtils(" found arg end: "_endPos) ;##
.
. set preChars=$translate(^flgMessages(mnemonic,"args",i,"preChars"),$char(9),^flgTab)
. ; do doWrite^InfoHubUtils(" looking for '"_preChars_"' starting @"_searchStart) ;##
. if ((1=i)&(""=preChars)) set startPos=1
. else do
. . set startFound=0
. . for searchStart=searchStart:-1:1 do quit:startFound
. . . ; do doWrite^InfoHubUtils(" @"_searchStart_"...") ;##
. . . set startPos=$find(message,preChars,searchStart)
. . . set:(startPos&(startPos<=searchLimit)) startFound=1
. . if ('startFound) set quit=1
. . else set searchLimit=startPos
. quit:quit
.
. ; do doWrite^InfoHubUtils(" found arg start: "_startPos) ;##
.
. set var("args",i)=$extract(message,startPos,endPos)
. ; do doWrite^InfoHubUtils(" arg is '"_var("args",i)_"'") ;##
do doWrite^InfoHubUtils(" returning "_quit) ;#
quit quit