Menu

Is there a way to get STAF command status in live

Mojo
2013-07-07
2013-08-23
  • Mojo

    Mojo - 2013-07-07

    Hi,
    I'll try to make myself clearer.
    I have a command that runs something like 10 minutes, and I want to get the command status in live, I mean , for example , I want to ping from one machine to another for 10 minutes, but I want staf to show the command output , as long as there is one ofcourse, and not to wait to the command to end to determine its status.

    Thanks

     
  • Sharon Lucas

    Sharon Lucas - 2013-07-08

    STAF doesn't provide a direct way to get the content of a process's stdout/stderr while the process is running. It doesn't provide the ability to return the process's stdout/stderr until the process completes. However, you could specify the name of the stdout/stderr file when starting the process using the STDOUT option. Then, while the process is running, you could access this file by submitting a STAF FS GET FILE request, or submit a PROCESS START request that runs a command like tail or cat to get the contents of the stdout file name you specified.

    We also have a feature request open that would enable this to be done in another way (but it is not implemented yet). For more information see Feature #523877 "Add open/read/write/close support to FS" at http://sourceforge.net/tracker/?func=detail&aid=523877&group_id=33142&atid=407384.

     
  • Cathy Pedersen

    Cathy Pedersen - 2013-08-23

    Can you provide examples of these 2 options for capturing the stdout in the STAX screen? I've been trying various permutations without much luck. Thank you.

     
  • Sharon Lucas

    Sharon Lucas - 2013-08-23

    Here's an example of a STAX job that can use either:
    - a FS GET FILE request to get the entire contents of the process's stdout file
    or
    - a 'tail -n10' command to get the last 10 lines of the process's stdout file

    and display the stdout data in the "Messages" panel of the STAX Monitor (and log it to the STAX Job User's log file).

    <?xml version="1.0" encoding="UTF-8" standalone="no"?>
    <!DOCTYPE stax SYSTEM "stax.dtd">
    
    <stax>
    
    <defaultcall function="Main"/>
    
    <function name="Main">
      <sequence>
    
        <script>
          # Set to either 'FS' or 'tail'.
          # 'FS' indicates to get the entire contents of the stdout file
          #      using a FS GET FILE request, or
          # 'tail' indicates to get the last 10 lines of the stdout file
          #      using the tail command.
          getMethod = 'FS'
    
          pingMachine = 'staf1e'  # Set to the host name or an IP address of
                                # a system in your network
        </script>
    
        <!-- This example is running a process that never completes, a
             continuous ping command so need a timer to stop it after 1 minute.
             Instead of using a continue ping command (just becaues it
             continuously generates output) to demonstrate retrieving process
             output while the process is still running, you would set the
             command value with whatever your real command is and probably
             remove the timer element enclosing the call to the RunProcess
             function.
          -->
        <timer duration="'1m'">
          <call function="'RunProcess'">
            {
             'machine': 'local',
             'command': 'ping -t %s' % (pingMachine), 
             'stdoutFileName': 'C:/temp/process.out'
            }
          </call>
        </timer>
    
      </sequence>
    </function>
    
    <function name="RunProcess">
      <function-map-args>
        <function-required-arg name="machine">
          Machine where the process will be run
        </function-required-arg>
        <function-required-arg name="command">
          The command to be run on the specified machine via the process element
        </function-required-arg>
        <function-optional-arg name="stdoutFileName" default="'/tmp/process.out'">
          The name of the file on the specified machine where the process's
          stdout/stderr data will be written
        </function-optional-arg>
      </function-map-args>
    
      <sequence>
    
        <process name="command">
          <location>machine</location>
          <command mode="'shell'">command</command>
          <stdout>stdoutFileName</stdout>
          <stderr mode="'stdout'"/>
          <returnstdout/>
          <!-- Uses a process-action sub-element to run a task in parallel while
               the process is running to retrieve data from the process's stdout/
               stderr file -->
          <process-action>
            <call function="'GetProcessOutput'">
              {
                'machine': machine,
                'stdoutFileName': stdoutFileName,
                'getMethod': getMethod,
                'delayTime': '10s'
              }
            </call>
          </process-action>
        </process>
    
        <script>
          processRC = RC
    
          # Get the process's complete stdout/stderr from the STAXResult
          if STAXResult != None:
            processStdout = STAXResult[0][1]
          else:
            processStdout = None
        </script>
    
        <if expr="RC != 0">
          <log message="1" level="'error'">
            """Process failed. RC=%d, STAFResult=%s, Stdout:
            %s""" % (processRC, STAFResult, processStdout)
          </log>
          <else>
            <log message="1">
              """Process completed successfully (RC=0) Stdout:
              %s""" % (processStdout)
            </log>
          </else>        
        </if>
    
        <return>processRC</return>
    
      </sequence>
    
    </function>
    
    <function name="GetProcessOutput">
      <function-map-args>
        <function-required-arg name="machine">
          Machine where the process will be run
        </function-required-arg>
        <function-required-arg name="stdoutFileName">
          The name of the file on the specified machine where the process's
          stdout/stderr data will be written
        </function-required-arg>
        <function-optional-arg name="getMethod" default="'FS'">
          Specifies whether to get the last 10 lines of data in the process's
          stdout file or to submit a GET FILE request to the FS service to get
          the entire contents of the process stdout file.  Valid values are
          'tail' or 'FS' and it defaults to 'FS'.  Note: To use tail, this
          command must be available on the system where the process is running.
          Unix systems provide the tail command and on Windows if you have
          Cygwin installed and in the PATH you can use the tail command.
        </function-optional-arg>
        <function-optional-arg name="delayTime" default="'10s'">
          Time to wait during a loop before getting the process's stdout/stderr
          e.g. 10s, 30s, 1m, 30m, 1h, 1d, dtc
        </function-optional-arg>
      </function-map-args>
    
      <block name="'GetProcessOutput'">
        <sequence>
          <!-- 
          While the process is still running, in a loop that continues until
          the process has completed, wait for the specified delayTime and then
          retrieve the last xx lines of output written to the process's
          stdout/stderr file.  To determine if the process is still running,
          it submits a PROCESS QUERY HANDLE reuqest specifying STAXProcessHandle
          which contains the handle of the process and if it fails, it assumes
          the process is no longer running.
          -->
    
          <script>
            processComplete = 0
            delayTime = '10s' # You can set this to how long you want to wait
                              # before getting the process's stdout/stderr
                              # e.g. 10s, 30s, 1m, 30m, 1h, 1d, etc
    
            if getMethod == 'tail':
              numLines = 10   # You can configure to the number of lines in the
                              # process's stdout file that you want the tail
                              # command to return.
              command = 'tail -n%s %s' % (numLines, stdoutFileName)
            else:
              request = 'GET FILE %s TEXT' % (stdoutFileName)
    
            msg = ''
          </script>
    
          <loop until="processComplete">
            <sequence>
    
              <stafcmd name="'Delay %s' % (delayTime)">
                <location>'local'</location>
                <service>'DELAY'</service>
                <request>'DELAY %s' % (delayTime)</request>
              </stafcmd>
    
              <if expr="getMethod == 'tail'">
                <sequence>
                  <!-- Use tail to get the last 10 lines in the stdout file -->
    
                  <process name="command">
                    <location>machine</location>
                    <command>command</command>
                    <stderr mode="'stdout'"/>
                    <returnstdout/>
                  </process>
    
                  <script>
                    if RC == 0:
                      if STAXResult != None:
                        msg = STAXResult[0][1]
                      else:
                        msg = None
                    else:
                      msg = 'Command "%s" failed with RC=%s STAFResult=%s STAXResult=%s' % \
                            (command, RC, STAFResult, STAXResult)
                  </script>
                </sequence>
                <else>
                  <sequence>
                    <!-- Submit a FS GET FILE command to get the contents of
                         the stdout file -->
    
                    <stafcmd name="request">
                      <location>machine</location>
                      <service>'FS'</service>
                      <request>request</request>
                    </stafcmd>
    
                    <script>
                      if RC == 0:
                        msg = STAFResult
                      else:
                        msg = 'STAF %s FS %s failed with RC=%s Result=%s' % \
                              (machine, request, RC, STAFResult)
                    </script>
                  </sequence>
                </else>
              </if>
    
              <log message="1">msg</log>
    
              <!-- Now check if the process is still running -->
    
              <stafcmd>
               <location>machine</location>
               <service>'PROCESS'</service>
               <request>'QUERY HANDLE %s' % (STAXProcessHandle)</request>
              </stafcmd>
    
              <if expr="RC != 0">
                <sequence>
                  <log message="1">
                    'STAF %s PROCESS QUERY HANDLE %s failed with RC=%s Result=%s' % \
                    (RC, STAFResult)
                  </log>
                  <script>processComplete = 1</script>
                </sequence>
              </if>
    
            </sequence>
          </loop>
    
        </sequence>
      </block>
    </function>
    
    </stax>
    
     

Log in to post a comment.