zoukankan      html  css  js  c++  java
  • 采用highchart js+flot+rrd生成cpu、mem状态监控图

    HTML

                 <script type="text/javascript" src="../static/js/jquery-1.8.0.min.js"></script>
                <script src="../static/js/highcharts.js"></script>
                <script language='javascript' src='../../src/lib/binaryXHR.js'></script>
                <script language='javascript' src='../../src/lib/rrdFile.js'></script>
                <script type="text/javascript" src="../static/js/get_cpu_mem_data.js"></script>
                <script src="../static/js/highcharts.js"></script>
                <script type="text/javascript" src="../static/js/cpu_memory.js"></script>
                <div class="clearfix">
                    <div id="container" ></div>
                </div>

    js

    binaryXHR.js


    /*
     * BinaryFile over XMLHttpRequest
     * Part of the javascriptRRD package
     * Copyright (c) 2009 Frank Wuerthwein, fkw@ucsd.edu
     * MIT License [http://www.opensource.org/licenses/mit-license.php]
     *
     * Original repository: http://javascriptrrd.sourceforge.net/
     *
     * Based on:
     *   Binary Ajax 0.1.5
     *   Copyright (c) 2008 Jacob Seidelin, cupboy@gmail.com, http://blog.nihilogic.dk/
     *   MIT License [http://www.opensource.org/licenses/mit-license.php]
     */

    // ============================================================
    // Exception class
    function InvalidBinaryFile(msg) {
      this.message=msg;
      this.name="Invalid BinaryFile";
    }

    // pretty print
    InvalidBinaryFile.prototype.toString = function() {
      return this.name + ': "' + this.message + '"';
    }

    // =====================================================================
    // BinaryFile class
    //   Allows access to element inside a binary stream
    function BinaryFile(strData, iDataOffset, iDataLength) {
        var data = strData;
        var dataOffset = iDataOffset || 0;
        var dataLength = 0;
        // added 
        var doubleMantExpHi=Math.pow(2,-28);
        var doubleMantExpLo=Math.pow(2,-52);
        var doubleMantExpFast=Math.pow(2,-20);

        var switch_endian = false;

        this.getRawData = function() {
            return data;
        }

        if (typeof strData == "string") {
            dataLength = iDataLength || data.length;

            this.getByteAt = function(iOffset) {
                return data.charCodeAt(iOffset + dataOffset) & 0xFF;
            }
        } else if (typeof strData == "unknown") {
            dataLength = iDataLength || IEBinary_getLength(data);

            this.getByteAt = function(iOffset) {
                return IEBinary_getByteAt(data, iOffset + dataOffset);
            }
        } else {
          throw new InvalidBinaryFile("Unsupported type " + (typeof strData));
        }

        this.getEndianByteAt = function(iOffset,width,delta) {
          if (this.switch_endian) 
            return this.getByteAt(iOffset+width-delta-1);
          else
            return this.getByteAt(iOffset+delta);
        }

        this.getLength = function() {
            return dataLength;
        }

        this.getSByteAt = function(iOffset) {
            var iByte = this.getByteAt(iOffset);
            if (iByte > 127)
                return iByte - 256;
            else
                return iByte;
        }

        this.getShortAt = function(iOffset) {
                var iShort = (this.getEndianByteAt(iOffset,2,1) << 8) + this.getEndianByteAt(iOffset,2,0)
            if (iShort < 0) iShort += 65536;
            return iShort;
        }
        this.getSShortAt = function(iOffset) {
            var iUShort = this.getShortAt(iOffset);
            if (iUShort > 32767)
                return iUShort - 65536;
            else
                return iUShort;
        }
        this.getLongAt = function(iOffset) {
                var iByte1 = this.getEndianByteAt(iOffset,4,0),
                     iByte2 = this.getEndianByteAt(iOffset,4,1),
                     iByte3 = this.getEndianByteAt(iOffset,4,2),
                     iByte4 = this.getEndianByteAt(iOffset,4,3);

            var iLong = (((((iByte4 << 8) + iByte3) << 8) + iByte2) << 8) + iByte1;
            if (iLong < 0) iLong += 4294967296;
            return iLong;
        }
        this.getSLongAt = function(iOffset) {
            var iULong = this.getLongAt(iOffset);
            if (iULong > 2147483647)
                return iULong - 4294967296;
            else
                return iULong;
        }
        this.getStringAt = function(iOffset, iLength) {
            var aStr = [];
            for (var i=iOffset,j=0;i<iOffset+iLength;i++,j++) {
                aStr[j] = String.fromCharCode(this.getByteAt(i));
            }
            return aStr.join("");
        }

        // Added
        this.getCStringAt = function(iOffset, iMaxLength) {
            var aStr = [];
            for (var i=iOffset,j=0;(i<iOffset+iMaxLength) && (this.getByteAt(i)>0);i++,j++) {
                aStr[j] = String.fromCharCode(this.getByteAt(i));
            }
            return aStr.join("");
        }

        // Added
        this.getDoubleAt = function(iOffset) {
                var iByte1 = this.getEndianByteAt(iOffset,8,0),
                     iByte2 = this.getEndianByteAt(iOffset,8,1),
                     iByte3 = this.getEndianByteAt(iOffset,8,2),
                     iByte4 = this.getEndianByteAt(iOffset,8,3),
                     iByte5 = this.getEndianByteAt(iOffset,8,4),
                     iByte6 = this.getEndianByteAt(iOffset,8,5),
                     iByte7 = this.getEndianByteAt(iOffset,8,6),
                     iByte8 = this.getEndianByteAt(iOffset,8,7);
            var iSign=iByte8 >> 7;
            var iExpRaw=((iByte8 & 0x7F)<< 4) + (iByte7 >> 4);
            var iMantHi=((((((iByte7 & 0x0F) << 8) + iByte6) << 8) + iByte5) << 8) + iByte4;
            var iMantLo=((((iByte3) << 8) + iByte2) << 8) + iByte1;

            if (iExpRaw==0) return 0.0;
            if (iExpRaw==0x7ff) return undefined;

            var iExp=(iExpRaw & 0x7FF)-1023;

            var dDouble = ((iSign==1)?-1:1)*Math.pow(2,iExp)*(1.0 + iMantLo*doubleMantExpLo + iMantHi*doubleMantExpHi);
            return dDouble;
        }
        // added
        // Extracts only 4 bytes out of 8, loosing in precision (20 bit mantissa)
        this.getFastDoubleAt = function(iOffset) {
                var iByte5 = this.getEndianByteAt(iOffset,8,4),
                 iByte6 = this.getEndianByteAt(iOffset,8,5),
                 iByte7 = this.getEndianByteAt(iOffset,8,6),
                 iByte8 = this.getEndianByteAt(iOffset,8,7);
            var iSign=iByte8 >> 7;
            var iExpRaw=((iByte8 & 0x7F)<< 4) + (iByte7 >> 4);
            var iMant=((((iByte7 & 0x0F) << 8) + iByte6) << 8) + iByte5;

            if (iExpRaw==0) return 0.0;
            if (iExpRaw==0x7ff) return undefined;

            var iExp=(iExpRaw & 0x7FF)-1023;

            var dDouble = ((iSign==1)?-1:1)*Math.pow(2,iExp)*(1.0 + iMant*doubleMantExpFast);
            return dDouble;
        }

        this.getCharAt = function(iOffset) {
            return String.fromCharCode(this.getByteAt(iOffset));
        }
    }


    document.write(
        "<script type='text/vbscript'> "
        + "Function IEBinary_getByteAt(strBinary, iOffset) "
        + "    IEBinary_getByteAt = AscB(MidB(strBinary,iOffset+1,1)) "
        + "End Function "
        + "Function IEBinary_getLength(strBinary) "
        + "    IEBinary_getLength = LenB(strBinary) "
        + "End Function "
        + "</script> "
    );



    // ===============================================================
    // Load a binary file from the specified URL 
    // Will return an object of type BinaryFile
    function FetchBinaryURL(url) {
      var request =  new XMLHttpRequest();
      request.open("GET", url,false);
      try {
        request.overrideMimeType('text/plain; charset=x-user-defined');
      } catch (err) {
        // ignore any error, just to make both FF and IE work
      }
      request.send(null);

      var response=request.responseBody;
      if (response==undefined){ // responseBody is non standard, but the only way to make it work in IE
        response=request.responseText;
      }
      var bf=new BinaryFile(response);
      return bf;
    }


    // ===============================================================
    // Asyncronously load a binary file from the specified URL 
    //
    // callback must be a function with one or two arguments:
    //  - bf = an object of type BinaryFile
    //  - optional argument object (used only if callback_arg not undefined) 
    function FetchBinaryURLAsync(url, callback, callback_arg) {
      var callback_wrapper = function() {
        if(this.readyState == 4) {
          var response=this.responseBody;
          if (response==undefined){ // responseBody is non standard, but the only way to make it work in IE
        response=this.responseText;
          }
          var bf=new BinaryFile(response);
          if (callback_arg!=null) {
        callback(bf,callback_arg);
          } else {
        callback(bf);
          }
        }
      }

      var request =  new XMLHttpRequest();
      request.onreadystatechange = callback_wrapper;
      request.open("GET", url,true);
      try {
        request.overrideMimeType('text/plain; charset=x-user-defined');
      } catch (err) {
        // ignore any error, just to make both FF and IE work
      }
      request.send(null);
      return request
    }
    rrdFile.js

    /*
     * Client library for access to RRD archive files
     * Part of the javascriptRRD package
     * Copyright (c) 2009-2010 Frank Wuerthwein, fkw@ucsd.edu
     *                         Igor Sfiligoi, isfiligoi@ucsd.edu
     *
     * Original repository: http://javascriptrrd.sourceforge.net/
     * 
     * MIT License [http://www.opensource.org/licenses/mit-license.php]
     *
     */

    /*
     *
     * RRDTool has been developed and is maintained by
     * Tobias Oether [http://oss.oetiker.ch/rrdtool/]
     *
     * This software can be used to read files produced by the RRDTool
     * but has been developed independently.
     * 
     * Limitations:
     *
     * This version of the module assumes RRD files created on linux 
     * with intel architecture and supports both 32 and 64 bit CPUs.
     * All integers in RRD files are suppoes to fit in 32bit values.
     *
     * Only versions 3 and 4 of the RRD archive are supported.
     *
     * Only AVERAGE,MAXIMUM,MINIMUM and LAST consolidation functions are
     * supported. For all others, the behaviour is at the moment undefined.
     *
     */

    /*
     * Dependencies:
     *   
     * The data provided to this module require an object of a class
     * that implements the following methods:
     *   getByteAt(idx)            - Return a 8 bit unsigned integer at offset idx
     *   getLongAt(idx)            - Return a 32 bit unsigned integer at offset idx
     *   getDoubleAt(idx)          - Return a double float at offset idx
     *   getFastDoubleAt(idx)      - Similar to getDoubleAt but with less precision
     *   getCStringAt(idx,maxsize) - Return a string of at most maxsize characters
     *                               that was 0-terminated in the source
     *
     * The BinaryFile from binaryXHR.js implements this interface.
     *
     */


    // ============================================================
    // Exception class
    function InvalidRRD(msg) {
      this.message=msg;
      this.name="Invalid RRD";
    }

    // pretty print
    InvalidRRD.prototype.toString = function() {
      return this.name + ': "' + this.message + '"';
    }


    // ============================================================
    // RRD DS Info class
    function RRDDS(rrd_data,rrd_data_idx,my_idx) {
      this.rrd_data=rrd_data;
      this.rrd_data_idx=rrd_data_idx;
      this.my_idx=my_idx;
    }

    RRDDS.prototype.getIdx = function() {
      return this.my_idx;
    }
    RRDDS.prototype.getName = function() {
      return this.rrd_data.getCStringAt(this.rrd_data_idx,20);
    }
    RRDDS.prototype.getType = function() {
      return this.rrd_data.getCStringAt(this.rrd_data_idx+20,20);
    }
    RRDDS.prototype.getMin = function() {
      return this.rrd_data.getDoubleAt(this.rrd_data_idx+48);
    }
    RRDDS.prototype.getMax = function() {
      return this.rrd_data.getDoubleAt(this.rrd_data_idx+56);
    }


    // ============================================================
    // RRD RRA Info class
    function RRDRRAInfo(rrd_data,rra_def_idx,
                int_align,row_cnt,pdp_step,my_idx) {
      this.rrd_data=rrd_data;
      this.rra_def_idx=rra_def_idx;
      this.int_align=int_align;
      this.row_cnt=row_cnt;
      this.pdp_step=pdp_step;
      this.my_idx=my_idx;

      // char nam[20], uint row_cnt, uint pdp_cnt
      this.rra_pdp_cnt_idx=rra_def_idx+Math.ceil(20/int_align)*int_align+int_align;
    }

    RRDRRAInfo.prototype.getIdx = function() {
      return this.my_idx;
    }

    // Get number of rows
    RRDRRAInfo.prototype.getNrRows = function() {
      return this.row_cnt;
    }

    // Get number of slots used for consolidation
    // Mostly for internal use
    RRDRRAInfo.prototype.getPdpPerRow = function() {
      return this.rrd_data.getLongAt(this.rra_pdp_cnt_idx);
    }

    // Get RRA step (expressed in seconds)
    RRDRRAInfo.prototype.getStep = function() {
      return this.pdp_step*this.getPdpPerRow();
    }

    // Get consolidation function name
    RRDRRAInfo.prototype.getCFName = function() {
      return this.rrd_data.getCStringAt(this.rra_def_idx,20);
    }


    // ============================================================
    // RRD RRA handling class
    function RRDRRA(rrd_data,rra_ptr_idx,
            rra_info,
            header_size,prev_row_cnts,ds_cnt) {
      this.rrd_data=rrd_data;
      this.rra_info=rra_info;
      this.row_cnt=rra_info.row_cnt;
      this.ds_cnt=ds_cnt;

      var row_size=ds_cnt*8;

      this.base_rrd_db_idx=header_size+prev_row_cnts*row_size;

      // get imediately, since it will be needed often
      this.cur_row=rrd_data.getLongAt(rra_ptr_idx);

      // calculate idx relative to base_rrd_db_idx
      // mostly used internally
      this.calc_idx = function(row_idx,ds_idx) {
        if ((row_idx>=0) && (row_idx<this.row_cnt)) {
          if ((ds_idx>=0) && (ds_idx<ds_cnt)){
        // it is round robin, starting from cur_row+1
        var real_row_idx=row_idx+this.cur_row+1;
        if (real_row_idx>=this.row_cnt) real_row_idx-=this.row_cnt;
        return row_size*real_row_idx+ds_idx*8;
          } else {
        throw RangeError("DS idx ("+ row_idx +") out of range [0-" + ds_cnt +").");
          }
        } else {
          throw RangeError("Row idx ("+ row_idx +") out of range [0-" + this.row_cnt +").");
        }    
      }
    }

    RRDRRA.prototype.getIdx = function() {
      return this.rra_info.getIdx();
    }

    // Get number of rows/columns
    RRDRRA.prototype.getNrRows = function() {
      return this.row_cnt;
    }
    RRDRRA.prototype.getNrDSs = function() {
      return this.ds_cnt;
    }

    // Get RRA step (expressed in seconds)
    RRDRRA.prototype.getStep = function() {
      return this.rra_info.getStep();
    }

    // Get consolidation function name
    RRDRRA.prototype.getCFName = function() {
      return this.rra_info.getCFName();
    }

    RRDRRA.prototype.getEl = function(row_idx,ds_idx) {
      return this.rrd_data.getDoubleAt(this.base_rrd_db_idx+this.calc_idx(row_idx,ds_idx));
    }

    // Low precision version of getEl
    // Uses getFastDoubleAt
    RRDRRA.prototype.getElFast = function(row_idx,ds_idx) {
      return this.rrd_data.getFastDoubleAt(this.base_rrd_db_idx+this.calc_idx(row_idx,ds_idx));
    }

    // ============================================================
    // RRD Header handling class
    function RRDHeader(rrd_data) {
      this.rrd_data=rrd_data;
      this.validate_rrd();
      this.calc_idxs();
    }

    // Internal, used for initialization
    RRDHeader.prototype.validate_rrd = function() {
      if (this.rrd_data.getLength()<1) throw new InvalidRRD("Empty file.");
      if (this.rrd_data.getLength()<16) throw new InvalidRRD("File too short.");
      if (this.rrd_data.getCStringAt(0,4)!=="RRD") throw new InvalidRRD("Wrong magic id.");

      this.rrd_version=this.rrd_data.getCStringAt(4,5);
      if ((this.rrd_version!=="0003")&&(this.rrd_version!=="0004")&&(this.rrd_version!=="0001")) {
        throw new InvalidRRD("Unsupported RRD version "+this.rrd_version+".");
      }

      this.float_width=8;
      if (this.rrd_data.getLongAt(12)==0) {
        // not a double here... likely 64 bit
        this.float_align=8;
        if (! (this.rrd_data.getDoubleAt(16)==8.642135e+130)) {
          // uhm... wrong endian?
          this.rrd_data.switch_endian=true;
        }
        if (this.rrd_data.getDoubleAt(16)==8.642135e+130) {
          // now, is it all 64bit or only float 64 bit?
          if (this.rrd_data.getLongAt(28)==0) {
        // true 64 bit align
        this.int_align=8;
        this.int_width=8;
          } else {
        // integers are 32bit aligned
        this.int_align=4;
        this.int_width=4;
          }
        } else {
          throw new InvalidRRD("Magic float not found at 16.");
        }
      } else {
        /// should be 32 bit alignment
        if (! (this.rrd_data.getDoubleAt(12)==8.642135e+130)) {
          // uhm... wrong endian?
          this.rrd_data.switch_endian=true;
        }
        if (this.rrd_data.getDoubleAt(12)==8.642135e+130) {
          this.float_align=4;
          this.int_align=4;
          this.int_width=4;
        } else {
          throw new InvalidRRD("Magic float not found at 12.");
        }
      }
      this.unival_width=this.float_width;
      this.unival_align=this.float_align;

      // process the header here, since I need it for validation

      // char magic[4], char version[5], double magic_float

      // long ds_cnt, long rra_cnt, long pdp_step, unival par[10]
      this.ds_cnt_idx=Math.ceil((4+5)/this.float_align)*this.float_align+this.float_width;
      this.rra_cnt_idx=this.ds_cnt_idx+this.int_width;
      this.pdp_step_idx=this.rra_cnt_idx+this.int_width;

      //always get only the low 32 bits, the high 32 on 64 bit archs should always be 0
      this.ds_cnt=this.rrd_data.getLongAt(this.ds_cnt_idx);
      if (this.ds_cnt<1) {
        throw new InvalidRRD("ds count less than 1.");
      }

      this.rra_cnt=this.rrd_data.getLongAt(this.rra_cnt_idx);
      if (this.ds_cnt<1) {
        throw new InvalidRRD("rra count less than 1.");
      }

      this.pdp_step=this.rrd_data.getLongAt(this.pdp_step_idx);
      if (this.pdp_step<1) {
        throw new InvalidRRD("pdp step less than 1.");
      }

      // best guess, assuming no weird align problems
      this.top_header_size=Math.ceil((this.pdp_step_idx+this.int_width)/this.unival_align)*this.unival_align+10*this.unival_width;
      var t=this.rrd_data.getLongAt(this.top_header_size);
      if (t==0) {
        throw new InvalidRRD("Could not find first DS name.");
      }
    }

    // Internal, used for initialization
    RRDHeader.prototype.calc_idxs = function() {
      this.ds_def_idx=this.top_header_size;
      // char ds_nam[20], char dst[20], unival par[10]
      this.ds_el_size=Math.ceil((20+20)/this.unival_align)*this.unival_align+10*this.unival_width;

      this.rra_def_idx=this.ds_def_idx+this.ds_el_size*this.ds_cnt;
      // char cf_nam[20], uint row_cnt, uint pdp_cnt, unival par[10]
      this.row_cnt_idx=Math.ceil(20/this.int_align)*this.int_align;
      this.rra_def_el_size=Math.ceil((this.row_cnt_idx+2*this.int_width)/this.unival_align)*this.unival_align+10*this.unival_width;

      this.live_head_idx=this.rra_def_idx+this.rra_def_el_size*this.rra_cnt;
      // time_t last_up, int last_up_usec
      this.live_head_size=2*this.int_width;

      this.pdp_prep_idx=this.live_head_idx+this.live_head_size;
      // char last_ds[30], unival scratch[10]
      this.pdp_prep_el_size=Math.ceil(30/this.unival_align)*this.unival_align+10*this.unival_width;

      this.cdp_prep_idx=this.pdp_prep_idx+this.pdp_prep_el_size*this.ds_cnt;
      // unival scratch[10]
      this.cdp_prep_el_size=10*this.unival_width;

      this.rra_ptr_idx=this.cdp_prep_idx+this.cdp_prep_el_size*this.ds_cnt*this.rra_cnt;
      // uint cur_row
      this.rra_ptr_el_size=1*this.int_width;
      
      this.header_size=this.rra_ptr_idx+this.rra_ptr_el_size*this.rra_cnt;
    }

    // Optional initialization
    // Read and calculate row counts
    RRDHeader.prototype.load_row_cnts = function() {
      this.rra_def_row_cnts=[];
      this.rra_def_row_cnt_sums=[]; // how many rows before me
      for (var i=0; i<this.rra_cnt; i++) {
        this.rra_def_row_cnts[i]=this.rrd_data.getLongAt(this.rra_def_idx+i*this.rra_def_el_size+this.row_cnt_idx,false);
        if (i==0) {
          this.rra_def_row_cnt_sums[i]=0;
        } else {
          this.rra_def_row_cnt_sums[i]=this.rra_def_row_cnt_sums[i-1]+this.rra_def_row_cnts[i-1];
        }
      }
    }

    // ---------------------------
    // Start of user functions

    RRDHeader.prototype.getMinStep = function() {
      return this.pdp_step;
    }
    RRDHeader.prototype.getLastUpdate = function() {
      return this.rrd_data.getLongAt(this.live_head_idx,false);
    }

    RRDHeader.prototype.getNrDSs = function() {
      return this.ds_cnt;
    }
    RRDHeader.prototype.getDSNames = function() {
      var ds_names=[]
      for (var idx=0; idx<this.ds_cnt; idx++) {
        var ds=this.getDSbyIdx(idx);
        var ds_name=ds.getName()
        ds_names.push(ds_name);
      }
      return ds_names;
    }
    RRDHeader.prototype.getDSbyIdx = function(idx) {
      if ((idx>=0) && (idx<this.ds_cnt)) {
        return new RRDDS(this.rrd_data,this.ds_def_idx+this.ds_el_size*idx,idx);
      } else {
        throw RangeError("DS idx ("+ idx +") out of range [0-" + this.ds_cnt +").");
      }    
    }
    RRDHeader.prototype.getDSbyName = function(name) {
      for (var idx=0; idx<this.ds_cnt; idx++) {
        var ds=this.getDSbyIdx(idx);
        var ds_name=ds.getName()
        if (ds_name==name)
          return ds;
      }
      throw RangeError("DS name "+ name +" unknown.");
    }

    RRDHeader.prototype.getNrRRAs = function() {
      return this.rra_cnt;
    }
    RRDHeader.prototype.getRRAInfo = function(idx) {
      if ((idx>=0) && (idx<this.rra_cnt)) {
        return new RRDRRAInfo(this.rrd_data,
                  this.rra_def_idx+idx*this.rra_def_el_size,
                  this.int_align,this.rra_def_row_cnts[idx],this.pdp_step,
                  idx);
      } else {
        throw RangeError("RRA idx ("+ idx +") out of range [0-" + this.rra_cnt +").");
      }    
    }

    // ============================================================
    // RRDFile class
    //   Given a BinaryFile, gives access to the RRD archive fields
    // 
    // Arguments:
    //   bf must be an object compatible with the BinaryFile interface
    //   file_options - currently no semantics... introduced for future expandability
    function RRDFile(bf,file_options) {
      this.file_options=file_options;

      var rrd_data=bf

      this.rrd_header=new RRDHeader(rrd_data);
      this.rrd_header.load_row_cnts();

      // ===================================
      // Start of user functions

      this.getMinStep = function() {
        return this.rrd_header.getMinStep();
      }
      this.getLastUpdate = function() {
        return this.rrd_header.getLastUpdate();
      }

      this.getNrDSs = function() {
        return this.rrd_header.getNrDSs();
      }
      this.getDSNames = function() {
        return this.rrd_header.getDSNames();
      }
      this.getDS = function(id) {
        if (typeof id == "number") {
          return this.rrd_header.getDSbyIdx(id);
        } else {
          return this.rrd_header.getDSbyName(id);
        }
      }

      this.getNrRRAs = function() {
        return this.rrd_header.getNrRRAs();
      }

      this.getRRAInfo = function(idx) {
        return this.rrd_header.getRRAInfo(idx);
      }

      this.getRRA = function(idx) {
        rra_info=this.rrd_header.getRRAInfo(idx);
        return new RRDRRA(rrd_data,
                  this.rrd_header.rra_ptr_idx+idx*this.rrd_header.rra_ptr_el_size,
                  rra_info,
                  this.rrd_header.header_size,
                  this.rrd_header.rra_def_row_cnt_sums[idx],
                  this.rrd_header.ds_cnt);
      }

    }

    get_cpu_mem_data.js

          rrd_data=undefined;
          var cpu_value,mem_value;
          function get_cpu_mem_val(bf) {
              var i_rrd_data=undefined;
              if (bf.getLength()<1) {
                alert("File is empty (possibly loading failed)!");
                return 1;
              }
              
              try {
                var i_rrd_data=new RRDFile(bf);            
              } catch(err) {
                alert("File is not a valid RRD archive! "+err);
              }
              if (i_rrd_data!=undefined) {
                rrd_data=i_rrd_data;
                var rra=rrd_data.getRRA(0);
                var cpu=rra.getElFast(60-1,0);
                var mem=rra.getElFast(60-1,1);
                if (cpu ==undefined){
                    cpu=0;    
                }
                if (mem ==undefined){
                    mem=0;    
                }
                cpu_value=cpu;
                mem_value=mem;
               //alert("cpu:"+cpu+"mem:"+mem); 
              }
              else
              {
                var cpu=0;
                var mem=0;
              }
          }

          function get_cpu_mem(){
            fname="../sysstatus.rrd?rand="+Math.random();
            try {
              FetchBinaryURLAsync(fname,get_cpu_mem_val);
                var  data=[{cpu_value:cpu_value,mem_value:mem_value}];
                return data; 
            } catch (err) {
               alert("Failed loading "+fname+" "+err);
            }
          }
          
         function get_cpu_mem_vals(bf) {
              var i_rrd_data=undefined;
              if (bf.getLength()<1) {
                alert("File is empty (possibly loading failed)!");
                return 1;
              }
              
              try {
                var i_rrd_data=new RRDFile(bf);            
              } catch(err) {
                alert("File is not a valid RRD archive! "+err);
              }
              if (i_rrd_data!=undefined) {
                rrd_data=i_rrd_data;
              }
              
              var rra=rrd_data.getRRA(0);
              var rows=rra.getNrRows();
              for (var i=0; i<rows;i++) {
                var cpu=rra.getElFast(i,0);
                var mem=rra.getElFast(i,1);
              }
          }
          function get_cpu_mems(){
            fname="./sysstatus.rrd";
            try {
              FetchBinaryURLAsync(fname,get_cpu_mem_vals);
            } catch (err) {
               alert("Failed loading "+fname+" "+err);
            }
          }

    cpu_memory.js

               $(function() {
                    Highcharts.setOptions({
                        global: {
                            useUTC: false
                        }
                    });
                       var chart;
                    $('#container').highcharts({
                        credits:{enabled:false},//不显示Highcharts的链接
                        chart: {
                            type: 'spline',
                            marginRight: 150,
                            marginLeft: 50,
                            marginBottom: 25,
                            animation: Highcharts.svg,
                            
                            events: {
                                load: function() {

                                    // 若有第3条线,则添加
                                    // var series_other_property = this.series[2]
                                    // 并在 series: [] 中添加相应的 (name, data) 对
                                    var series_cpu = this.series[0];
                                    var series_mem = this.series[1];

                                    // 定时器,每隔1000ms刷新曲线一次
                                    setInterval(function() {
                                    get_cpu_mem();
                                
                                        // 使用JQuery从后台Servlet获取
                                        // JSON格式的数据,
                                        // 如 "{"cpu": 80,"mem": 10}"
                                        //alert('cpu_value'+cpu_value+',mem_value'+mem_value);
                                    //$.getJSON("", null,function(data) {
                                            // 当前时间,为x轴数据
                                            var x = (new Date()).getTime();
                                            
                                            // y轴数据
                                            var cpu = cpu_value;
                                            var mem = mem_value;

                                            // 更新曲线数据
                                            series_cpu.addPoint([x, cpu], true, true);
                                            series_mem.addPoint([x, mem], true, true);
                                       // });
                                    },
                                    1000/*启动间隔,单位ms*/
                                    );
                                }
                            }
                        },
                        title: {
                            text: 'CPU 内存使用率(%)',
                            x: -20
                        },
                        xAxis: {
                            type: 'datetime',
                            tickPixelInterval: 150
                        },
                        yAxis: {
                            title: {
                                text: 'CPU 内存使用率(%)'
                            },
                            plotLines: [{
                                value: 0,
                                1,
                                color: '#808080'
                            }]
                        },
                        tooltip: {
                               formatter: function() 
                               {
                                    return '<b>'+ this.series.name +'</b><br/>'+
                                    Highcharts.dateFormat('%Y-%m-%d %H:%M:%S', this.x) +'<br/>'+
                                    Highcharts.numberFormat(this.y, 2);
                               }
                               //valueSuffix: '%'
                        },
                        legend: {
                            layout: 'vertical',
                            align: 'right',
                            verticalAlign: 'top',
                            x: -10,
                            y: 100,
                            borderWidth: 0
                        },
                        series: [
                        // 第1条曲线的(name, data)对
                        {
                            name: 'CPU',
                            data: (function() {
                                var data = [],
                                time = (new Date()).getTime(),
                                 
                                 i;
                                // 给曲线y值赋初值0
                                for (i = -9; i <= 0; i++) {
                                    data.push({
                                        x: time + i * 1000,
                                        cpu: 0
                                    });
                                }
                                return data;
                            })()
                        },

                        // 第2条曲线的(name, data)对
                        {
                            name: '内存',
                            data: (function() {
                                var data = [],
                                time = (new Date()).getTime(),
                                                         
                                 i;
                                // 给曲线y值赋初值0
                                for (i = -9; i <= 0; i++) {
                                    data.push({
                                        x: time + i * 1000,
                                        y: 0
                                    });
                                }
                                return data;
                            })()
                        },
                        ]
                    });
                });

  • 相关阅读:
    3-附1 ->和*的区别
    第2章 变量和基本类型
    第2章 变量和基本类型 附3---底层const和顶层const
    第2章 变量和基本类型 附2 --声明和定义的区别
    第2章 变量和基本类型 附1---变量和对象的区别
    第一章 开始
    1. 数据采集基础问题
    跟波利亚学解题---1
    [PTA]L2-001 紧急救援 (25 分)
    [图论]最短路计数(spfa)
  • 原文地址:https://www.cnblogs.com/qingsong/p/5031351.html
Copyright © 2011-2022 走看看