#include #include #include #include #include #include #include ///\brief A class storing information about the cpu the server is running on. class cpudata{ public: std::string model;/// 0){ model = (data + i); } if (sscanf(data, "cpu cores : %d", &i) == 1){ cores = i; } if (sscanf(data, "siblings : %d", &i) == 1){ threads = i; } if (sscanf(data, "physical id : %d", &i) == 1){ id = i; } if (sscanf(data, "cpu MHz : %d", &i) == 1){ mhz = i; } } ; }; ///\brief Checks the capabilities of the system. ///\param capa The location to store the capabilities. void checkCapable(JSON::Value & capa){ //capa.null(); capa.removeMember("cpu"); std::ifstream cpuinfo("/proc/cpuinfo"); if (cpuinfo){ std::map cpus; char line[300]; int proccount = -1; while (cpuinfo.good()){ cpuinfo.getline(line, 300); if (cpuinfo.fail()){ //empty lines? ignore them, clear flags, continue if ( !cpuinfo.eof()){ cpuinfo.ignore(); cpuinfo.clear(); } continue; } if (memcmp(line, "processor", 9) == 0){ proccount++; } cpus[proccount].fill(line); } //fix wrong core counts std::map corecounts; for (int i = 0; i <= proccount; ++i){ corecounts[cpus[i].id]++; } //remove double physical IDs - we only want real CPUs. std::set used_physids; int total_speed = 0; int total_threads = 0; for (int i = 0; i <= proccount; ++i){ if ( !used_physids.count(cpus[i].id)){ used_physids.insert(cpus[i].id); JSON::Value thiscpu; thiscpu["model"] = cpus[i].model; thiscpu["cores"] = cpus[i].cores; if (cpus[i].cores < 2 && corecounts[cpus[i].id] > cpus[i].cores){ thiscpu["cores"] = corecounts[cpus[i].id]; } thiscpu["threads"] = cpus[i].threads; if (thiscpu["cores"].asInt() > thiscpu["threads"].asInt()){ thiscpu["threads"] = thiscpu["cores"]; } thiscpu["mhz"] = cpus[i].mhz; capa["cpu"].append(thiscpu); total_speed += cpus[i].cores * cpus[i].mhz; total_threads += cpus[i].threads; } } capa["speed"] = total_speed; capa["threads"] = total_threads; } std::ifstream cpuUsage("/proc/stat"); if (cpuUsage){ char line[300]; cpuUsage.getline(line, 300); long long int i, o, p, q; if (sscanf(line, "cpu %lli %lli %lli %lli ", &i, &o, &p, &q) == 4){ capa["usage"]["user"] = i; capa["usage"]["nice"] = o; capa["usage"]["system"] = p; capa["usage"]["idle"] = q; }else{ std::cerr << "HALP!" << std::endl; } } std::ifstream meminfo("/proc/meminfo"); if (meminfo){ char line[300]; int bufcache = 0; while (meminfo.good()){ meminfo.getline(line, 300); if (meminfo.fail()){ //empty lines? ignore them, clear flags, continue if ( !meminfo.eof()){ meminfo.ignore(); meminfo.clear(); } continue; } long long int i; if (sscanf(line, "MemTotal : %lli kB", &i) == 1){ capa["mem"]["total"] = i; } if (sscanf(line, "MemFree : %lli kB", &i) == 1){ capa["mem"]["free"] = i; } if (sscanf(line, "SwapTotal : %lli kB", &i) == 1){ capa["mem"]["swaptotal"] = i; } if (sscanf(line, "SwapFree : %lli kB", &i) == 1){ capa["mem"]["swapfree"] = i; } if (sscanf(line, "Buffers : %lli kB", &i) == 1){ bufcache += i; } if (sscanf(line, "Cached : %lli kB", &i) == 1){ bufcache += i; } } capa["mem"]["used"] = capa["mem"]["total"].asInt() - capa["mem"]["free"].asInt() - bufcache; capa["mem"]["cached"] = bufcache; capa["load"]["memory"] = ((capa["mem"]["used"].asInt() + (capa["mem"]["swaptotal"].asInt() - capa["mem"]["swapfree"].asInt())) * 100) / capa["mem"]["total"].asInt(); } std::ifstream loadavg("/proc/loadavg"); if (loadavg){ char line[300]; loadavg.getline(line, 300); //parse lines here float onemin; if (sscanf(line, "%f %*f %*f", &onemin) == 1){ capa["load"]["one"] = (long long int)(onemin*1000); } } std::ifstream netUsage("/proc/net/dev"); capa["net"]["sent"] = 0; capa["net"]["recv"] = 0; while (netUsage){ char line[300]; netUsage.getline(line, 300); long long unsigned sent = 0; long long unsigned recv = 0; //std::cout << line; if (sscanf(line, "%*s %llu %*u %*u %*u %*u %*u %*u %*u %llu", &recv, &sent) == 2){ //std::cout << "Net: " << recv << ", " << sent << std::endl; capa["net"]["recv"] = (long long int)(capa["net"]["recv"].asInt() + recv); capa["net"]["sent"] = (long long int)(capa["net"]["sent"].asInt() + sent); } } } int main(int argc, char** argv){ JSON::Value stats; checkCapable(stats); std::ofstream file(argv[1]); file << "Time in seconds,1m load average,Memory use in bytes,CPU percentage,Uploaded bytes,Downloaded bytes" << std::endl; long long int totalCpu = 0; long long int grandTotal = 0; long long int usrCpu = 0; long long int niceCpu = 0; long long int systemCpu = 0; long long int prevUsrCpu = stats["usage"]["user"].asInt(); long long int prevNiceCpu = stats["usage"]["nice"].asInt(); long long int prevSystemCpu = stats["usage"]["system"].asInt(); long long int prevIdleCpu = stats["usage"]["idle"].asInt(); long long int startUpload = stats["net"]["sent"].asInt(); long long int startDownload = stats["net"]["recv"].asInt(); long long int startTime = Util::epoch(); long long int lastTime = 0; while (true){ Util::sleep(500);//faster than once per second, just in case we go out of sync somewhere if (lastTime == Util::epoch()){ continue;//if a second hasn't passed yet, skip this run } lastTime = Util::epoch(); checkCapable(stats); file << (lastTime - startTime) << ",";//time since start file << (double)stats["load"]["one"].asInt()/1000.0 << ","; //LoadAvg file << stats["mem"]["used"].asString() << ","; //MemUse usrCpu = stats["usage"]["user"].asInt() - prevUsrCpu; niceCpu = stats["usage"]["nice"].asInt() - prevNiceCpu; systemCpu = stats["usage"]["system"].asInt() - prevSystemCpu; totalCpu = usrCpu + niceCpu + systemCpu; grandTotal = totalCpu + stats["usage"]["idle"].asInt() - prevIdleCpu; if (grandTotal != 0){ file << 100 * (double)totalCpu / grandTotal << ",";//totalCpu }else{ file << "," << std::endl;//unknown CPU usage } file << (stats["net"]["sent"].asInt() - startUpload) << "," << (stats["net"]["recv"].asInt() - startDownload) << std::endl; prevUsrCpu = stats["usage"]["user"].asInt(); prevNiceCpu = stats["usage"]["nice"].asInt(); prevSystemCpu = stats["usage"]["system"].asInt(); prevIdleCpu = stats["usage"]["idle"].asInt(); } return 0; }