實現真實的機櫃模擬圖
實現真實的機櫃模擬圖
一般能反映機房設備位置、結構我們都喜歡通過網路拓撲圖來展現,但個人感覺還不夠直觀、明了的表現出自己想要的結果(自己太挑剔了,呵呵)。因此寫一個生成真實機櫃模擬圖平台,實現與真實伺服器外觀、服務狀態、空閑位置等信息。
系統截圖
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
複製代碼 《解決方案》
謝謝分享