KMPTCMRT ;SP/JML - Collect Cache Metrics for the Real-Time Timed Collection Monitor ;2/1/2023
;;4.0;CAPACITY MANAGEMENT;**1,2,3,4**;3/1/2018;Build 36
;
; Reference to $$WORKDAY^XUWORKDY in ICR #10046
; Reference to $$HTFM^XLFDT in ICR #10103
; Reference to GETENV^%ZOSV, EC^%ZOSV and LGR^%ZOSV in ICR #10097
; Reference to $ESTACK, $ETRAP, ^%ZTER and UNWIND^%ZTER in ICR #1621
;
RUN(KMPTEST) ;
N $ESTACK,$ETRAP S $ETRAP="D ^%ZTER Q"
I $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VTCM DRIVER")
N KMPCHKH,KMPFMDAY,KMPH,KMPHANG,KMPINST,KMPNDTYP,KMPVNODE,KMPPARMS,KMPRUNNS,KMPSINF,KMPSINT
N KMPSTOP,KMPWORK,ZTDESC,ZTDTH,ZTRTN,ZTSAVE,U,Y,KMPFMDAY
;
; ALWAYS - verify data is not building past configured number of days - if so for any reason, delete it
D PURGEDLY^KMPVCBG("VTCM")
; Quit if monitor is not turned on
I $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969)'="ON" D Q
.I $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VTCM DRIVER END")
; Check environment
I $$PROD^KMPVCCFG'="prod",$$GETVAL^KMPVCCFG("VTCM","ALLOW TEST SYSTEM",8969,"I")'=1 Q
S U="^"
D GETENV^%ZOSV S KMPVNODE=$P(Y,U,3)_":"_$P($P(Y,U,4),":",2) ;supported by ICR #10097
S KMPINST=$P(KMPVNODE,":",2),KMPNDTYP=$$NODETYPE^KMPUTLW(KMPINST)
S KMPFMDAY=+$$HTFM^XLFDT($H,1) ;supported by ICR #10103
S KMPWORK=$$WORKDAY^XUWORKDY(KMPFMDAY) ;supported by ICR #10046
S KMPSINF=$$SITEINFO^KMPVCCFG() ; site name^fac num^mail domain^prod/test^site code
; Main loop - job off collection to keep interval intact - DON't use TaskMan!
S KMPSTOP=0,KMPCHKH=+$H
; Setup Parameter array to send to job
S KMPPARMS("KMPINST")=KMPINST,KMPPARMS("KMPNDTYP")=KMPNDTYP
S KMPPARMS("KMPFMDAY")=KMPFMDAY,KMPPARMS("KMPWORK")=KMPWORK
S KMPPARMS("KMPSINF")=KMPSINF,KMPPARMS("KMPCHKH")=KMPCHKH
S KMPPARMS("KMPRUNNS")=$NAMESPACE
F D Q:KMPSTOP
.I $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969)'="ON" S KMPSTOP=1 Q ; RUN FLAG SET TO 0
.S KMPH=$H
.I KMPH>KMPCHKH SET KMPSTOP=1 Q
.S KMPSINT=$$GETVAL^KMPVCCFG("VTCM","COLLECTION INTERVAL",8969)
.S KMPHANG=KMPSINT*60
.S KMPPARMS("KMPH")=KMPH,KMPPARMS("KMPSINT")=KMPSINT
.S KMPPARMS("KMPHANG")=KMPHANG
.M ^KMPTMP("KMPV","VTCM",KMPVNODE,"PARMS")=KMPPARMS
.J COLLECT(KMPVNODE)
.H KMPHANG
I $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VTCM DRIVER END")
Q
;
COLLECT(KMPVNODE) ;
N $ESTACK,$ETRAP S $ETRAP="D ^%ZTER Q"
I $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VTCM COLLECTOR")
N KMPAE,KMPBCC,KMPBCS,KMPCE,KMPCMET,KMPCSPS,KMPDASH,KMPDATE,KMPDBS,KMPDR,KMPDRDFF,KMPDST,KMPDW,KMPECPAS,KMPECPDS
N KMPECPASR,KMPECPDSR,KMPETSO,KMPGR,KMPGRS,KMPGS,KMPH,KMPINST,KMPJE,KMPJMEM,KMPJMMET,KMPJMSG,KMPJS,KMPJSMET,KMPJSON,KMPJST
N KMPLB,KMPLC,KMPLH,KMPLL,KMPLR,KMPLT,KMPNEWTS,KMPMEM,KMPMETS,KMPNDTYP,KMPOLDTS,KMPP,KMPPAR,KMPPARMS,KMPPREV,KMPRC,KMPROUT
N KMPRR,KMPSA,KMPSEC,KMPSLOT,KMPSMH,KMPSMHC,KMPSMHM,KMPSMHP,KMPSSRC,KMPSSRV,KMPSTAT,KMPSUT,KMPTGST,KMPTIMES,KMPTNS
N KMPTSEC,KMPTSMHM,KMPTSMHP,KMPTSMHT,KMPUTCE,KMPUTCO,KMPVBLK,KMPWD,KMPZTS
;
M KMPPARMS=^KMPTMP("KMPV","VTCM",KMPVNODE,"PARMS")
S KMPFMDAY=KMPPARMS("KMPFMDAY"),KMPWORK=KMPPARMS("KMPWORK")
S KMPSINF=KMPPARMS("KMPSINF"),KMPCHKH=KMPPARMS("KMPCHKH")
S KMPH=KMPPARMS("KMPH"),KMPSINT=KMPPARMS("KMPSINT")
S KMPINST=KMPPARMS("KMPINST"),KMPNDTYP=KMPPARMS("KMPNDTYP")
S KMPRUNNS=KMPPARMS("KMPRUNNS")
S U="^"
;
S KMPJSON=##class(%DynamicObject).%New()
S KMPJMSG=##class(%DynamicObject).%New()
S KMPJMMET=##class(%DynamicObject).%New()
S KMPCMET=##class(%DynamicObject).%New()
S KMPJSMET=##class(%DynamicObject).%New()
S KMPJMEM=##class(%DynamicObject).%New()
S KMPJSON.Function="VTCM"
S KMPH=$H
S KMPSLOT=$$SLOT^KMPVCCFG(KMPH,KMPSINT,"HOROLOG")
S $P(KMPH,",",2)=KMPSLOT
S KMPTIMES=$$TSTAMP^KMPUTLW(KMPH,"HOROLOG",1) ; yyy-mm-dd hh:mm:ssZts
S KMPETSO=$P(KMPTIMES,"^")
S KMPUTCO=$P(KMPTIMES,"^",2)
S KMPUTCE=$P(KMPTIMES,"^",3)
S KMPDST=$P(KMPTIMES,"^",4)
S KMPDATE=$$SHORTDAT^KMPUTLW(KMPH,"HOROLOG")
;
D SITE^KMPUTLW(KMPJSON)
S KMPJMSG.Timestamp=KMPETSO,KMPJMSG.UtcOdbc=KMPUTCO
S KMPJMSG.UtcEpoch=KMPUTCE,KMPJMSG.IsDst=KMPDST
S KMPJMSG.Node=$P(KMPVNODE,":"),KMPJMSG.NodeType=KMPNDTYP
S KMPJMSG.Instance=KMPINST,KMPJMSG.Workday=KMPWORK
S KMPJMSG.Date=KMPDATE
S KMPJSON.MessageData=KMPJMSG
;
; Get metrics
K KMPMETS
D KMPVVTCM^%ZOSVKSD(.KMPMETS)
I $NAMESPACE'=KMPRUNNS S $NAMESPACE=KMPRUNNS
S KMPDASH=KMPMETS("KMPVDASH"),KMPROUT=KMPMETS("KMPVROUT")
S KMPSMH=KMPMETS("KMPVSMH"),KMPMEM=KMPMETS("KMPVMEM")
; MATH metricsf -- per second
; DiskReads, DiskWrites, GloSets, GloRefs, JournalEntries, LogicalReads, RoutineCommands, RouRefs
S KMPPREV=$G(^KMPTMP("KMPV","VTCM","TEMP",KMPVNODE))
S KMPNEWTS=$P($$TSTAMP^KMPUTLW($H,"HOROLOG",0),"^")
I KMPPREV="" D
.S KMPDR="",$P(KMPPREV,"^",1)=KMPDASH.DiskReads
.S KMPDW="",$P(KMPPREV,"^",2)=KMPDASH.DiskWrites
.S KMPGR="",$P(KMPPREV,"^",3)=KMPDASH.GloRefs
.S KMPGS="",$P(KMPPREV,"^",4)=KMPDASH.GloSets
.S KMPJE="",$P(KMPPREV,"^",5)=KMPDASH.JournalEntries
.S KMPLR="",$P(KMPPREV,"^",6)=KMPDASH.LogicalReads
.S KMPRC="",$P(KMPPREV,"^",7)=KMPROUT.RtnCommands
.S KMPRR="",$P(KMPPREV,"^",8)=KMPDASH.RouRefs
.S $P(KMPPREV,"^",9)=KMPNEWTS
.S ^KMPTMP("KMPV","VTCM","TEMP",KMPVNODE)=KMPPREV
E D
.S KMPOLDTS=$P(KMPPREV,"^",9),$P(KMPPREV,"^",9)=KMPNEWTS
.S KMPTSEC=$system.SQL.DATEDIFF("ss",KMPOLDTS,KMPNEWTS)
.S KMPDRDFF=KMPDASH.DiskReads-$P(KMPPREV,"^",1),KMPDR=KMPDRDFF/KMPTSEC,$P(KMPPREV,"^",1)=KMPDASH.DiskReads
.S KMPDW=(KMPDASH.DiskWrites-$P(KMPPREV,"^",2))/KMPTSEC,$P(KMPPREV,"^",2)=KMPDASH.DiskWrites
.S KMPGR=(KMPDASH.GloRefs-$P(KMPPREV,"^",3))/KMPTSEC,$P(KMPPREV,"^",3)=KMPDASH.GloRefs
.S KMPGS=(KMPDASH.GloSets-$P(KMPPREV,"^",4))/KMPTSEC,$P(KMPPREV,"^",4)=KMPDASH.GloSets
.S KMPJE=(KMPDASH.JournalEntries-$P(KMPPREV,"^",5))/KMPTSEC,$P(KMPPREV,"^",5)=KMPDASH.JournalEntries
.S KMPLR=(KMPDASH.LogicalReads-$P(KMPPREV,"^",6))/KMPTSEC,$P(KMPPREV,"^",6)=KMPDASH.LogicalReads
.S KMPRC=(KMPROUT.RtnCommands-$P(KMPPREV,"^",7))/KMPTSEC,$P(KMPPREV,"^",7)=KMPROUT.RtnCommands
.S KMPRR=(KMPDASH.RouRefs-$P(KMPPREV,"^",8))/KMPTSEC,$P(KMPPREV,"^",8)=KMPDASH.RouRefs
.S $P(KMPPREV,"^",9)=KMPNEWTS
.I KMPDW<0 S KMPDW=""
.I KMPGR<0 S KMPGR=""
.I KMPGS<0 S KMPGS=""
.I KMPJE<0 S KMPJE=""
.I KMPLR<0 S KMPLR=""
.I KMPRC<0 S KMPRC=""
.I KMPRR<0 S KMPRR=""
.F KMPPAR="KMPDR","KMPDW","KMPGS","KMPGR","KMPJE","KMPLR","KMPRC","KMPRR" S @KMPPAR=$FN(@KMPPAR,"",2)
.S ^KMPTMP("KMPV","VTCM","TEMP",KMPVNODE)=KMPPREV
;Math Metrics
S KMPJMMET.DR=KMPDR,KMPJMMET.DW=KMPDW,KMPJMMET.GR=KMPGR,KMPJMMET.GS=KMPGS,KMPJMMET.JE=KMPJE
S KMPJMMET.LR=KMPLR,KMPJMMET.RC=KMPRC,KMPJMMET.RR=KMPRR
S KMPJSON.MathMetrics=KMPJMMET
; Count metrics
; ApplicationErrors, CSPSessions, CacheEfficiency, ECPAppServerRate, ECPDataServerRate, LicenseCurrent
; LicenseCurrentPct, LicenseHigh, LicenseHighPct, LicenseLimit, Processes, SeriousAlerts
S KMPAE=KMPDASH.ApplicationErrors,KMPCE=KMPDASH.CacheEfficiency,KMPCSPS=KMPDASH.CSPSessions
S KMPECPASR=KMPDASH.ECPAppSrvRate,KMPECPDSR=KMPDASH.ECPDataSrvRate,KMPGRS=KMPDASH.GloRefsPerSec
S KMPLC=KMPDASH.LicenseCurrent,KMPLH=KMPDASH.LicenseHigh,KMPLL=KMPDASH.LicenseLimit
S KMPP=KMPDASH.Processes,KMPSA=KMPDASH.SeriousAlerts
; Block Collisions
S KMPVBLK=","
D BLKCOL^%ZOSVKSD(.KMPVBLK)
I $NAMESPACE'=KMPRUNNS S $NAMESPACE=KMPRUNNS
S KMPBCC=$P(KMPVBLK,",",2),KMPBCS=$P(KMPVBLK,",")
S KMPCMET.AE=KMPAE,KMPCMET.BCC=KMPBCC,KMPCMET.BCS=KMPBCS,KMPCMET.CE=KMPCE,KMPCMET.CSPS=KMPCSPS
S KMPCMET.ECPASR=KMPECPASR,KMPCMET.ECPDSR=KMPECPDSR,KMPCMET.GRS=KMPGRS
S KMPCMET.LC=KMPLC,KMPCMET.LH=KMPLH,KMPCMET.LL=KMPLL,KMPCMET.PROCS=KMPP,KMPCMET.SA=KMPSA
S KMPJSON.CountMetrics=KMPCMET
; status metrics
; DatabaseSpace, ECPAppServer, ECPDataServer, JournalSpace, JournalStatus, LastBackup, LicenseType,
; LockTable, ShadowServer, ShadowSource, SystemUpTime, WriteDaemon
; Last Backup Format -- "May 1 2019 09:04AM"
S KMPDBS=KMPDASH.DatabaseSpace,KMPECPAS=KMPDASH.ECPAppServer,KMPECPDS=KMPDASH.ECPDataServer
S KMPJS=KMPDASH.JournalSpace,KMPJST=KMPDASH.JournalStatus,KMPLB=KMPDASH.LastBackup,KMPLT=KMPDASH.LockTable
S KMPSSRV=KMPDASH.ShadowServer,KMPSSRC=KMPDASH.ShadowSource,KMPSUT=KMPDASH.SystemUpTime,KMPWD=KMPDASH.WriteDaemon
S KMPJSMET.DBS=KMPDBS,KMPJSMET.ECPAS=KMPECPAS,KMPJSMET.ECPDS=KMPECPDS,KMPJSMET.JS=KMPJS,KMPJSMET.JST=KMPJS
S KMPJSMET.LB=KMPLB,KMPJSMET.LT=KMPLT,KMPJSMET.SSRV=KMPSSRV,KMPJSMET.SSRC=KMPSSRC,KMPJSMET.SUT=KMPSUT,KMPJSMET.WD=KMPWD
S KMPJSMET.DBTIM=$$DBTIMCHK(KMPNDTYP)
S KMPJSON.StatusMetrics=KMPJSMET
;
; Memory Metrics
S KMPSMHM=$P(KMPSMH,",") ; p17:TotalSMHMemUsed^ -- $P(KMPSMH,",")
S KMPSMHP=$P(KMPSMH,",",2) ;p18:SMHPagesUsed^ -- $P(KMPSMH,",",2)
S KMPSMHC=$P(KMPSMH,",",3) ;p19:ConfiguredSMHMemory^ -- $P(KMPSMH,",",3)
S KMPTSMHM=$P(KMPMEM,",") ; p20:total Shared Memory Heap available (including pages, smt, genstrtab^ -- $P(KMPMEM,",")
S KMPTSMHP=$P(KMPMEM,",",2) ; p21:pages total available Shared Memory Heap pages (in bytes)^ -- $P(KMPMEM,",",2)
S KMPTSMHT=$P(KMPMEM,",",3) ; p22:smt total available memory in SMT table^ -- $P(KMPMEM,",",3)
S KMPTGST=$P(KMPMEM,",",4) ; p23:genstrtab total available memory in General String Table^ -- $P(KMPMEM,",",4)
S KMPJMEM.SMHM=KMPSMHM,KMPJMEM.SMHP=KMPSMHP,KMPJMEM.SMHC=KMPSMHC,KMPJMEM.TSMHM=KMPTSMHM
S KMPJMEM.TSMHP=KMPTSMHP,KMPJMEM.TSMHT=KMPTSMHT,KMPJMEM.TGST=KMPTGST
S KMPJSON.MemoryMetrics=KMPJMEM
;
S KMPSTAT=$$POST^KMPUTLW(KMPJSON,"/timedcollection",,"VTCM")
I +KMPSTAT'=200 H 30 S KMPSTAT=$$POST^KMPUTLW(KMPJSON,"/timedcollection",,"VTCM")
S ^XTMP("KMP "_KMPFMDAY,"VTCM","HTTP",KMPVNODE,$P($H,",",2))=KMPSTAT
I $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969,"I") D RU^%ZOSVKR("KMP VTCM COLLECTOR END")
I +KMPSTAT'=200 D SETRETRY
Q
;
DBTIMCHK(KMPNDTYP) ;
I KMPNDTYP'="FE" Q ""
; *** CODE FROM DBTIMCHK^ZSTU ***
N $NAMESPACE,DEFNSP,ECPCHAN,MGRPATH,LOCTIME,SVRTIME,SVRNAME,DURATION,DIZ,PID
S DEFNSP=$ZDEFNSP,$NAMESPACE="%SYS",DURATION=""
S ECPCHAN=$P(##Class(%SYS.Namespace).GetGlobalDest(DEFNSP,"DIZ",""),"^")
S MGRPATH=$G(^|DEFNSP|DIZ("ZDBSVR","PATH"))
I $L(ECPCHAN),$L(MGRPATH) D
.J DBTIMSET^ZSTU["^"_ECPCHAN_"^"_MGRPATH] S PID=$ZC
.S LOCTIME=$H H 2
.S SVRTIME=$P($G(^|DEFNSP|DIZ("ZDBSVR","TIME",PID)),"^")
.S SVRNAME=$P($G(^|DEFNSP|DIZ("ZDBSVR","TIME",PID)),"^",2)
.K ^|DEFNSP|DIZ("ZDBSVR","TIME",PID)
.S DURATION=$ZABS((86400*(LOCTIME-SVRTIME))+$P(LOCTIME,",",2)-$P(SVRTIME,",",2))
.I DURATION>10 D ##Class(%SYS.System).WriteToConsoleLog("KMP: "_KMPINST_" "_DURATION_"seconds off DB Server",0,1)
Q DURATION
;
SETRETRY ;
N KMPTEXT
S KMPTEXT("SUBJECT")="VSM FAILED SEND: VTCM 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","VTCM","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","VTCM","RETRY",KMPVNODE,KMPDAY)) Q:KMPDAY="" D
.S KMPI=""
.F S KMPI=$O(^KMPTMP("KMPV","VTCM","RETRY",KMPVNODE,KMPDAY,KMPI)) Q:KMPI="" D
..S KMPJSON=$G(^KMPTMP("KMPV","VTCM","RETRY",KMPVNODE,KMPDAY,KMPI))
..S KMPSTAT=$$POST^KMPUTLW({}.%FromJSON(KMPJSON),"/timedcollection",,"VTCM")
..I +KMPSTAT=200 K ^KMPTMP("KMPV","VTCM","RETRY",KMPVNODE,KMPDAY,KMPI)
..H $R(10)
Q
--- Routine Detail --- with STRUCTURED ROUTINE LISTING ---[H[J[2J[HKMPTCMRT 11649 printed Dec 13, 2024@01:41:56 Page 2
KMPTCMRT ;SP/JML - Collect Cache Metrics for the Real-Time Timed Collection Monitor ;2/1/2023
+1 ;;4.0;CAPACITY MANAGEMENT;**1,2,3,4**;3/1/2018;Build 36
+2 ;
+3 ; Reference to $$WORKDAY^XUWORKDY in ICR #10046
+4 ; Reference to $$HTFM^XLFDT in ICR #10103
+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(KMPTEST) ;
+1 NEW $ESTACK,$ETRAP
SET $ETRAP="D ^%ZTER Q"
+2 IF $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VTCM DRIVER")
+3 NEW KMPCHKH,KMPFMDAY,KMPH,KMPHANG,KMPINST,KMPNDTYP,KMPVNODE,KMPPARMS,KMPRUNNS,KMPSINF,KMPSINT
+4 NEW KMPSTOP,KMPWORK,ZTDESC,ZTDTH,ZTRTN,ZTSAVE,U,Y,KMPFMDAY
+5 ;
+6 ; ALWAYS - verify data is not building past configured number of days - if so for any reason, delete it
+7 DO PURGEDLY^KMPVCBG("VTCM")
+8 ; Quit if monitor is not turned on
+9 IF $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969)'="ON"
Begin DoDot:1
+10 IF $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VTCM DRIVER END")
End DoDot:1
QUIT
+11 ; Check environment
+12 IF $$PROD^KMPVCCFG'="prod"
IF $$GETVAL^KMPVCCFG("VTCM","ALLOW TEST SYSTEM",8969,"I")'=1
QUIT
+13 SET U="^"
+14 ;supported by ICR #10097
DO GETENV^%ZOSV
SET KMPVNODE=$PIECE(Y,U,3)_":"_$PIECE($PIECE(Y,U,4),":",2)
+15 SET KMPINST=$PIECE(KMPVNODE,":",2)
SET KMPNDTYP=$$NODETYPE^KMPUTLW(KMPINST)
+16 ;supported by ICR #10103
SET KMPFMDAY=+$$HTFM^XLFDT($HOROLOG,1)
+17 ;supported by ICR #10046
SET KMPWORK=$$WORKDAY^XUWORKDY(KMPFMDAY)
+18 ; site name^fac num^mail domain^prod/test^site code
SET KMPSINF=$$SITEINFO^KMPVCCFG()
+19 ; Main loop - job off collection to keep interval intact - DON't use TaskMan!
+20 SET KMPSTOP=0
SET KMPCHKH=+$HOROLOG
+21 ; Setup Parameter array to send to job
+22 SET KMPPARMS("KMPINST")=KMPINST
SET KMPPARMS("KMPNDTYP")=KMPNDTYP
+23 SET KMPPARMS("KMPFMDAY")=KMPFMDAY
SET KMPPARMS("KMPWORK")=KMPWORK
+24 SET KMPPARMS("KMPSINF")=KMPSINF
SET KMPPARMS("KMPCHKH")=KMPCHKH
+25
*** ERROR ***
SET KMPPARMS("KMPRUNNS")=$NAMESPACE
+26 FOR
Begin DoDot:1
+27 ; RUN FLAG SET TO 0
IF $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969)'="ON"
SET KMPSTOP=1
QUIT
+28 SET KMPH=$HOROLOG
+29 IF KMPH>KMPCHKH
SET KMPSTOP=1
QUIT
+30 SET KMPSINT=$$GETVAL^KMPVCCFG("VTCM","COLLECTION INTERVAL",8969)
+31 SET KMPHANG=KMPSINT*60
+32 SET KMPPARMS("KMPH")=KMPH
SET KMPPARMS("KMPSINT")=KMPSINT
+33 SET KMPPARMS("KMPHANG")=KMPHANG
+34 MERGE ^KMPTMP("KMPV","VTCM",KMPVNODE,"PARMS")=KMPPARMS
+35 JOB COLLECT(KMPVNODE)
+36 HANG KMPHANG
End DoDot:1
if KMPSTOP
QUIT
+37 IF $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VTCM DRIVER END")
+38 QUIT
+39 ;
COLLECT(KMPVNODE) ;
+1 NEW $ESTACK,$ETRAP
SET $ETRAP="D ^%ZTER Q"
+2 IF $$GETVAL^KMPVCCFG("VTCM","ONOFF",8969,"I")
DO RU^%ZOSVKR("KMP VTCM COLLECTOR")
+3 NEW KMPAE,KMPBCC,KMPBCS,KMPCE,KMPCMET,KMPCSPS,KMPDASH,KMPDATE,KMPDBS,KMPDR,KMPDRDFF,KMPDST,KMPDW,KMPECPAS,KMPECPDS
+4 NEW KMPECPASR,KMPECPDSR,KMPETSO,KMPGR,KMPGRS,KMPGS,KMPH,KMPINST,KMPJE,KMPJMEM,KMPJMMET,KMPJMSG,KMPJS,KMPJSMET,KMPJSON,KMPJST
+5 NEW KMPLB,KMPLC,KMPLH,KMPLL,KMPLR,KMPLT,KMPNEWTS,KMPMEM,KMPMETS,KMPNDTYP,KMPOLDTS,KMPP,KMPPAR,KMPPARMS,KMPPREV,KMPRC,KMPROUT
+6 NEW KMPRR,KMPSA,KMPSEC,KMPSLOT,KMPSMH,KMPSMHC,KMPSMHM,KMPSMHP,KMPSSRC,KMPSSRV,KMPSTAT,KMPSUT,KMPTGST,KMPTIMES,KMPTNS
+7 NEW KMPTSEC,KMPTSMHM,KMPTSMHP,KMPTSMHT,KMPUTCE,KMPUTCO,KMPVBLK,KMPWD,KMPZTS
+8 ;
+9 MERGE KMPPARMS=^KMPTMP("KMPV","VTCM",KMPVNODE,"PARMS")
+10 SET KMPFMDAY=KMPPARMS("KMPFMDAY")
SET KMPWORK=KMPPARMS("KMPWORK")
+11 SET KMPSINF=KMPPARMS("KMPSINF")
SET KMPCHKH=KMPPARMS("KMPCHKH")
+12 SET KMPH=KMPPARMS("KMPH")
SET KMPSINT=KMPPARMS("KMPSINT")
+13 SET KMPINST=KMPPARMS("KMPINST")
SET KMPNDTYP=KMPPARMS("KMPNDTYP")
+14 SET KMPRUNNS=KMPPARMS("KMPRUNNS")
+15 SET U="^"
+16 ;
+17 SET KMPJSON=##class(%DynamicObject).%New()
+18 SET KMPJMSG=##class(%DynamicObject).%New()
+19 SET KMPJMMET=##class(%DynamicObject).%New()
+20 SET KMPCMET=##class(%DynamicObject).%New()
+21 SET KMPJSMET=##class(%DynamicObject).%New()
+22 SET KMPJMEM=##class(%DynamicObject).%New()
+23 SET KMPJSON.Function="VTCM"
+24 SET KMPH=$HOROLOG
+25 SET KMPSLOT=$$SLOT^KMPVCCFG(KMPH,KMPSINT,"HOROLOG")
+26 SET $PIECE(KMPH,",",2)=KMPSLOT
+27 ; yyy-mm-dd hh:mm:ssZts
SET KMPTIMES=$$TSTAMP^KMPUTLW(KMPH,"HOROLOG",1)
+28 SET KMPETSO=$PIECE(KMPTIMES,"^")
+29 SET KMPUTCO=$PIECE(KMPTIMES,"^",2)
+30 SET KMPUTCE=$PIECE(KMPTIMES,"^",3)
+31 SET KMPDST=$PIECE(KMPTIMES,"^",4)
+32 SET KMPDATE=$$SHORTDAT^KMPUTLW(KMPH,"HOROLOG")
+33 ;
+34 DO SITE^KMPUTLW(KMPJSON)
+35 SET KMPJMSG.Timestamp=KMPETSO
SET KMPJMSG.UtcOdbc=KMPUTCO
+36 SET KMPJMSG.UtcEpoch=KMPUTCE
SET KMPJMSG.IsDst=KMPDST
+37 SET KMPJMSG.Node=$PIECE(KMPVNODE,":")
SET KMPJMSG.NodeType=KMPNDTYP
+38 SET KMPJMSG.Instance=KMPINST
SET KMPJMSG.Workday=KMPWORK
+39 SET KMPJMSG.Date=KMPDATE
+40 SET KMPJSON.MessageData=KMPJMSG
+41 ;
+42 ; Get metrics
+43 KILL KMPMETS
+44 DO KMPVVTCM^%ZOSVKSD(.KMPMETS)
+45
*** ERROR ***
IF $NAMESPACE'=KMPRUNNS