Question
· Oct 1, 2019

Current rss memory consumption / use of $zf(-100)

I need to know the current rss memory consumption. On earlier Cache versions I used this method:

set sc = ##class(%Net.Remote.Utility).RunCommandViaZF("smem -u cacheusr | grep cacheusr | awk '{print $6}'",,.rss)

It doesn't work because we use $zf(-100) on IRIS 2019.1.

New version:

ClassMethod Test()
{
set cmd = "smem"
set args = 8
set args(1)="-u"
set args(2)="irisusr"
set args(3)="|"
set args(4)="grep"
set args(5)="irisusr"
set args(6)="|"
set args(7)="awk"
set args(8)="'{print $6}'"
set sc = ##class(%Net.Remote.Utility).RunCommandViaZF(cmd,,.rss,,,.code,.args)
//set sc = $zf(-100, "", cmd, .args)
zw rss,sc
}

Produces this output:

zw rss
rss="User     Count     Swap      USS      PSS      RSS
"_$c(13,10)_"daemon       1        0      236      241      664
"_$c(13,10)_"systemd-timesync     1        0      652      799     1848
"_$c(13,10)_"messagebus     1        0     1036     1164     1924
"_$c(13,10)_"systemd-resolve     1        0      968     1193     2424
"_$c(13,10)_"systemd-network     1        0     1220     1227     1752
"_$c(13,10)_"syslog       1        0     1596     1604     2056
"_$c(13,10)_"do-agent     1        0    13236    13305    14320
"_$c(13,10)_"irisusr     22        0   125480   152261   352264
"_$c(13,10)_"root        37        0   456892   476026   585572 "_$c(13,10)

I tried adding "/NOQUOTE" to $zf(-100), however it didn't help.

How do I get the amount of rss memory for irisusr?

I added /LOGCMD and this is what I see in messages.log:

09/05/19-13:02:35:971 (5423) 0 $ZF(-100) argv[0]=smem
09/05/19-13:02:35:971 (5423) 0 $ZF(-100) argv[1]=-u
09/05/19-13:02:35:971 (5423) 0 $ZF(-100) argv[2]=irisusr
09/05/19-13:02:35:971 (5423) 0 $ZF(-100) argv[3]=|
09/05/19-13:02:35:971 (5423) 0 $ZF(-100) argv[4]=grep
09/05/19-13:02:35:971 (5423) 0 $ZF(-100) argv[5]=irisusr
09/05/19-13:02:35:971 (5423) 0 $ZF(-100) argv[6]=|
09/05/19-13:02:35:971 (5423) 0 $ZF(-100) argv[7]=awk
09/05/19-13:02:35:971 (5423) 0 $ZF(-100) argv[8]='{print $6}'
09/05/19-13:02:36:210 (5423) 0 $ZF(-100) ret=0

UPD. Here's a solution.

Discussion (2)0
Log in or sign up to continue
Parameter User = "irisusr";

/// Get memory consumed by irisusr
/// w ##class().GetCurrentMemory()
ClassMethod GetCurrentMemory() As %Integer
{
    Set cmd = "smem"
    Set args = 8
    Set args(1) = "-u"
    Set args(2) = ..#User
    Set args(3) = "|"
    Set args(4) = "grep"
    Set args(5) = ..#User
    Set args(6) = "|"
    Set args(7) = "awk"
    Set args(8) = "'{print $6}'"
    Set sc = ..RunCommandViaZF(cmd,,.rss,,, .code, .args)
    If $$$ISOK(sc){
        Set rss = +rss
        Set ^rss($zdt($h, 3, 1)) = rss
    } Else {
        Set rss = ..#MemoryMax
    }
    Quit rss
}

/// w ##class().GetTotalMemory()
ClassMethod GetTotalMemory() As %Integer
{
    Set cmd = "free"
    Set args = 6
    Set args(1) = "|"
    Set args(2) = "grep"
    Set args(3) = "Mem"
    Set args(4) = "|"
    Set args(5) = "awk"
    Set args(6) = "'{print $2}'"
    Set sc = ..RunCommandViaZF(cmd,,.total,,, .code, .args)
    If $$$ISOK(sc){
        Set total = +total
    } Else {
        Set total = 0
    }
    Quit total
}
/// Run a command using $ZF(-100) and an external temporary file to store the command output. <br>
/// If <var>pDeleteTempFile</var> is 0 (false), the temporary file is not deleted; in this case, it is up to the caller to delete it when done with it.
ClassMethod RunCommandViaZF(pCmd As %String, Output pTempFileName As %String, Output pOutput As %String, pOpenTimeout As %Integer = 5, pDeleteTempFile As %Boolean = 1, Output pRetCode As %String, ByRef pCmdArgs, pAsynchronous As %Boolean = 0) As %Status
{
    Set tSC = $$$OK
    Set pOutput = ""
    Set pRetCode = ""
    Set IO = $IO
    Set ZEOFMode = $ZU(68,40,1)
    Set pTempFileName = ""
    Try {
        Set (tFile,pTempFileName) = ##class(%File).TempFilename("txt")
        If tFile="" Set tSC = $$$ERROR($$$ObjectScriptError, "Failed to obtain a temporary file name") Quit
        Set cmdFlags = "/SHELL /NOQUOTE " _ $Select(pAsynchronous:"/ASYNC",1:"") _"/STDOUT="""_tFile_"""/STDERR="""_tFile_""""
        Set pRetCode = $ZF(-100,cmdFlags,pCmd,.pCmdArgs)
        Close tFile Open tFile:("RS"):pOpenTimeout
        If '$T Set tSC = $$$ERROR($$$ObjectScriptError, "Failed to open temporary file '"_tFile_"'") Quit
        Set TooMuch = 0
        Use tFile
        For {
            // Keep reading through end of file; save only first 32,000 characters
            Set tLine = "" Read tLine:1
            If '$T && (tLine=$C(-1)) Quit  // Exit by timeout
            If 'TooMuch {
                Set:pOutput'="" pOutput = pOutput_$C(13,10)
                If $L(pOutput)+$l(tLine)<32000 {
                    Set pOutput = pOutput_tLine
                }
                Else {
                    Set pOutput = pOutput_$E(tLine,1,32000-$L(pOutput))_" (more...)"
                    Set TooMuch = 1
                }
            }
            If ($ZEOF=-1) Quit  // Exit by EOF
        }
    }
    Catch (ex) {
        Set tSC = ex.AsStatus()
    }
    Try {
        If pDeleteTempFile {
            Close tFile:"D"
        }
        Else {
            Close tFile
        }
    } Catch (ex) {
        // don't overwrite the error status if it's already populated
        Set:$$$ISOK(tSC) tSC = ex.AsStatus()
    }
    If 'ZEOFMode Do $ZU(68,40,0) // Restore ZEOF mode
    Use IO
    Quit tSC
}