KMPMCMRT ;ATL/JML - Collect HL7/HLO counts for the VistA Message Count Monitor ;2/1/2023
;;4.0;CAPACITY MANAGEMENT;**1,2,3,4**;3/1/2018;Build 36
;
; Reference to $$HTFM^XLFDT in ICR #10103
; Reference to $$WORKDAY^XUWORKDY in ICR #10046
; Reference to GETENV^%ZOSV, EC^%ZOSV and LGR^%ZOSV in ICR #10097
; Reference to $ESTACK, $ETRAP, ^%ZTER and UNWIND^%ZTER in ICR #1621
;
RUN ; Collect metrics per configured interval and store in ^KMPTMP("KMPV","VMCM","DLY" -- CALLED VIA CACHE TASK MANAGER
;
;
N $ESTACK,$ETRAP S $ETRAP="D ^%ZTER Q"
I $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VMCM DRIVER")
N KMPD,KMPPARMS,KMPFMDAY,KMPH,KMPNDTYP,KMPSC,KMPVCHKH,KMPVH,KMPVHANG,KMPVNODE,KMPVSINF,KMPVSINT,KMPVSTOP,KMPVTEST
N KMPDST,KMPETSO,KMPINST,KMPTIMES,KMPUTCE,KMPUTCO,KMPWORK
N Y,ZTDESC,ZTDTH,ZTRTN,ZTSAVE
; ALWAYS - verify data is not building past configured number of days - if so for any reason, delete it
D PURGEDLY^KMPVCBG("VMCM")
; Quit if monitor is not turned on
I $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969)'="ON" D Q
.I $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VMCM DRIVER END")
; Environment Check
; if TEST system - quit if system is a front end OR allow test=no
; if PROD system - quit if system is a front end AND allow test=no
S KMPVTEST=$$GETVAL^KMPVCCFG("VMCM","ALLOW TEST SYSTEM",8969,"I")
D GETENV^%ZOSV S KMPVNODE=$P(Y,U,3)_":"_$P($P(Y,U,4),":",2) ;supported by ICR #10097
I $$PROD^KMPVCCFG'="prod" I ($$ISBENODE^KMPVCCFG(KMPVNODE)=0)!(KMPVTEST=0) Q
I $$PROD^KMPVCCFG="prod" I ($$ISBENODE^KMPVCCFG(KMPVNODE)=0)&(KMPVTEST=0) Q
;
S KMPVSTOP=0,KMPVCHKH=+$H
S KMPVSINF=$$SITEINFO^KMPVCCFG()
S KMPSC=$P(KMPVSINF,"^",5)
S KMPH=$H,KMPD=$P(KMPH,","),KMPFMDAY=+$$HTFM^XLFDT(KMPH,1) ;supported by ICR #10103
S KMPWORK=$$WORKDAY^XUWORKDY(KMPFMDAY) ;supported by ICR #10046
S KMPINST=$P(KMPVNODE,":",2),KMPNDTYP=$$NODETYPE^KMPUTLW(KMPINST)
S KMPPARMS("KMPVCHKH")=KMPVCHKH,KMPPARMS("KMPVSINF")=KMPVSINF
S KMPPARMS("KMPSC")=KMPSC,KMPPARMS("KMPH")=KMPH
S KMPPARMS("KMPD")=KMPD,KMPPARMS("KMPFMDAY")=KMPFMDAY
S KMPPARMS("KMPINST")=KMPINST,KMPPARMS("KMPNDTYP")=KMPNDTYP
S KMPPARMS("KMPWORK")=KMPWORK
F D Q:KMPVSTOP
.I $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969)'="ON" S KMPVSTOP=1 Q ; RUN FLAG SET TO 0
.S KMPVH=$H
.I KMPVH>KMPVCHKH SET KMPVSTOP=1 Q
.S KMPVSINT=$$GETVAL^KMPVCCFG("VMCM","COLLECTION INTERVAL",8969)
.S KMPVHANG=KMPVSINT*60
.S KMPPARMS("KMPVH")=KMPVH,KMPPARMS("KMPVSINT")=KMPVSINT
.M ^KMPTMP("KMPV","VMCM",KMPVNODE,"PARMS")=KMPPARMS
.J COLLECT(KMPVNODE)
.H KMPVHANG
I $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VMCM DRIVER END")
Q
;
COLLECT(KMPVNODE) ;
N $ES,$ETRAP S $ETRAP="D ^%ZTER Q"
I $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VMCM COLLECTOR")
N B,KMPARR,KMPARR1,KMPCURR,KMPDELTA,KMPDEV,KMPETS,KMPHLOIN,KMPHLOUT,KMPNDTYP,KMPINST,KMPPETS,KMPPREV,KMPVLIEN,KMPVLLINE,KMPVLN,KMPVLNAME
N KMPVLPROC,KMPVLRECV,KMPVLSEND,KMPVLSENT,KMPVLSTATE,KMPVTIME
;
K ^KMPTMP("KMPV","VMCM","TRANSMIT")
M KMPPARMS=^KMPTMP("KMPV","VMCM",KMPVNODE,"PARMS")
M KMPARR=^KMPTMP("KMPV","VMCM","PREVIOUS")
S KMPVCHKH=KMPPARMS("KMPVCHKH"),KMPVSINF=KMPPARMS("KMPVSINF")
S KMPSC=KMPPARMS("KMPSC"),KMPH=KMPPARMS("KMPH")
S KMPD=KMPPARMS("KMPD"),KMPFMDAY=KMPPARMS("KMPFMDAY")
S KMPWORK=KMPPARMS("KMPWORK")
S KMPVH=KMPPARMS("KMPVH"),KMPVSINT=KMPPARMS("KMPVSINT")
S KMPINST=KMPPARMS("KMPINST"),KMPNDTYP=KMPPARMS("KMPNDTYP")
S KMPVLN=1,B="|",U="^"
S KMPVTIME=$$SLOT^KMPVCCFG(KMPVH,KMPVSINT,"HOROLOG")
S KMPTIMES=$$TSTAMP^KMPUTLW(+KMPVH_","_KMPVTIME,"HOROLOG",1) ; yyy-mm-dd hh:mm:ssZts
S KMPETSO=$P(KMPTIMES,"^"),KMPUTCO=$P(KMPTIMES,"^",2)
S KMPUTCE=$P(KMPTIMES,"^",3),KMPDST=$P(KMPTIMES,"^",4)
S (KMPVLIEN,KMPVLLINE,KMPVLNAME,KMPVLSTATE)=""
S (KMPVLRECV,KMPVLPROC,KMPVLSEND,KMPVLSENT)=0
F S KMPVLIEN=$O(^HLCS(870,KMPVLIEN)) Q:KMPVLIEN="" D
.I $D(^HLCS(870,KMPVLIEN,0)) D
..S KMPVLLINE=$G(^HLCS(870,KMPVLIEN,0))
..S KMPVLNAME=$P(KMPVLLINE,"^",1),KMPDEV=$P(KMPVLLINE,"^",4)
..I KMPVLNAME="" S KMPVLNAME="Unknown_"_KMPVLIEN
..S KMPVLSTATE=$P(KMPVLLINE,"^",5)
..S KMPVLRECV=+$G(^HLCS(870,KMPVLIEN,"IN QUEUE BACK POINTER"))
..S KMPVLPROC=+$G(^HLCS(870,KMPVLIEN,"IN QUEUE FRONT POINTER"))
..S KMPVLSEND=+$G(^HLCS(870,KMPVLIEN,"OUT QUEUE BACK POINTER"))
..S KMPVLSENT=+$G(^HLCS(870,KMPVLIEN,"OUT QUEUE FRONT POINTER"))
..;
..S KMPCURR=KMPVLRECV_"^"_KMPVLPROC_"^"_KMPVLSEND_"^"_KMPVLSENT_"^"_$P($$TSTAMP^KMPUTLW($H,"HOROLOG",0),"^",1)
..S KMPPREV=$G(KMPARR(KMPVLNAME)) ; VAL VAL VAL VAL TIME
..S KMPARR1(KMPVLNAME)=KMPCURR
..Q:KMPPREV=""
..; CALCULATE DELTA
..S KMPDELTA=$$CALCDELT(KMPCURR,KMPPREV)
..; S INTO TRANSIT GLOBAL
..S ^KMPTMP("KMPV","VMCM","TRANSMIT",$J,KMPVLN)=KMPVLNAME_B_KMPVLSTATE_B_KMPDEV_B_KMPDELTA,KMPVLN=KMPVLN+1
; Add HLO metrics
S KMPHLOIN=$$HLODAILY("IN"),KMPHLOUT=$$HLODAILY("OUT")
I $D(KMPARR) S ^KMPTMP("KMPV","VMCM","TRANSMIT",$J,KMPVLN)="HLO"_B_B_B_KMPHLOIN_B_B_KMPHLOUT_B
;
K ^KMPTMP("KMPV","VMCM","PREVIOUS")
M ^KMPTMP("KMPV","VMCM","PREVIOUS")=KMPARR1
;
; quit if no data to transmit.
N KMPCNT,KMPDARR,KMPDATA,KMPDONE,KMPJMSG,KMPJSON,KMPLI,KMPMAX,KMPSTAT,KMPTI
I '$D(^KMPTMP("KMPV","VMCM","TRANSMIT",$J)) D Q
.I $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VMCM COLLECTOR END")
S KMPTI="",KMPMAX=40000
S KMPLI=$O(^KMPTMP("KMPV","VMCM","TRANSMIT",$J,""),-1)
S KMPDONE=0
F D Q:KMPDONE
.N KMPDARR,KMPJMSG,KMPJSON
.S KMPJSON=##class(%DynamicObject).%New()
.S KMPJSON.Function="VMCM"
.S KMPJMSG=##class(%DynamicObject).%New()
.D SITE^KMPUTLW(KMPJSON)
.S KMPJMSG.Timestamp=KMPETSO,KMPJMSG.UtcOdbc=KMPUTCO
.S KMPJMSG.UtcEpoch=KMPUTCE,KMPJMSG.IsDst=KMPDST
.S KMPJMSG.Workday=KMPWORK,KMPJMSG.Instance=KMPINST
.S KMPJMSG.Node=$P(KMPVNODE,":"),KMPJMSG.NodeType=KMPNDTYP
.S KMPJMSG.Date=$$SHORTDAT^KMPUTLW(KMPD,"HOROLOG")
.S KMPJSON.MessageData=KMPJMSG
.S KMPDARR=##class(%DynamicArray).%New()
.S KMPCNT=0
.F S KMPTI=$O(^KMPTMP("KMPV","VMCM","TRANSMIT",$J,KMPTI)) Q:KMPTI=""!(KMPCNT>KMPMAX) D
..S KMPDATA=$G(^KMPTMP("KMPV","VMCM","TRANSMIT",$J,KMPTI))
..D KMPDARR.%Push(KMPDATA)
..I KMPTI>=KMPLI S KMPDONE=1
..S KMPCNT=KMPCNT+1
.S KMPJSON.Details=KMPDARR
.S KMPSTAT=$$POST^KMPUTLW(KMPJSON,"/messagecount",,"VMCM")
.I +KMPSTAT'=200 S KMPSTAT=$$POST^KMPUTLW(KMPJSON,"/messagecount",,"VMCM")
.S ^XTMP("KMP "_KMPFMDAY,"VMCM","HTTP",KMPVNODE,$P($H,",",2))=KMPSTAT
.I +KMPSTAT'=200 D SETRETRY
K ^KMPTMP("KMPV","VMCM","TRANSMIT",$J)
I $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VMCM COLLECTOR END")
Q
;
HLODAILY(KMPDIR) ;
N KMPHLO,KMPHLOD,KMPHLOTS,KMPMIN,KMPVHRAP,KMPVHSAP,KMPVHTIME,KMPVHTODAY,KMPVHTOTAL,KMPVHTYPE
S KMPVHTOTAL=0
S KMPVHTODAY=$$DT^XLFDT
S KMPVHTIME=KMPVHTODAY-.0001
F S KMPVHTIME=$O(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME)) Q:'KMPVHTIME Q:((KMPVHTIME\1)>KMPVHTODAY) D
.S KMPVHSAP=""
.F S KMPVHSAP=$O(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME,KMPVHSAP)) Q:KMPVHSAP="" D
..Q:KMPVHSAP="ACCEPT ACK"
..S KMPVHRAP=""
..F S KMPVHRAP=$O(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME,KMPVHSAP,KMPVHRAP)) Q:KMPVHRAP="" D
...S KMPVHTYPE=""
...F S KMPVHTYPE=$O(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME,KMPVHSAP,KMPVHRAP,KMPVHTYPE)) Q:KMPVHTYPE="" D
....S KMPVHTOTAL=KMPVHTOTAL+$G(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME,KMPVHSAP,KMPVHRAP,KMPVHTYPE))
S KMPHLOTS=$P($$TSTAMP^KMPUTLW($H,"HOROLOG",0),"^")
; SET CUR INTO ARRAY
S KMPARR1("HLO",KMPDIR)=KMPVHTOTAL_"^"_KMPHLOTS
I '$D(KMPARR) Q ""
; Get previous
S KMPHLO=KMPARR("HLO",KMPDIR)
; CALC TIME DIFF
S KMPMIN=$system.SQL.DATEDIFF("mi",$P(KMPHLO,"^",2),KMPHLOTS)
I KMPMIN=0 S KMPMIN=1
; CALC NUMBER DIFF
S KMPHLOD=$FN((KMPVHTOTAL-$P(KMPHLO,"^",1))/KMPMIN,"",0)
; RETURN VALUE
Q KMPHLOD
;
CALCDELT(KMPCURR,KMPPREV) ;
N KMPCTS,KMPI,KMPMIN,KMPPTS,KMPDELT
S KMPCTS=$P(KMPCURR,"^",5),KMPPTS=$P(KMPPREV,"^",5)
S KMPMIN=$system.SQL.DATEDIFF("mi",KMPPTS,KMPCTS)
I KMPMIN=0 S KMPMIN=1
F KMPI=1:1:4 S $P(KMPDELT,"|",KMPI)=$FN(($P(KMPCURR,"^",KMPI)-$P(KMPPREV,"^",KMPI))/KMPMIN,"",0)
Q KMPDELT
;
SETRETRY ;
N KMPTEXT
S KMPTEXT("SUBJECT")="VSM FAILED SEND: VMCM at "_KMPJSON.Site.SiteCode
S KMPTEXT(1)="Status Code: "_+KMPSTAT
S KMPTEXT(2)="Status Text: "_$P(KMPSTAT,"^",2)
S KMPTEXT(3)="Response Time: "_$P(KMPSTAT,"^",3)
S KMPTEXT(4)="Node: "_KMPVNODE
D INFOMSG^KMPUTLW(.KMPTEXT)
S ^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,+$H,$H)=KMPJSON.%ToJSON()
Q
;
RETRY ; retry failed POSTS
N KMPDAY,KMPI,KMPJSON,KMPSTAT,KMPVNODE,Y
;
D GETENV^%ZOSV S KMPVNODE=$P(Y,"^",3)_":"_$P($P(Y,"^",4),":",2) ;supported by ICR #10097
S KMPDAY=""
F S KMPDAY=$O(^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,KMPDAY)) Q:KMPDAY="" D
.S KMPI=""
.F S KMPI=$O(^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,KMPDAY,KMPI)) Q:KMPI="" D
..S KMPJSON=$G(^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,KMPDAY,KMPI))
..S KMPSTAT=$$POST^KMPUTLW({}.%FromJSON(KMPJSON),"/messagecount",,"VMCM")
..I +KMPSTAT=200 K ^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,KMPDAY,KMPI)
..H $R(10)
Q
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HKMPMCMRT 9119 printed Dec 13, 2024@01:41:28 Page 2
KMPMCMRT ;ATL/JML - Collect HL7/HLO counts for the VistA Message Count Monitor ;2/1/2023
+1 ;;4.0;CAPACITY MANAGEMENT;**1,2,3,4**;3/1/2018;Build 36
+2 ;
+3 ; Reference to $$HTFM^XLFDT in ICR #10103
+4 ; Reference to $$WORKDAY^XUWORKDY in ICR #10046
+5 ; Reference to GETENV^%ZOSV, EC^%ZOSV and LGR^%ZOSV in ICR #10097
+6 ; Reference to $ESTACK, $ETRAP, ^%ZTER and UNWIND^%ZTER in ICR #1621
+7 ;
RUN ; Collect metrics per configured interval and store in ^KMPTMP("KMPV","VMCM","DLY" -- CALLED VIA CACHE TASK MANAGER
+1 ;
+2 ;
+3 NEW $ESTACK,$ETRAP
SET $ETRAP="D ^%ZTER Q"
+4 IF $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VMCM DRIVER")
+5 NEW KMPD,KMPPARMS,KMPFMDAY,KMPH,KMPNDTYP,KMPSC,KMPVCHKH,KMPVH,KMPVHANG,KMPVNODE,KMPVSINF,KMPVSINT,KMPVSTOP,KMPVTEST
+6 NEW KMPDST,KMPETSO,KMPINST,KMPTIMES,KMPUTCE,KMPUTCO,KMPWORK
+7 NEW Y,ZTDESC,ZTDTH,ZTRTN,ZTSAVE
+8 ; ALWAYS - verify data is not building past configured number of days - if so for any reason, delete it
+9 DO PURGEDLY^KMPVCBG("VMCM")
+10 ; Quit if monitor is not turned on
+11 IF $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969)'="ON"
Begin DoDot:1
+12 IF $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VMCM DRIVER END")
End DoDot:1
QUIT
+13 ; Environment Check
+14 ; if TEST system - quit if system is a front end OR allow test=no
+15 ; if PROD system - quit if system is a front end AND allow test=no
+16 SET KMPVTEST=$$GETVAL^KMPVCCFG("VMCM","ALLOW TEST SYSTEM",8969,"I")
+17 ;supported by ICR #10097
DO GETENV^%ZOSV
SET KMPVNODE=$PIECE(Y,U,3)_":"_$PIECE($PIECE(Y,U,4),":",2)
+18 IF $$PROD^KMPVCCFG'="prod"
IF ($$ISBENODE^KMPVCCFG(KMPVNODE)=0)!(KMPVTEST=0)
QUIT
+19 IF $$PROD^KMPVCCFG="prod"
IF ($$ISBENODE^KMPVCCFG(KMPVNODE)=0)&(KMPVTEST=0)
QUIT
+20 ;
+21 SET KMPVSTOP=0
SET KMPVCHKH=+$HOROLOG
+22 SET KMPVSINF=$$SITEINFO^KMPVCCFG()
+23 SET KMPSC=$PIECE(KMPVSINF,"^",5)
+24 ;supported by ICR #10103
SET KMPH=$HOROLOG
SET KMPD=$PIECE(KMPH,",")
SET KMPFMDAY=+$$HTFM^XLFDT(KMPH,1)
+25 ;supported by ICR #10046
SET KMPWORK=$$WORKDAY^XUWORKDY(KMPFMDAY)
+26 SET KMPINST=$PIECE(KMPVNODE,":",2)
SET KMPNDTYP=$$NODETYPE^KMPUTLW(KMPINST)
+27 SET KMPPARMS("KMPVCHKH")=KMPVCHKH
SET KMPPARMS("KMPVSINF")=KMPVSINF
+28 SET KMPPARMS("KMPSC")=KMPSC
SET KMPPARMS("KMPH")=KMPH
+29 SET KMPPARMS("KMPD")=KMPD
SET KMPPARMS("KMPFMDAY")=KMPFMDAY
+30 SET KMPPARMS("KMPINST")=KMPINST
SET KMPPARMS("KMPNDTYP")=KMPNDTYP
+31 SET KMPPARMS("KMPWORK")=KMPWORK
+32 FOR
Begin DoDot:1
+33 ; RUN FLAG SET TO 0
IF $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969)'="ON"
SET KMPVSTOP=1
QUIT
+34 SET KMPVH=$HOROLOG
+35 IF KMPVH>KMPVCHKH
SET KMPVSTOP=1
QUIT
+36 SET KMPVSINT=$$GETVAL^KMPVCCFG("VMCM","COLLECTION INTERVAL",8969)
+37 SET KMPVHANG=KMPVSINT*60
+38 SET KMPPARMS("KMPVH")=KMPVH
SET KMPPARMS("KMPVSINT")=KMPVSINT
+39 MERGE ^KMPTMP("KMPV","VMCM",KMPVNODE,"PARMS")=KMPPARMS
+40 JOB COLLECT(KMPVNODE)
+41 HANG KMPVHANG
End DoDot:1
if KMPVSTOP
QUIT
+42 IF $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VMCM DRIVER END")
+43 QUIT
+44 ;
COLLECT(KMPVNODE) ;
+1 NEW $ESTACK,$ETRAP
SET $ETRAP="D ^%ZTER Q"
+2 IF $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VMCM COLLECTOR")
+3 NEW B,KMPARR,KMPARR1,KMPCURR,KMPDELTA,KMPDEV,KMPETS,KMPHLOIN,KMPHLOUT,KMPNDTYP,KMPINST,KMPPETS,KMPPREV,KMPVLIEN,KMPVLLINE,KMPVLN,KMPVLNAME
+4 NEW KMPVLPROC,KMPVLRECV,KMPVLSEND,KMPVLSENT,KMPVLSTATE,KMPVTIME
+5 ;
+6 KILL ^KMPTMP("KMPV","VMCM","TRANSMIT")
+7 MERGE KMPPARMS=^KMPTMP("KMPV","VMCM",KMPVNODE,"PARMS")
+8 MERGE KMPARR=^KMPTMP("KMPV","VMCM","PREVIOUS")
+9 SET KMPVCHKH=KMPPARMS("KMPVCHKH")
SET KMPVSINF=KMPPARMS("KMPVSINF")
+10 SET KMPSC=KMPPARMS("KMPSC")
SET KMPH=KMPPARMS("KMPH")
+11 SET KMPD=KMPPARMS("KMPD")
SET KMPFMDAY=KMPPARMS("KMPFMDAY")
+12 SET KMPWORK=KMPPARMS("KMPWORK")
+13 SET KMPVH=KMPPARMS("KMPVH")
SET KMPVSINT=KMPPARMS("KMPVSINT")
+14 SET KMPINST=KMPPARMS("KMPINST")
SET KMPNDTYP=KMPPARMS("KMPNDTYP")
+15 SET KMPVLN=1
SET B="|"
SET U="^"
+16 SET KMPVTIME=$$SLOT^KMPVCCFG(KMPVH,KMPVSINT,"HOROLOG")
+17 ; yyy-mm-dd hh:mm:ssZts
SET KMPTIMES=$$TSTAMP^KMPUTLW(+KMPVH_","_KMPVTIME,"HOROLOG",1)
+18 SET KMPETSO=$PIECE(KMPTIMES,"^")
SET KMPUTCO=$PIECE(KMPTIMES,"^",2)
+19 SET KMPUTCE=$PIECE(KMPTIMES,"^",3)
SET KMPDST=$PIECE(KMPTIMES,"^",4)
+20 SET (KMPVLIEN,KMPVLLINE,KMPVLNAME,KMPVLSTATE)=""
+21 SET (KMPVLRECV,KMPVLPROC,KMPVLSEND,KMPVLSENT)=0
+22 FOR
SET KMPVLIEN=$ORDER(^HLCS(870,KMPVLIEN))
if KMPVLIEN=""
QUIT
Begin DoDot:1
+23 IF $DATA(^HLCS(870,KMPVLIEN,0))
Begin DoDot:2
+24 SET KMPVLLINE=$GET(^HLCS(870,KMPVLIEN,0))
+25 SET KMPVLNAME=$PIECE(KMPVLLINE,"^",1)
SET KMPDEV=$PIECE(KMPVLLINE,"^",4)
+26 IF KMPVLNAME=""
SET KMPVLNAME="Unknown_"_KMPVLIEN
+27 SET KMPVLSTATE=$PIECE(KMPVLLINE,"^",5)
+28 SET KMPVLRECV=+$GET(^HLCS(870,KMPVLIEN,"IN QUEUE BACK POINTER"))
+29 SET KMPVLPROC=+$GET(^HLCS(870,KMPVLIEN,"IN QUEUE FRONT POINTER"))
+30 SET KMPVLSEND=+$GET(^HLCS(870,KMPVLIEN,"OUT QUEUE BACK POINTER"))
+31 SET KMPVLSENT=+$GET(^HLCS(870,KMPVLIEN,"OUT QUEUE FRONT POINTER"))
+32 ;
+33 SET KMPCURR=KMPVLRECV_"^"_KMPVLPROC_"^"_KMPVLSEND_"^"_KMPVLSENT_"^"_$PIECE($$TSTAMP^KMPUTLW($HOROLOG,"HOROLOG",0),"^",1)
+34 ; VAL VAL VAL VAL TIME
SET KMPPREV=$GET(KMPARR(KMPVLNAME))
+35 SET KMPARR1(KMPVLNAME)=KMPCURR
+36 if KMPPREV=""
QUIT
+37 ; CALCULATE DELTA
+38 SET KMPDELTA=$$CALCDELT(KMPCURR,KMPPREV)
+39 ; S INTO TRANSIT GLOBAL
+40 SET ^KMPTMP("KMPV","VMCM","TRANSMIT",$JOB,KMPVLN)=KMPVLNAME_B_KMPVLSTATE_B_KMPDEV_B_KMPDELTA
SET KMPVLN=KMPVLN+1
End DoDot:2
End DoDot:1
+41 ; Add HLO metrics
+42 SET KMPHLOIN=$$HLODAILY("IN")
SET KMPHLOUT=$$HLODAILY("OUT")
+43 IF $DATA(KMPARR)
SET ^KMPTMP("KMPV","VMCM","TRANSMIT",$JOB,KMPVLN)="HLO"_B_B_B_KMPHLOIN_B_B_KMPHLOUT_B
+44 ;
+45 KILL ^KMPTMP("KMPV","VMCM","PREVIOUS")
+46 MERGE ^KMPTMP("KMPV","VMCM","PREVIOUS")=KMPARR1
+47 ;
+48 ; quit if no data to transmit.
+49 NEW KMPCNT,KMPDARR,KMPDATA,KMPDONE,KMPJMSG,KMPJSON,KMPLI,KMPMAX,KMPSTAT,KMPTI
+50 IF '$DATA(^KMPTMP("KMPV","VMCM","TRANSMIT",$JOB))
Begin DoDot:1
+51 IF $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VMCM COLLECTOR END")
End DoDot:1
QUIT
+52 SET KMPTI=""
SET KMPMAX=40000
+53 SET KMPLI=$ORDER(^KMPTMP("KMPV","VMCM","TRANSMIT",$JOB,""),-1)
+54 SET KMPDONE=0
+55 FOR
Begin DoDot:1
+56 NEW KMPDARR,KMPJMSG,KMPJSON
+57 SET KMPJSON=##class(%DynamicObject).%New()
+58 SET KMPJSON.Function="VMCM"
+59 SET KMPJMSG=##class(%DynamicObject).%New()
+60 DO SITE^KMPUTLW(KMPJSON)
+61 SET KMPJMSG.Timestamp=KMPETSO
SET KMPJMSG.UtcOdbc=KMPUTCO
+62 SET KMPJMSG.UtcEpoch=KMPUTCE
SET KMPJMSG.IsDst=KMPDST
+63 SET KMPJMSG.Workday=KMPWORK
SET KMPJMSG.Instance=KMPINST
+64 SET KMPJMSG.Node=$PIECE(KMPVNODE,":")
SET KMPJMSG.NodeType=KMPNDTYP
+65 SET KMPJMSG.Date=$$SHORTDAT^KMPUTLW(KMPD,"HOROLOG")
+66 SET KMPJSON.MessageData=KMPJMSG
+67 SET KMPDARR=##class(%DynamicArray).%New()
+68 SET KMPCNT=0
+69 FOR
SET KMPTI=$ORDER(^KMPTMP("KMPV","VMCM","TRANSMIT",$JOB,KMPTI))
if KMPTI=""!(KMPCNT>KMPMAX)
QUIT
Begin DoDot:2
+70 SET KMPDATA=$GET(^KMPTMP("KMPV","VMCM","TRANSMIT",$JOB,KMPTI))
+71 DO KMPDARR.%Push(KMPDATA)
+72 IF KMPTI>=KMPLI
SET KMPDONE=1
+73 SET KMPCNT=KMPCNT+1
End DoDot:2
+74 SET KMPJSON.Details=KMPDARR
+75 SET KMPSTAT=$$POST^KMPUTLW(KMPJSON,"/messagecount",,"VMCM")
+76 IF +KMPSTAT'=200
SET KMPSTAT=$$POST^KMPUTLW(KMPJSON,"/messagecount",,"VMCM")
+77 SET ^XTMP("KMP "_KMPFMDAY,"VMCM","HTTP",KMPVNODE,$PIECE($HOROLOG,",",2))=KMPSTAT
+78 IF +KMPSTAT'=200
DO SETRETRY
End DoDot:1
if KMPDONE
QUIT
+79 KILL ^KMPTMP("KMPV","VMCM","TRANSMIT",$JOB)
+80 IF $$GETVAL^KMPVCCFG("VMCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VMCM COLLECTOR END")
+81 QUIT
+82 ;
HLODAILY(KMPDIR) ;
+1 NEW KMPHLO,KMPHLOD,KMPHLOTS,KMPMIN,KMPVHRAP,KMPVHSAP,KMPVHTIME,KMPVHTODAY,KMPVHTOTAL,KMPVHTYPE
+2 SET KMPVHTOTAL=0
+3 SET KMPVHTODAY=$$DT^XLFDT
+4 SET KMPVHTIME=KMPVHTODAY-.0001
+5 FOR
SET KMPVHTIME=$ORDER(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME))
if 'KMPVHTIME
QUIT
if ((KMPVHTIME\1)>KMPVHTODAY)
QUIT
Begin DoDot:1
+6 SET KMPVHSAP=""
+7 FOR
SET KMPVHSAP=$ORDER(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME,KMPVHSAP))
if KMPVHSAP=""
QUIT
Begin DoDot:2
+8 if KMPVHSAP="ACCEPT ACK"
QUIT
+9 SET KMPVHRAP=""
+10 FOR
SET KMPVHRAP=$ORDER(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME,KMPVHSAP,KMPVHRAP))
if KMPVHRAP=""
QUIT
Begin DoDot:3
+11 SET KMPVHTYPE=""
+12 FOR
SET KMPVHTYPE=$ORDER(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME,KMPVHSAP,KMPVHRAP,KMPVHTYPE))
if KMPVHTYPE=""
QUIT
Begin DoDot:4
+13 SET KMPVHTOTAL=KMPVHTOTAL+$GET(^HLSTATS(KMPDIR,"HOURLY",KMPVHTIME,KMPVHSAP,KMPVHRAP,KMPVHTYPE))
End DoDot:4
End DoDot:3
End DoDot:2
End DoDot:1
+14 SET KMPHLOTS=$PIECE($$TSTAMP^KMPUTLW($HOROLOG,"HOROLOG",0),"^")
+15 ; SET CUR INTO ARRAY
+16 SET KMPARR1("HLO",KMPDIR)=KMPVHTOTAL_"^"_KMPHLOTS
+17 IF '$DATA(KMPARR)
QUIT ""
+18 ; Get previous
+19 SET KMPHLO=KMPARR("HLO",KMPDIR)
+20 ; CALC TIME DIFF
+21
*** ERROR ***
SET KMPMIN=$system.SQL.DATEDIFF("mi",$PIECE(KMPHLO,"^",2),KMPHLOTS)
+22 IF KMPMIN=0
SET KMPMIN=1
+23 ; CALC NUMBER DIFF
+24 SET KMPHLOD=$FNUMBER((KMPVHTOTAL-$PIECE(KMPHLO,"^",1))/KMPMIN,"",0)
+25 ; RETURN VALUE
+26 QUIT KMPHLOD
+27 ;
CALCDELT(KMPCURR,KMPPREV) ;
+1 NEW KMPCTS,KMPI,KMPMIN,KMPPTS,KMPDELT
+2 SET KMPCTS=$PIECE(KMPCURR,"^",5)
SET KMPPTS=$PIECE(KMPPREV,"^",5)
+3
*** ERROR ***
SET KMPMIN=$system.SQL.DATEDIFF("mi",KMPPTS,KMPCTS)
+4 IF KMPMIN=0
SET KMPMIN=1
+5 FOR KMPI=1:1:4
SET $PIECE(KMPDELT,"|",KMPI)=$FNUMBER(($PIECE(KMPCURR,"^",KMPI)-$PIECE(KMPPREV,"^",KMPI))/KMPMIN,"",0)
+6 QUIT KMPDELT
+7 ;
SETRETRY ;
+1 NEW KMPTEXT
+2 SET KMPTEXT("SUBJECT")="VSM FAILED SEND: VMCM at "_KMPJSON.Site.SiteCode
+3 SET KMPTEXT(1)="Status Code: "_+KMPSTAT
+4 SET KMPTEXT(2)="Status Text: "_$PIECE(KMPSTAT,"^",2)
+5 SET KMPTEXT(3)="Response Time: "_$PIECE(KMPSTAT,"^",3)
+6 SET KMPTEXT(4)="Node: "_KMPVNODE
+7 DO INFOMSG^KMPUTLW(.KMPTEXT)
+8 SET ^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,+$HOROLOG,$HOROLOG)=KMPJSON.%ToJSON()
+9 QUIT
+10 ;
RETRY ; retry failed POSTS
+1 NEW KMPDAY,KMPI,KMPJSON,KMPSTAT,KMPVNODE,Y
+2 ;
+3 ;supported by ICR #10097
DO GETENV^%ZOSV
SET KMPVNODE=$PIECE(Y,"^",3)_":"_$PIECE($PIECE(Y,"^",4),":",2)
+4 SET KMPDAY=""
+5 FOR
SET KMPDAY=$ORDER(^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,KMPDAY))
if KMPDAY=""
QUIT
Begin DoDot:1
+6 SET KMPI=""
+7 FOR
SET KMPI=$ORDER(^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,KMPDAY,KMPI))
if KMPI=""
QUIT
Begin DoDot:2
+8 SET KMPJSON=$GET(^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,KMPDAY,KMPI))
+9 SET KMPSTAT=$$POST^KMPUTLW({}.%FromJSON(KMPJSON),"/messagecount",,"VMCM")
+10 IF +KMPSTAT=200
KILL ^KMPTMP("KMPV","VMCM","RETRY",KMPVNODE,KMPDAY,KMPI)
+11 HANG $RANDOM(10)
End DoDot:2
End DoDot:1
+12 QUIT