歡迎您光臨本站 註冊首頁

實現真實的機櫃模擬圖

←手機掃碼閱讀     火星人 @ 2014-03-03 , reply:0

實現真實的機櫃模擬圖

 

實現真實的機櫃模擬圖



一般能反映機房設備位置、結構我們都喜歡通過網路拓撲圖來展現,但個人感覺還不夠直觀、明了的表現出自己想要的結果(自己太挑剔了,呵呵)。因此寫一個生成真實機櫃模擬圖平台,實現與真實伺服器外觀、服務狀態、空閑位置等信息。

系統截圖
1、平台顯示某一排截圖


2、平台顯示某台伺服器詳細信息截圖


3、狀態說明
2U伺服器正常狀態

2U伺服器當機狀態


系統原理
       通過獲取運維平台的伺服器信息(包括位置、操作系統、機型等),格式為XML,通過c++的tinyxml來解析並渲染成比較美觀的HTML格式。當機的信息通過Nagios來獲取。這樣就可以生成非常人性化的展現平台了:)



系統代碼Servermap.cpp/***************************************************************************

*   Copyright (C) 2010 by Liu Tiansi   *

*   liutiansi@gmail.com   *

*                                                                         *

*   This program is free software; you can redistribute it and/or modify  *

*   it under the terms of the GNU General Public License as published by  *

*   the Free Software Foundation; either version 2 of the License, or     *

*   (at your option) any later version.                                   *

*                                                                         *

*   This program is distributed in the hope that it will be useful,       *

*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *

*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *

*   GNU General Public License for more details.                          *

*                                                                         *

*   You should have received a copy of the GNU General Public License     *

*   along with this program; if not, write to the                         *

*   Free Software Foundation, Inc.,                                       *

*   59 Temple Place - Suite 330, Boston, MA  02111-1307, CN.             *

***************************************************************************/





#include

#include

#include

#include

#include "tinyxml.h"

#include "tinyxml.cpp"

#include "tinystr.h"

#include "tinystr.cpp"

#include "tinyxmlparser.cpp"

#include "tinyxmlerror.cpp"



using namespace std;



class servermap {



  public:

    servermap( string *serverrow,string _idctype);

    ~servermap();

    string int2str( int num);

    void Getdownserver ();

    string writefile (string filename);

    string GetServerCondition (string ip,string servertype);

    string (*displayXmlDocument_info (string filename));

    void ProduRow();

    void ProduCurrServer();



  private:

    string idctype;

    string (*p_info);  // 所有的伺服器信息指針(從XML文件中遍歷);

    string (*pserver_info);  // 當前機房的伺服器信息指針(從XML文件中遍歷);

    string ServerInfo;  // 所有的伺服器信息數組(從XML文件中遍歷);

    string ServerInfo_CurrServer;  //當前機房數組,從ServerInfo中過濾出來;

    string ServerDownIP;    //當伺服器清單;

    int ServerInfoNumber;  //獲取所有信息的有效行;

    string *CurrServer_row;  //指向當前機房數組的指針;

    int CurrServerInfoNumber;  //獲取當前機房信息的有效行;

    string HTMLstr;    //存儲HTML串;

};



//構造func,傳入排數及機房類型;

servermap::servermap( string *Serverrow,string _idctype)

{

  idctype=_idctype;

  //初始化HTML頭;

  HTMLstr="\n\n\n伺服器模擬狀態圖\n";

  HTMLstr+="\n";

  

  //機房排數組;

  CurrServer_row=Serverrow;

  ServerInfoNumber=0;

  CurrServerInfoNumber=0;



  //獲取當前伺服器清單;

  Getdownserver();



  //遍歷所有伺服器信息;

  displayXmlDocument_info("ServerInfoAll.xml");



  //簡化當前機房伺服器清單;

  ProduCurrServer();

}



//類虛構func,銷毀創建的指針;

servermap::~servermap()

{

  //clear mem;

}



//整形轉字元串方法(來源於互聯網);

