#include "FileHelper.h" #include "ComDef.h" // common #include "File.h" #include "Locks.h" // depends #include "GetNetState.h" // STD #include #include NAMESPACE_MAS_BEGIN FileHelper * FileHelper::_ins = nullptr; tzc::Mutex FileHelper::_insLock; FileHelper * FileHelper::GetInstance() { if (!_ins) { _insLock.Lock(); if (!_ins) { _ins = new FileHelper(); } _insLock.Unlock(); } return _ins; } void FileHelper::DestoryInstance() { tzc::ScopedLock lock(_insLock); TZ_delete(_ins); } void FileHelper::GetSysStatData(SysStatInfo & data) { FILE * file = fopen("/proc/stat", "r"); if (nullptr == file) { TZLogError("file[/proc/stat] open failed!!!"); return; } TZ_CHAR buff[1024]; if (nullptr == fgets(buff, 1024, file)) { fclose(file); TZLogError("file[/proc/stat] read failed!!!"); return; } fclose(file); TZLogDebug(1, "[%s] read from [/proc/stat]~~~", buff); std::stringstream stream(buff); char tmp[16]; stream >> tmp; // cpuXX stream >> data.user; stream >> data.system; stream >> data.idle; stream >> data.iowait; stream >> data.irq; stream >> data.softirq; } void FileHelper::GetSysMemData(SysMemInfo & data) { FILE * file = fopen("/proc/meminfo", "r"); if (nullptr == file) { TZLogError("file[/proc/meminfo] open failed!!!"); return; } std::string name; TZ_ULONG num; TZ_CHAR buff[1024]; while (fgets(buff, 1024, file)) { TZLogDebug(1, "[%s] read from [/proc/meminfo]~~~", buff); std::stringstream stream(buff); stream >> name; stream >> num; if ("MemTotal:" == name) { data.MemTotal = num; } else if ("MemAvailable:" == name) { data.MemAvailable = num; } } fclose(file); } void FileHelper::GetSysDiskIOData(std::list & datas) { FILE * file = fopen("/proc/diskstats", "r"); if (nullptr == file) { TZLogError("file[/proc/diskstats] open failed!!!"); return; } TZ_CHAR buff[1024]; while (fgets(buff, 1024, file)) { SysDiskStatInfo data; std::stringstream stream(buff); stream >> data.MainDevIndex; stream >> data.SubDevIndex; stream >> data.DevName; /* FIXME: 多磁盘下,筛选要获取的磁盘信息 */ if (data.DevName != "sda" && data.DevName != "sdb" && data.DevName != "sdc" && data.DevName != "sdd" /* && info.DevName != "XXX" */ ) continue; stream >> data.ReadFinishCount; stream >> data.MergeReadFinishedCount; stream >> data.ReadSectionCount; stream >> data.ReadMilinSeconds; stream >> data.WriteFinishedCount; stream >> data.MergeWriteFinishedCount; stream >> data.WriteSectionCount; stream >> data.WriteMilinSeconds; stream >> data.ProcingIO; stream >> data.IOMilinSeconds; stream >> data.IOMilinSecondsAvg; struct timeval tv; gettimeofday(&tv, nullptr); data.collectTime = tv.tv_sec; datas.push_back(data); } fclose(file); } void FileHelper::GetSysNetBandData(std::list & datas) { FILE * file = fopen("/proc/net/dev", "r"); if (nullptr == file) { TZLogError("file[/proc/net/dev] open failed!!!"); return; } TZ_CHAR buff[1024]; fgets(buff, 1024, file); fgets(buff, 1024, file); while (fgets(buff, 1024, file)) { SysNetBandInfo data; std::stringstream stream(buff); stream >> data.NicName; data.NicName[data.NicName.size() - 1] = '\0'; stream >> data.Receive.bytes; stream >> data.Receive.packets; stream >> data.Receive.errs; stream >> data.Receive.drop; stream >> data.Receive.fifo; stream >> data.Receive.frame; stream >> data.Receive.compressed; stream >> data.Receive.multicast; stream >> data.Transmit.bytes; stream >> data.Transmit.packets; stream >> data.Transmit.errs; stream >> data.Transmit.drop; stream >> data.Transmit.colls; stream >> data.Transmit.carrier; stream >> data.Transmit.compressed; TZ_INT sock = if_socket(); if (MEC_FAILED == sock) { close(sock); continue; } TZ_UINT bandWidth = 0; get_ifethspeed(sock, data.NicName.c_str(), &bandWidth); data.BandWidth = bandWidth; close(sock); struct timeval tv; gettimeofday(&tv, nullptr); data.collectTime = tv.tv_sec; datas.push_back(data); } fclose(file); } void FileHelper::GetSystemInfo(SystemInfo & info) { getSingalCmdResult("uname -a", info.Origin); getSingalCmdResult("uname -s", info.KernelName); getSingalCmdResult("uname -r", info.KernelRelease); getSingalCmdResult("uname -v", info.KernelVesion); getSingalCmdResult("uname -o", info.OperatingSystem); getSingalCmdResult("uname -m", info.Machine); getSingalCmdResult("uname -n", info.NodeName); TZLogDebug(10, "Origins),KernelName(%s),KernelRelease(%s),KernelVesion(%s)," "OperatingSystem(%s),Machine(%s),NodeName(%s)", info.KernelName.c_str(), info.KernelRelease.c_str(), info.KernelVesion.c_str(), info.OperatingSystem.c_str(), info.Machine.c_str(), info.NodeName.c_str()); } void FileHelper::GetCPUInfo(CPUInfo & info) { /* FIXME:仅能获取配有多个同型号CPU的信息 */ std::string cmdName = "cat /proc/cpuinfo |grep 'model name'"; FILE * file = popen(cmdName.c_str(), "r"); if (nullptr == file) { TZLogError("cmd[%s] exec failed!!!", cmdName.c_str()); return; } TZ_CHAR buff[1024]; if (nullptr == fgets(buff, 1024, file)) { pclose(file); TZLogError("cmd[%s] read failed!!!", cmdName.c_str()); return; } pclose(file); std::string res(buff); size_t cur = res.find(":"); if (std::string::npos != cur) { info.CPUName.assign(res.c_str() + cur + 2); info.CPUName[info.CPUName.size() - 1] = '\0'; } res.clear(); getSingalCmdResult("cat /proc/cpuinfo | grep \"physical id\" | sort | uniq |wc -l", res); info.CPUPhysicalNum = std::atoi(res.c_str()); res.clear(); getSingalCmdResult("cat /proc/cpuinfo| grep \"processor\"| wc -l", res); info.CPULogicNum = std::atoi(res.c_str()); /* !! KylinOS 不支持此命令 */ res.clear(); getSingalCmdResult("cat /proc/cpuinfo| grep \"cpu cores\" | uniq", res); std::stringstream ss(res.c_str()); ss >> res; ss >> res; ss >> res; ss >> info.CPUCoreNum; TZLogDebug(10, "[%s](%d)(%d)(%d)", info.CPUName.c_str(), info.CPUPhysicalNum, info.CPUCoreNum, info.CPULogicNum); } void FileHelper::GetNetPortInfo(std::list & infos) { FILE * file = popen("netstat -anupt", "r"); if (nullptr == file) { TZLogError("cmd[netstat -anupt] exec failed!!!"); return; } TZ_CHAR buff[4096]; /* 前2行是无效信息(有可能是4行) */ TZ_BOOL isAviled = FALSE; while (fgets(buff, 4096, file)) { if (std::string(buff).find("Proto") != std::string::npos) { isAviled = TRUE; break; } } if (isAviled == FALSE) { pclose(file); return; } infos.clear(); while (fgets(buff, 4096, file)) { NetstatInfo info; std::stringstream stream(buff); stream >> info.Proto; stream >> info.RecvQ; stream >> info.SendQ; stream >> info.LocalAddress; stream >> info.ForeignAddress; stream >> info.State; stream >> info.Pid_Pname; infos.push_back(info); } pclose(file); } void FileHelper::GetDiskInfo(std::list & infos) { FILE * file = popen("df", "r"); if (nullptr == file) { TZLogError("cmd[df] exec failed!!!"); return; } infos.clear(); TZ_CHAR buff[4096]; fgets(buff, 4096, file); while (fgets(buff, 4096, file)) { DiskstatInfo info; std::stringstream stream(buff); stream >> info.Filesystem; stream >> info.Blocks_1K; stream >> info.Used; stream >> info.Available; stream >> info.UseRate; stream >> info.MountedOn; infos.push_back(info); } pclose(file); } void FileHelper::GetGPUInfo(std::string & info) { /* * FIXME: nvidia-smi命令不是必装项, * 此函数可以完善 */ std::string res; getSingalCmdResult("lspci | grep -i vga", res); size_t pos = res.find("controller: "); if (std::string::npos == pos) return; info = res.substr(pos + 12, res.length() - pos - 13); } TZ_INT FileHelper::GetInterFaceInfo(std::list & infos) { TZ_INT sock = if_socket(); if (MEC_FAILED == sock) { close(sock); return MEC_FAILED; } TZ_CHAR addr[64]{ '\0' }; TZ_INT addrlen(64); TZLogDebug(10, "info size %d", infos.size()); for (auto & iter : infos) { if (MEC_FAILED == get_ifhwaddr(sock, iter.Name.c_str(), addr, addrlen)) { TZLogError("get_ifhwaddr error[%s]!!!", iter.Name.c_str()); } iter.HwAddr.assign(addr); memset(addr, '\0', 64); if (MEC_FAILED == get_ifaddr(sock, iter.Name.c_str(), addr, addrlen)) { TZLogError("get_ifaddr error[%s]!!!", iter.Name.c_str()); } iter.InetAddr.assign(addr); memset(addr, '\0', 64); if (-1 == get_ifnetMask(sock, iter.Name.c_str(), addr, addrlen)) { TZLogError("get_ifnetMask error[%s]!!!", iter.Name.c_str()); } iter.Netmask.assign(addr); memset(addr, '\0', 64); if (-1 == get_ifstat(sock, iter.Name.c_str(), &(iter.Status))) { TZLogError("get_ifstat error[%s]!!!", iter.Name.c_str()); } if (35 == iter.Status) iter.Status = 1; else iter.Status = 0; } close(sock); std::string filename = "/proc/net/if_inet6"; std::string buf, ipv6addr; /* 该类型打开文件操作可以直接忽略空格进行赋值 */ std::fstream file; file.open(filename, std::ios::in); while (!(EOF == file.peek())) { for (TZ_INT i = 0; i < 6 && !(EOF == file.peek()); i++) { file >> buf; if (i == 0) ipv6addr = buf; if (i == 5) { for (auto& iter : infos) { if (buf == iter.Name) { iter.Inet6Addr += ipv6addr.substr(0, 4); iter.Inet6Addr += "::"; for (TZ_INT i = 0; i < 3; i++) { iter.Inet6Addr += ipv6addr.substr(16 + i * 4, 4); iter.Inet6Addr += ":"; } iter.Inet6Addr += ipv6addr.substr(28, 4); } } } } } file.close(); return MEC_OK; } void FileHelper::GetComponentFilePaths( const std::string & root, std::set & paths) { DIR * dirp = opendir(root.c_str()); if(!dirp) { TZLogWarn("open dir %s failed!!!", root.c_str()); return; } dirent * dir_entry = nullptr; while(dir_entry = readdir(dirp)) { std::string relFName = dir_entry->d_name; if (relFName.size() < sizeof(SO_SUFFIX)) continue; std::string extname = relFName.substr( relFName.size() - sizeof(SO_SUFFIX) + 1); if (extname == SO_SUFFIX) { paths.insert(root + relFName); } } closedir(dirp); } void FileHelper::getSingalCmdResult(const std::string & cmd, std::string & res) { if (cmd.size() <= 0) return; FILE * pin = popen(cmd.c_str(), "r"); if (!pin) return; TZ_CHAR buffer[1024] {0}; if (nullptr == fgets(buffer, 1024, pin)) { pclose(pin); return; } pclose(pin); TZLogDebug(1, "%s", buffer); std::string result(buffer); if (result.size() >= 1) /* 结果最后有一个\n */ { res.assign(result.c_str(), result.size() - 1); } } void FileHelper::getPairValues(const std::string & str, TZ_ULONG & values) { std::stringstream stream(str); std::string item; stream >> item; stream >> values; } void FileHelper::getPairValues(const std::string & str, TZ_ULONGLONG & values) { std::stringstream stream(str); std::string item; stream >> item; stream >> values; } FileHelper::FileHelper() { } FileHelper::~FileHelper() { } NAMESPACE_MAS_END