Browse Source

!3 new method to get linux system monitor

chenliangyu 1 year ago
parent
commit
ba3d83f100

+ 13 - 1
Module/mod_guiconsole/CMakeLists.txt

@@ -24,12 +24,23 @@ if(Boost_FOUND)
 	MESSAGE( STATUS "Boost_LIB_VERSION = ${Boost_LIB_VERSION}")
 endif()
 
-
+if(MSVC)
+set(${MODULE_PREFIX}_SRCS
+	mod_guiconsole.cpp
+	guiconsole_define.cpp
+	${ThirdPartyHeadRoot}/modp_b64/modp_b64.cc
+	)
+else()
 set(${MODULE_PREFIX}_SRCS
 	mod_guiconsole.cpp
 	guiconsole_define.cpp
 	${ThirdPartyHeadRoot}/modp_b64/modp_b64.cc
+	linux_system_monitor/linux_parser.cpp
+	linux_system_monitor/process.cpp
+	linux_system_monitor/processor.cpp
+	linux_system_monitor/system.cpp
 	)
+endif(MSVC)
 
 set(MOD_VERSION_STRING "0.0.1-dev1")
 add_module_libraries(${MODULE_PREFIX} ${MODULE_NAME} ${MOD_VERSION_STRING})
@@ -43,6 +54,7 @@ target_include_directories(${MODULE_NAME} PRIVATE
 target_link_directories(${MODULE_NAME} PRIVATE
 	${CONAN_LIB_DIRS_JSONCPP}
 	${CONAN_LIB_DIRS_BOOST}
+	linux_system_monitor
 )
 
 # 添加实体需要依赖的其他共享库(包括系统库)

+ 1 - 0
Module/mod_guiconsole/guiconsole_define.cpp

@@ -254,6 +254,7 @@ std::pair<long, std::string> PollProcessList(long UpdateTime, system_monitor_sta
 #include <unordered_map>
 #include <sys/types.h>
 #include <sys/stat.h>
+#include <map>
 
 
 double get_cpu_usage(int pid) {

+ 299 - 0
Module/mod_guiconsole/linux_system_monitor/linux_parser.cpp

@@ -0,0 +1,299 @@
+#include <dirent.h>
+#include <unistd.h>
+#include <string>
+#include <vector>
+#include <iostream>
+
+#include "linux_parser.h"
+
+using std::stof;
+using std::string;
+using std::to_string;
+using std::vector;
+
+// DONE: An example of how to read data from the filesystem
+string LinuxParser::OperatingSystem() {
+  string line;
+  string key;
+  string value;
+  std::ifstream filestream(kOSPath);
+  if (filestream.is_open()) {
+    while (std::getline(filestream, line)) {
+      std::replace(line.begin(), line.end(), ' ', '_');
+      std::replace(line.begin(), line.end(), '=', ' ');
+      std::replace(line.begin(), line.end(), '"', ' ');
+      std::istringstream linestream(line);
+      while (linestream >> key >> value) {
+        if (key == "PRETTY_NAME") {
+          std::replace(value.begin(), value.end(), '_', ' ');
+          return value;
+        }
+      }
+    }
+  }
+  return value;
+}
+
+// DONE: An example of how to read data from the filesystem
+string LinuxParser::Kernel() {
+  string os, kernel, kernel2;
+  string line;
+  std::ifstream stream(kProcDirectory + kVersionFilename);
+  if (stream.is_open()) {
+    std::getline(stream, line);
+    std::istringstream linestream(line);
+    linestream >> os >> kernel >> kernel2;
+  }
+  kernel = kernel + " " + kernel2; 
+  return kernel;
+}
+
+vector<int> LinuxParser::Pids() {
+  vector<int> pids;
+  DIR* directory = opendir(kProcDirectory.c_str());
+  struct dirent* file;
+  while ((file = readdir(directory)) != nullptr) {
+    // Is this a directory?
+    if (file->d_type == DT_DIR) {
+      // Is every character of the name a digit?
+      string filename(file->d_name);
+      if (std::all_of(filename.begin(), filename.end(), isdigit)) {
+        int pid = stoi(filename);
+        pids.push_back(pid);
+      }
+    }
+  }
+  closedir(directory);
+  return pids;
+}
+
+// TODO: Read and return the system memory utilization
+float LinuxParser::MemoryUtilization() { return 0.0; }
+
+// TODO: Read and return the system uptime
+long LinuxParser::UpTime() { 
+  
+  string uptime, line; 
+  
+  string path =  kProcDirectory + "/uptime";
+  std::ifstream filestream(path);
+
+  if (filestream.is_open()) {
+    while (std::getline(filestream, line)) {
+      std::istringstream linestream(line);
+      linestream >> uptime;
+    }
+  }
+  return std::stol(uptime); 
+
+}
+
+// TODO: Read and return the number of jiffies for the system
+long LinuxParser::Jiffies() { return 0; }
+
+// TODO: Read and return the number of active jiffies for a PID
+long LinuxParser::ActiveJiffies(int pid[[maybe_unused]]) { return 0; }
+
+// TODO: Read and return the number of active jiffies for the system
+long LinuxParser::ActiveJiffies() { return 0; }
+
+// TODO: Read and return the number of idle jiffies for the system
+long LinuxParser::IdleJiffies() { return 0; }
+
+// TODO: Read and return CPU utilization
+vector<string> LinuxParser::CpuUtilization() { return {"0.2"}; }
+
+// TODO: Read and return the total number of processes
+int LinuxParser::TotalProcesses() { 
+  
+  vector<int> idVec = LinuxParser::Pids() ;
+  int numProcess = idVec.size();
+
+  return numProcess; 
+}
+
+// TODO: Read and return the number of running processes
+int LinuxParser::RunningProcesses() {
+    
+  vector<int> idVec = LinuxParser::Pids() ;
+  vector<int> idVec_running; 
+
+  
+  for (int pid: idVec){
+     int memory_usage = std::stoi(LinuxParser::Ram(pid));
+     if (memory_usage >0){
+       idVec_running.push_back(pid);
+     }
+  }
+  
+
+  /*
+  for (int pid: idVec){
+     float cpu_utilizaiton = LinuxParser::CpuUtilization(pid);
+     if (cpu_utilizaiton >0.01){
+       idVec_running.push_back(pid);
+     }
+  }
+  */
+
+
+
+  int numProcess_running = idVec_running.size();
+
+  return numProcess_running; 
+}
+
+// TODO: Read and return the command associated with a process
+string LinuxParser::Command(int pid) { 
+  
+  string cmd = "n.a."; 
+  string line;
+
+  string path =  kProcDirectory + "/" + std::to_string(pid) + "/cmdline";
+  std::ifstream filestream(path);
+
+  if (filestream.is_open()) {
+    while (std::getline(filestream, line)) {
+      std::istringstream linestream(line);
+      linestream >> cmd;
+    }
+  }
+  return cmd;
+}
+
+// TODO: Read and return the memory used by a process
+string LinuxParser::Ram(int pid) { 
+  
+  string line;
+  string key;
+  string value = std::to_string(0);
+  string path =  kProcDirectory + "/" + std::to_string(pid) + "/status";
+
+  std::ifstream filestream(path);
+  if (filestream.is_open()) {
+    while (std::getline(filestream, line)) {
+      std::replace(line.begin(), line.end(), ':', ' ');
+      std::istringstream linestream(line);
+      while (linestream >> key >> value) {
+        if (key == "VmRSS") {
+          //std::cout<< " match!" << std::to_string(pid) << " \n";
+          return std::to_string(std::stoi(value)/1024);
+        }
+      }
+    }
+  }
+  return std::to_string(0);
+  
+ }
+
+// TODO: Read and return the user ID associated with a process
+string LinuxParser::Uid(int pid) { 
+  
+  string line;
+  string key;
+  string value;
+  string path =  kProcDirectory + "/" + std::to_string(pid) + "/status";
+
+  std::ifstream filestream(path);
+  if (filestream.is_open()) {
+    while (std::getline(filestream, line)) {
+      std::replace(line.begin(), line.end(), ':', ' ');
+      std::istringstream linestream(line);
+      while (linestream >> key >> value) {
+        if (key == "Uid") {
+          return value;
+        }
+      }
+    }
+  }
+  return value;
+}
+
+// TODO: Read and return the user associated with a process
+string LinuxParser::User(int pid) { 
+  
+  string uid = LinuxParser::Uid(pid); 
+  string uname = "USER";
+
+  string line;
+  string username, x, id;
+ 
+  string path =  "/etc/passwd";
+
+  std::ifstream filestream(path);
+  if (filestream.is_open()) {
+    while (std::getline(filestream, line)) {
+      std::replace(line.begin(), line.end(), ':', ' ');
+      std::istringstream linestream(line);
+      while (linestream >> username >>  x >> id) {
+        if (id == uid) {
+          uname = username;
+        }
+      }
+    }
+  }
+  return uname;
+}
+
+
+// TODO: Read and return the uptime of a process
+long int LinuxParser::UpTime(int pid) { 
+  
+  //std::cout <<"pid:" << pid << "\n"; 
+  string line;
+  string v;
+  string path =  kProcDirectory + "/" + std::to_string(pid) + "/stat";
+
+  long int uptime, starttime;
+
+  std::ifstream filestream(path);
+  if (filestream.is_open()) {
+    while (std::getline(filestream, line)) {
+      std::istringstream linestream(line);
+      for (int i=0; i<22; i++){
+        linestream >> v;
+      }
+     
+      if (std::all_of(v.begin(), v.end(), isdigit)) {
+        starttime = std::stol(v)/sysconf(_SC_CLK_TCK);
+      }
+    }
+  }
+
+  uptime = LinuxParser::UpTime();
+
+  return uptime - starttime;
+  
+}
+
+
+float LinuxParser::CpuUtilization(int pid){
+
+  string line;
+  string v;
+  string path =  kProcDirectory + "/" + std::to_string(pid) + "/stat";
+
+  float cpuTime;
+
+  std::ifstream filestream(path);
+  if (filestream.is_open()) {
+    while (std::getline(filestream, line)) {
+      std::istringstream linestream(line);
+      for (int i=0; i<22; i++){
+        linestream >> v;
+        if (i==13 || i==14 ||  i==15 || i==16){
+          cpuTime += std::stof(v);
+        }
+      }    
+    }
+  }
+
+  float  processUptime = LinuxParser::UpTime();
+  cpuTime /= sysconf(_SC_CLK_TCK);
+
+  float utilization = cpuTime / processUptime; 
+
+  //std::cout << "cpuTime:" << cpuTime <<  " utilization: " << utilization << "\n";
+  return utilization;
+
+}

+ 58 - 0
Module/mod_guiconsole/linux_system_monitor/linux_parser.h

@@ -0,0 +1,58 @@
+#ifndef SYSTEM_PARSER_H
+#define SYSTEM_PARSER_H
+
+#include <fstream>
+#include <regex>
+#include <string>
+
+namespace LinuxParser {
+// Paths
+const std::string kProcDirectory{"/proc/"};
+const std::string kCmdlineFilename{"/cmdline"};
+const std::string kCpuinfoFilename{"/cpuinfo"};
+const std::string kStatusFilename{"/status"};
+const std::string kStatFilename{"/stat"};
+const std::string kUptimeFilename{"/uptime"};
+const std::string kMeminfoFilename{"/meminfo"};
+const std::string kVersionFilename{"/version"};
+const std::string kOSPath{"/etc/os-release"};
+const std::string kPasswordPath{"/etc/passwd"};
+
+// System
+float MemoryUtilization();
+long UpTime();
+std::vector<int> Pids();
+int TotalProcesses();
+int RunningProcesses();
+std::string OperatingSystem();
+std::string Kernel();
+
+// CPU
+enum CPUStates {
+  kUser_ = 0,
+  kNice_,
+  kSystem_,
+  kIdle_,
+  kIOwait_,
+  kIRQ_,
+  kSoftIRQ_,
+  kSteal_,
+  kGuest_,
+  kGuestNice_
+};
+std::vector<std::string> CpuUtilization();
+long Jiffies();
+long ActiveJiffies();
+long ActiveJiffies(int pid);
+long IdleJiffies();
+
+// Processes
+std::string Command(int pid);
+std::string Ram(int pid);
+std::string Uid(int pid);
+std::string User(int pid);
+long int UpTime(int pid);
+float CpuUtilization(int pid);
+};  // namespace LinuxParser
+
+#endif

+ 46 - 0
Module/mod_guiconsole/linux_system_monitor/process.cpp

@@ -0,0 +1,46 @@
+#include <unistd.h>
+#include <cctype>
+#include <sstream>
+#include <string>
+#include <vector>
+
+#include "process.h"
+#include "linux_parser.h"
+
+using std::string;
+using std::to_string;
+using std::vector;
+
+// TODO: Return this process's ID
+int Process::Pid() { return pid; }
+
+// TODO: Return this process's CPU utilization
+float Process::CpuUtilization() const { return LinuxParser::CpuUtilization(pid);}
+
+// TODO: Return the command that generated this process
+string Process::Command() { return LinuxParser::Command(pid); }
+
+// TODO: Return this process's memory utilization
+string Process::Ram() { return LinuxParser::Ram(pid); }
+
+// TODO: Return the user (name) that generated this process
+string Process::User() { return LinuxParser::User(pid); }
+
+// TODO: Return the age of this process (in seconds)
+long int Process::UpTime() { return LinuxParser::UpTime(pid); }
+
+// TODO: Overload the "less than" comparison operator for Process objects
+// REMOVE: [[maybe_unused]] once you define the function
+bool Process::operator<(Process const &b)  { 
+    
+    float a_val = this->CpuUtilization(); 
+    float b_val = b.CpuUtilization();
+
+    if (a_val < b_val) {return true;}
+    else {return false;}
+    
+    }
+
+Process::Process(int id){
+    pid = id; 
+}

+ 30 - 0
Module/mod_guiconsole/linux_system_monitor/process.h

@@ -0,0 +1,30 @@
+#ifndef PROCESS_H
+#define PROCESS_H
+
+#include <string>
+
+#include "processor.h"
+
+
+/*
+Basic class for Process representation
+It contains relevant attributes as shown below
+*/
+class Process {
+ public:
+  int Pid();                               // TODO: See src/process.cpp
+  std::string User();                      // TODO: See src/process.cpp
+  std::string Command();                   // TODO: See src/process.cpp
+  float CpuUtilization() const;                  // TODO: See src/process.cpp
+  std::string Ram();                       // TODO: See src/process.cpp
+  long int UpTime();                       // TODO: See src/process.cpp
+  bool operator<(Process const &b)     ;  // TODO: See src/process.cpp
+  Process(int);
+
+  // TODO: Declare any necessary private members
+ private:
+  int pid; 
+  Processor cpu;
+};
+
+#endif

+ 46 - 0
Module/mod_guiconsole/linux_system_monitor/processor.cpp

@@ -0,0 +1,46 @@
+#include <dirent.h>
+#include <unistd.h>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <thread>
+
+
+
+#include "processor.h"
+#include "linux_parser.h"
+
+
+// TODO: Return the aggregate CPU utilization
+float Processor::Utilization() {  
+
+    float utilization = 0.0;
+
+    std::string line;
+    std::string key;
+    std::string val1, val2;
+    float uptime, idletime;
+    std::string path =  LinuxParser::kProcDirectory + "/uptime";
+
+    std::ifstream filestream(path);
+    if (filestream.is_open()) {
+        while (std::getline(filestream, line)) {
+            std::istringstream linestream(line);
+            while (linestream >> val1 >> val2) {
+                uptime = std::stof(val1);
+                idletime = std::stof(val2);
+            }
+        }
+    }
+    
+   
+    int num_of_cores = std::thread::hardware_concurrency();
+    // std::cout << "num_of_cores:" << num_of_cores << "\n"; 
+
+
+    utilization = (uptime  * num_of_cores - idletime) / (uptime * num_of_cores); 
+    // std::cout <<"uptime: " <<uptime <<  " idletime: " << idletime << " utilization:" <<utilization << "\n";
+    
+    return utilization; 
+
+}

+ 12 - 0
Module/mod_guiconsole/linux_system_monitor/processor.h

@@ -0,0 +1,12 @@
+#ifndef PROCESSOR_H
+#define PROCESSOR_H
+
+class Processor {
+ public:
+  float Utilization();  // TODO: See src/processor.cpp
+
+  // TODO: Declare any necessary private members
+ private:
+};
+
+#endif

+ 122 - 0
Module/mod_guiconsole/linux_system_monitor/system.cpp

@@ -0,0 +1,122 @@
+#include <unistd.h>
+#include <cstddef>
+#include <set>
+#include <string>
+#include <vector>
+#include <iostream>
+#include <typeinfo>
+#include <algorithm>    // std::reverse
+
+
+#include "process.h"
+#include "processor.h"
+#include "system.h"
+#include "linux_parser.h"
+
+using std::set;
+using std::size_t;
+using std::string;
+using std::vector;
+
+#include "linux_parser.h"
+
+
+// TODO: Return the operating system name
+std::string System::OperatingSystem() { 
+    string os =  LinuxParser::OperatingSystem();
+    return os; 
+    }
+
+// TODO: Return the system's kernel identifier (string)
+std::string System::Kernel() { 
+    string kernel = LinuxParser::Kernel();
+    return kernel;
+    }
+
+// TODO: Return the system's CPU 
+Processor& System::Cpu() {  
+    return cpu_; 
+    }
+
+
+// TODO: Return the system's memory utilization
+float System::MemoryUtilization() { 
+    float utilization;
+
+    float totalMemoryUsage = 0;
+
+    vector<int> idVec = LinuxParser::Pids() ;
+    for (int pid : idVec){
+        Process pro(pid);
+        int memory_usage = std::stoi(LinuxParser::Ram(pid));
+        if (memory_usage >0){
+            totalMemoryUsage += memory_usage ;
+        }
+    } 
+
+
+    string cmd = "n.a."; 
+    string line, key, value;
+    string path =  LinuxParser::kProcDirectory + "/meminfo";
+
+    float memoryMax = 1;
+    std::ifstream filestream(path);
+    if (filestream.is_open()) {
+        while (std::getline(filestream, line)) {
+            std::replace(line.begin(), line.end(), ':', ' ');
+            std::istringstream linestream(line);
+            while (linestream >> key >> value) {
+                if (key == "MemTotal") {
+                    memoryMax = std::stoi(value)/1024;
+                }
+            }
+        }
+    }
+
+
+    utilization = totalMemoryUsage / memoryMax; 
+
+    return utilization; }
+
+// TODO: Return the number of processes actively running on the system
+int System::RunningProcesses() { 
+    
+    int runprocess = LinuxParser::RunningProcesses();
+    return runprocess;
+    }
+
+// TODO: Return the total number of processes on the system
+int System::TotalProcesses() { 
+    
+    int ttlprocess = LinuxParser::TotalProcesses();
+    return ttlprocess;
+    }
+
+// TODO: Return the number of seconds since the system started running
+long System::UpTime() { 
+    long uptime = LinuxParser::UpTime();
+    return uptime; 
+    }
+
+// TODO: Return a container composed of the system's processes
+vector<Process>& System::Processes() { 
+    
+    vector<int> idVec = LinuxParser::Pids() ;
+
+    vector<Process> processes_tmp;
+
+    for (int pid : idVec){
+        Process pro(pid);
+        int memory_usage = std::stoi(LinuxParser::Ram(pid));
+        if (memory_usage >0){
+            processes_tmp.push_back(pro);
+        }
+    } 
+
+    processes_ = processes_tmp;
+
+    std::sort(processes_.begin(), processes_.end());
+    std::reverse(processes_.begin(), processes_.end());
+
+    
+    return processes_; }

+ 28 - 0
Module/mod_guiconsole/linux_system_monitor/system.h

@@ -0,0 +1,28 @@
+#ifndef SYSTEM_H
+#define SYSTEM_H
+
+#include <string>
+#include <vector>
+
+
+#include "process.h"
+#include "processor.h"
+
+class System {
+ public:
+  Processor& Cpu();                   // TODO: See src/system.cpp
+  std::vector<Process>& Processes();  // TODO: See src/system.cpp
+  float MemoryUtilization();          // TODO: See src/system.cpp
+  long UpTime();                      // TODO: See src/system.cpp
+  int TotalProcesses();               // TODO: See src/system.cpp
+  int RunningProcesses();             // TODO: See src/system.cpp
+  std::string Kernel();               // TODO: See src/system.cpp
+  std::string OperatingSystem();      // TODO: See src/system.cpp
+
+  // TODO: Define any necessary private members
+ private:
+  Processor cpu_ = {};
+  std::vector<Process> processes_ = {};
+};
+
+#endif