Kyle Ward: Flex, AIR, Flash Developer.   
  • Home
  •  

    Server Load Monitor – With AIR and plink [putty]

    I created a Flex/AIR app that allows us to monitor the CPU usage, Memory usage and Server Load of our off site Linux server.

    It alerts us when any of these values exceed our configured maximums as well as storing the results in a sqlite database for viewing in either graph or table form.

      

    AIR’s Native Process connects to plink, commanding plink to log onto the required server and pass a shell script to be executed.

    Plink – a command-line interface to the PuTTY back ends;

    top.sh:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    #!/bin/sh
    mpstat 1 1 | awk 'NR >3 {print $3}'
    echo "~"
    free -o | grep Mem | awk '{print $2}'
    echo "~"
    free -o | grep Mem | awk '{print $3}'
    echo "~"
    cat /proc/loadavg | awk '{print $1}'
    echo "~"
    cat /proc/loadavg | awk '{print $2}'
    echo "~"
    cat /proc/loadavg | awk '{print $3}'

    The shell script has six commands it expects values back from, they are delimited by tildes to allow me to parse the result of my concatenated ProgressEvent.STANDARD_OUTPUT_DATA results when the NativeProcessExitEvent.EXIT is fired.

    MonitorService.as:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
      //plink command
      private function returnStartupArgs():Vector.<String>
      {
       var output:Vector.<String> = new Vector.<String>();
       
       output.push("-batch");
       output.push("-l");
       output.push(configVO.username);
       output.push("-pw");
       output.push(configVO.password);
       output.push("-m");
       output.push(topSHFile.nativePath);
       output.push(configVO.server);
         
       return output;
      }

      //ProgressEvent.STANDARD_OUTPUT_DATA
      private function handleOutputData(e:ProgressEvent):void
      {
       _output += _process.standardOutput.readUTFBytes(_process.standardOutput.bytesAvailable);
      }

      //NativeProcessExitEvent.EXIT
      private function handleExit(e:NativeProcessExitEvent):void
      {
       var monitorResultVO:MonitorResultVO = iMonitorResultVOParser.createFromString(_output);

       validateMonitorResult(monitorResultVO);
      }
     
      private function validateMonitorResult(monitorResultVO:MonitorResultVO):void
      {
       if (iValidateMonitorResultVO.validate(configVO, monitorResultVO))
       {
        successSignal.dispatch(monitorResultVO);
       }else {
        monitorResultVO.errorCode = MonitorErrorCode.MAXIMUM;
        monitorResultVO.errorMessage = iValidateMonitorResultVO.errorMessage;
       
        failSignal.dispatch(monitorResultVO);
       }
      }
    }

    Gotcha:

    The server’s host key is not cached in the registry. You
    have no guarantee that the server is the computer you
    think it is.
    http://the.earth.li/~sgtatham/putty/0.55/htmldoc/Chapter10.html

    This message comes up if you are trying to access a server and you dont have it’s key in your registry. In putty it is a popup which you click and in plink it requires y/n.

    AIR or plink seems to close the process when this message is recieved and i am unable to repond. I now simply openWithDefaultApplication putty so it can it connect to the server and allow us to respond manually. Not very elegant but it only needs to happen once and then the app can carry on polling the server. Solution pending!

    Leave a Reply