main.cpp 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. #include <iostream>
  2. #include <string>
  3. #include <cstdlib>
  4. #include <chrono>
  5. #include <thread>
  6. #include <boost/filesystem.hpp>
  7. #include "json/json.h"
  8. #include "defines.hpp"
  9. const char* DEFAULT_WATCH_DOG_CONFIG_PATH = ETC_PATH"WatchDog/watch_dog.json";
  10. // 递归计算目录大小
  11. std::uintmax_t calculateDirectorySize(const boost::filesystem::path& path) {
  12. if (!boost::filesystem::exists(path)) {
  13. LOG(ERROR) << path << "not exist!!!!!";
  14. return 0;
  15. }
  16. std::uintmax_t size = 0;
  17. for (const auto& entry : boost::filesystem::recursive_directory_iterator(path)) {
  18. if (boost::filesystem::is_regular_file(entry)) {
  19. size += boost::filesystem::file_size(entry);
  20. }
  21. }
  22. return size;
  23. }
  24. // 删除最后修改时间最早的文件
  25. void deleteOldestFile(const boost::filesystem::path& directoryPath) {
  26. boost::filesystem::path oldestFilePath;
  27. std::time_t oldestTime = std::numeric_limits<std::time_t>::max();
  28. for (const auto& entry : boost::filesystem::directory_iterator(directoryPath)) {
  29. if (boost::filesystem::is_regular_file(entry)) {
  30. const std::time_t lastModifiedTime = boost::filesystem::last_write_time(entry);
  31. if (lastModifiedTime < oldestTime) {
  32. oldestTime = lastModifiedTime;
  33. oldestFilePath = entry.path();
  34. }
  35. }
  36. }
  37. if (!oldestFilePath.empty()) {
  38. try {
  39. boost::filesystem::remove(oldestFilePath);
  40. LOG(INFO) << "Deleted file: " << oldestFilePath << std::endl;
  41. } catch (const std::exception& e) {
  42. LOG(ERROR) << "Failed to delete file: " << oldestFilePath << ", Error: " << e.what() << std::endl;
  43. }
  44. } else {
  45. LOG(WARNING) << "No files found in the directory." << oldestFilePath << std::endl;
  46. }
  47. }
  48. int main(int argc, char** argv) {
  49. std::string config_path;
  50. if (argc > 1) {
  51. config_path = argv[1];
  52. }
  53. else {
  54. config_path = DEFAULT_WATCH_DOG_CONFIG_PATH;
  55. }
  56. ZX::InitGlog("WatchDog", ETC_PATH"WatchDog/WatchDogLog/");
  57. LOG(INFO) << "load etc file from: " << DEFAULT_WATCH_DOG_CONFIG_PATH;
  58. Json::Value config_json;
  59. if (false == ReadJsonFile(config_path, config_json) || !config_json.isMember("process") || !config_json["process"].isArray()) {
  60. auto time = std::chrono::steady_clock::now();
  61. std::chrono::duration<double> diff = std::chrono::steady_clock::now() - time;
  62. while (diff.count() < 10) {
  63. LOG(ERROR) << "watch Program is empty!!! after " << 10 - diff.count() << "s, system will restart." << std::endl;
  64. std::this_thread::sleep_for(std::chrono::seconds(1));
  65. diff = std::chrono::steady_clock::now() - time;
  66. }
  67. system("systemctl reboot");
  68. exit(-1);
  69. }
  70. std::vector<std::string> programs;
  71. for (int i = 0; i < config_json["process"].size(); i++) {
  72. programs.push_back(config_json["process"][i]["program"].asString());
  73. }
  74. std::vector<std::string> logpaths;
  75. std::vector<std::uintmax_t> maxsizes;
  76. for (int i = 0; i < config_json["logpaths"].size(); i++) {
  77. logpaths.push_back(config_json["logpaths"][i]["path"].asString());
  78. maxsizes.push_back(config_json["logpaths"][i]["size"].asInt64());
  79. }
  80. int timeout_seconds = 10; // 超时时间(秒)
  81. while (true) {
  82. // 检查程序是否存活
  83. for (int i = 0; i < programs.size(); i++) {
  84. std::string cmd = "ps aux | grep '" + programs[i] + "' | grep -v grep";
  85. if (system(cmd.c_str()) != 0) {
  86. // 程序已死亡,重启
  87. LOG(WARNING) << "Program " << programs[i] << " has died, restarting..." << std::endl;
  88. std::stringstream pro(programs[i]);
  89. std::string name;
  90. pro >> name;
  91. system(("pkill -f " + name).c_str());
  92. std::this_thread::sleep_for(std::chrono::seconds(1));
  93. system(("./" + programs[i] + " &").c_str());
  94. }
  95. }
  96. // 清理目录下文件
  97. // 计算目录大小
  98. for (int i = 0; i < logpaths.size(); i++) {
  99. std::uintmax_t size = calculateDirectorySize(logpaths.at(i)) / (1024 * 1024);
  100. LOG(INFO) << logpaths[i] << " size: " << size << "MB" << " max size:" << maxsizes[i] << "MB";
  101. while (size > maxsizes[i]) {
  102. deleteOldestFile(logpaths[i]);
  103. size = calculateDirectorySize(logpaths[i]) / (1024 * 1024);
  104. }
  105. }
  106. // 等待一段时间后再次检测
  107. std::this_thread::sleep_for(std::chrono::seconds(timeout_seconds));
  108. }
  109. return 0;
  110. }