string servermap::int2str( int num)

{

    if (num == 0 )

       return " 0 ";

    string str = "" ;

    int num_ = num > 0 ? num : - 1 * num;



    while (num_)

    {

       str = ( char )(num_ % 10 + 48 ) + str;

       num_ /= 10 ;

    }



    if (num < 0 )

       str = " - " + str;

    return str;

}



//返回伺服器狀態圖片;

string servermap::GetServerCondition (string ip,string servertype)

{

  bool Obtaining=false;

  for (int i=0;i<50;i++)

  {

    if (ServerDownIP==ip)

    {

      Obtaining=true;

      break;

    }

  }



  if (servertype=="1U")

  if (Obtaining)

    return "1u_down.gif";

  else return "1u_normal.gif";



  if (servertype=="2U")

  if (Obtaining)

    return "2u_down.gif";

  else return "2u_normal.gif";



  if (servertype=="6U")

  if (Obtaining)

    return "ta_down.gif";

  else return "ta_normal.gif";

}



//獲取當機伺服器清單,從文件中獲取;

void servermap::Getdownserver()

{

  string mainpath="/ServerDownlist";

  string ip;

  ifstream FileObject;

  FileObject.open(mainpath.c_str(),ios::in);

  int i=0;

      while(getline(FileObject,ip))

      {

    ServerDownIP=ip;

    i+=1;

  }

     FileObject.close();

}



//寫配置文件方法,形參為文件名;

string servermap::writefile(string filename)

{

  string mainpath="/www/webroot/"+filename;

  ofstream FileObject;

  FileObject.open(mainpath.c_str(),ios::out);

  FileObject<<HTMLstr<<endl;

     FileObject.close();

  return "1";

}





//獲取XML文件伺服器信息數據到指針;

string (* servermap::displayXmlDocument_info(string filename))

{

  TiXmlDocument doc(filename.c_str());

  doc.LoadFile();

  TiXmlElement *root_r = doc.RootElement();

  //static vector<vector > ClassInfo(m,vector(n));

  int i=0;

  for(TiXmlNode *node = root_r->FirstChild(); node; node = node->NextSibling())

  {

    //輸出元素節點名稱;

    //cout << node->Value() << endl;



    //遍歷輸出節點屬性名稱及值;

    if (node->Type() == TiXmlNode::ELEMENT)

    {

      for(TiXmlAttribute *attr = node->ToElement()->FirstAttribute(); attr; attr = attr->Next())

      {

        cout << "    " << attr->Name() << " =: " << attr->Value() << endl;

      }

    }

    //遍歷輸齣子節點名稱及值;

    TiXmlNode *child = node->FirstChild();

    int j=0;

    while(child)

    {

      int type = child->Type();

      if (type == TiXmlNode::ELEMENT)

      {

        ServerInfo=child->ToElement()->GetText();

      }

      child = node->IterateChildren(child);

      j+=1;

    }

    i+=1;



  }

  ServerInfoNumber=i;

  p_info=ServerInfo;

  //free(ClassInfo);

}



//生成當前機房數組;

void servermap::ProduCurrServer()

{

  const char * strtmp;

  string strswap,stradd,Position0,Position1,Position2,Position3;



  for (int i=0;i<10;i++)

  {

    if (CurrServer_row=="")

      break;

    for (int j=0;j<ServerInfoNumber;j++)

    {

      strswap=*(*(p_info+j)+3);

      strtmp=strswap.c_str();

      Position0=strtmp;

      Position1=strtmp;

      Position2=strtmp;

      Position3=strtmp;

      if (idctype=="idc")

        stradd=Position0+Position1;

      else

        stradd=Position0+Position1+Position2+Position3;

      if (stradd==CurrServer_row)

      {

        CurrServerInfoNumber+=1;

        ServerInfo_CurrServer=*(*(p_info+j)+0);

        ServerInfo_CurrServer=*(*(p_info+j)+1);

        ServerInfo_CurrServer=*(*(p_info+j)+2);

        ServerInfo_CurrServer=*(*(p_info+j)+3);

        ServerInfo_CurrServer=*(*(p_info+j)+4);

      }

    }

  }

  pserver_info=ServerInfo_CurrServer;

}



