» Run/Control External Process from Groovy

The collector exports an Expect-like API allowing you to run/control external processes and deal with their output. The primary methods are:

  • Expect.open(commandLine) - starts the external process represented by the provided command line.
  • expect.stdout() - returns a string containing content from the external process's stdout.
  • expect.stderr() - returns a string containing content from the external process's stderr.
  • expect.exitValue() - returns the exit value of the external process.
  • expect.send(str) - writes a string to stdin of the external process (just like you type a string into an interactive program)
  • expect.expect(regex) - reads content from stdout of the external process until it finds a match.
  • expect.expect(regexs) - reads content from stdout of the external process until it finds a match to any one of regular expression in the provided regular expression array.
  • expect.before() - returns all text up to the expected regular expression.
  • expect.matched() - returns matched text.
  • expect.expectClose() - wait util the external process finishes.

Example 1. use Windows netstat command to count the number of active outgoing HTTP connection

Line 1. import com.santaba.collector.groovyapi.expect.Expect

// example of netstat output:
//  TCP    127.0.0.1:58581        jsong-laptop:58580     ESTABLISHED
//  TCP    192.168.1.100:49928    a72-246-111-51:https   CLOSE_WAIT
//  TCP    192.168.1.100:58034    webcs210p1:5050        ESTABLISHED
//  TCP    192.168.1.100:58551    r1:http                ESTABLISHED
//  TCP    192.168.1.100:58558    74.125.224.40:http     ESTABLISHED
//
// where the last 2 lines are active outgoing HTTP connections
//
Line 2. def cli = Expect.open("netstat.exe -p tcp")
Line 3. cli.expectClose()

Line 4. def cnt = 0
Line 5. s = cli.stdout()
Line 6. s.eachLine { line ->
Line 7.     if ( line =~ /http\s+ESTABLISHED/ ) {
Line 8.       cnt++
Line 9.     }
Line 10. }
Line 11. println cnt

Line 1 - to use collector's expect API, the code needs to put "import com.santaba.collector.groovyapi.expect.Expect" in the begining of the code.

Line 2 - start the external process to execute netstat.exe to print out all TCP connections. Expect.open() will return a client object used to control the external process.

Line 3 - cli.expectClose() waits for the external process to finish.

Line 5 - 10 - process the content of netstat's stdout and increase the counter when it finds a line has the format "... ... ...:http ESTABLISHED"

Example 2. Use nslookup in interactive mode to test a DNS server

Line 1. import com.santaba.collector.groovyapi.expect.Expect
Line 2. def cli = Expect.open( "nslookup.exe" )
Line 3. cli.expect( '> ')
Line 4. cli.send( "server 8.8.4.4\n" )
Line 5. cli.expect('> ')
Line 6. cli.send( "www.yahoo.com\n" )
Line 7. cli.expect('> ')
Line 8. cli.before().eachLine{ line ->
Line 9.   if ( line =~ /Addresses:\s+\d+\.\d+\.\d+\.\d+/ ) {
Line 10.     tokens = line.split(/:\s+/)
Line 11.     println tokens[1]
Line 12.   }
Line 13. }
Line 14. cli.send( "exit\n" )

The code above use nslooup in interactive mode to test if the DNS server 8.8.4.4 can resolve the name www.yahoo.com.

To have you understand the code easier, I paste the screenshot of  a nslookup interactive session here, where '> ' is the command prompt of nslookup.

Line 1 - to use collector's expect API, the code needs to put import com.santaba.collector.groovyapi.expect.Expect in the begining of the code.

Line 2 - start the external process to execute nslookup.exe in the interactive mode.

Line 3 - wait for nslookup to print out the command prompt to accept user's input.

Line 4 - 5 - type in "server 8.8.4.4" that ask nslookup to use 8.8.4.4 as the DNS server and wait for next command prompt from nslookup.

Line 6 -7 - type in "www.yahoo.com" that ask nslookup to resolve its IP address and wait for next commad prompt.

Line 8 - 13 - parse nslookup stdout's content output after we typed in "www.yahoo.com" to search the IP address.

Line 14 - type "exit" to terminate nslookup.