//生成伺服器拓撲狀態圖;

void servermap::ProduRow()

{

  string point_moddle_key="-0";

  string point_moddle="";

  string point_last="";

  string point_all="";

  string substrServer="";

  string DIVstr="";

  int allservercount=0;

  //所有機櫃循環體;

  for (int i=0;i<10;i++)

  {

    if (CurrServer_row=="")

      break;



    //當前排循環體;

    if (idctype=="idc")

      HTMLstr+="
"+CurrServer_row.substr(0,2)+"排
\n";

    else

      HTMLstr+="
"+CurrServer_row.substr(2,2)+"排
\n";

    HTMLstr+="\n";

          HTMLstr+="\n";



    for (int j=1;j<=7;j++)

    {

      point_moddle=point_moddle_key+int2str(j);

              HTMLstr+="\n";



    }

    HTMLstr+="\n";

      HTMLstr+="
\n";

      //HTMLstr+="
\n"  ;

      HTMLstr+="\n";

            HTMLstr+="\n";

              HTMLstr+="  \n";



      //當前列循環體;

      for (int k=1;k<=10;k++)

      {

        if (k==10)

          point_last="-10";

        else

          point_last=point_moddle_key+int2str(k);

        point_all=CurrServer_row+point_moddle+point_last;



        HTMLstr+="\n";

        HTMLstr+="  \n";

        HTMLstr+="  \n";

      }

      HTMLstr+="
0"+int2str(j)+"
\n";



        for (int m=0;m<=CurrServerInfoNumber;m++)

        {

          //過濾空元素;

          //cout<<point_all<<"=="<<*(*(pserver_info+j)+3)<<endl;

          substrServer=*(*(pserver_info+m)+3);

          if (idctype=="idc")

            substrServer=substrServer.substr(0,8);

          else

            substrServer=substrServer.substr(0,10);

          if (point_all==substrServer)

          {

            DIVstr+="IP:"+*(*(pserver_info+m)+0)+"
";

            DIVstr+="操作系統:"+*(*(pserver_info+m)+2)+"
";

            DIVstr+="位置:"+*(*(pserver_info+m)+3)+"
";

            DIVstr+="機型:"+*(*(pserver_info+m)+4)+"
";

            if (*(*(pserver_info+m)+4)=="1U")

              HTMLstr+="";

            else if (*(*(pserver_info+m)+4)=="2U")

              HTMLstr+="";

            else  HTMLstr+="";



            HTMLstr+="\n";

            allservercount+=1;

            DIVstr="";

            break;

          }

            

        }

        HTMLstr+=" 
\n";

      HTMLstr+="
\n";

        HTMLstr+="

\n";

  }

  HTMLstr+="\n";

}



//類入 口main(),接受用戶參數;

int main()

{

  string * row;

  string idctype="";



  //定義機櫃排號;

  string IDCA={"01","02","03","04","05","06"};

  string IDCC={"18","19","20"};



  

  //IDC A

  idctype="idc";

  row=IDCA;

  servermap appa(row,idctype);

  appa.ProduRow();

  appa.writefile("idca.html");

  //IDC C

  idctype="idc";

  row=IDCC;

  servermap appc(row,idctype);

  appc.ProduRow();

  appc.writefile("idcc.html");



  //free(p);

  return 0;

}
複製代碼XML數據格式

  192.168.0.1

  18

  windows-server

  CC06-05-08

  6U





  192.168.0.2

  19

  linux-server

  CC06-05-07-R

  6U





  192.168.0.3

  20

  windows-server

  CC06-04-07

  6U




複製代碼
《解決方案》

謝謝分享

[火星人 ] 實現真實的機櫃模擬圖已經有1180次圍觀

http://coctec.com/docs/service/show-post-1114.html