#include #include #include #include #include #include #include "json/json.h" #include "defines.hpp" const char* DEFAULT_WATCH_DOG_CONFIG_PATH = ETC_PATH"/etc/watch_dog.json"; // 递归计算目录大小 std::uintmax_t calculateDirectorySize(const boost::filesystem::path& path) { if (!boost::filesystem::exists(path)) { LOG(ERROR) << path << "not exist!!!!!"; return 0; } std::uintmax_t size = 0; for (const auto& entry : boost::filesystem::recursive_directory_iterator(path)) { if (boost::filesystem::is_regular_file(entry)) { size += boost::filesystem::file_size(entry); } } return size; } // 删除最后修改时间最早的文件 void deleteOldestFile(const boost::filesystem::path& directoryPath) { boost::filesystem::path oldestFilePath; std::time_t oldestTime = std::numeric_limits::max(); for (const auto& entry : boost::filesystem::directory_iterator(directoryPath)) { if (boost::filesystem::is_regular_file(entry)) { const std::time_t lastModifiedTime = boost::filesystem::last_write_time(entry); if (lastModifiedTime < oldestTime) { oldestTime = lastModifiedTime; oldestFilePath = entry.path(); } } } if (!oldestFilePath.empty()) { try { boost::filesystem::remove(oldestFilePath); LOG(INFO) << "Deleted file: " << oldestFilePath << std::endl; } catch (const std::exception& e) { LOG(ERROR) << "Failed to delete file: " << oldestFilePath << ", Error: " << e.what() << std::endl; } } else { LOG(WARNING) << "No files found in the directory." << std::endl; } } int main(int argc, char** argv) { std::string config_path; if (argc > 1) { config_path = argv[1]; } else { config_path = DEFAULT_WATCH_DOG_CONFIG_PATH; } ZX::InitGlog("WatchDog", ETC_PATH"/etc/WatchDog/"); LOG(INFO) << "load etc file from: " << DEFAULT_WATCH_DOG_CONFIG_PATH; Json::Value config_json; if (false == ReadJsonFile(config_path, config_json) || !config_json.isMember("process") || !config_json["process"].isArray()) { auto time = std::chrono::steady_clock::now(); std::chrono::duration diff = std::chrono::steady_clock::now() - time; while (diff.count() < 10) { LOG(ERROR) << "watch Program is empty!!! after " << 10 - diff.count() << "s, system will restart." << std::endl; std::this_thread::sleep_for(std::chrono::seconds(1)); diff = std::chrono::steady_clock::now() - time; } system("systemctl reboot"); exit(-1); } std::vector programs; for (int i = 0; i < config_json["process"].size(); i++) { programs.push_back(config_json["process"][i]["program"].asString()); } std::vector logpaths; std::vector maxsizes; for (int i = 0; i < config_json["logpaths"].size(); i++) { logpaths.push_back(config_json["logpaths"][i]["path"].asString()); maxsizes.push_back(config_json["logpaths"][i]["size"].asInt64()); } int timeout_seconds = 10; // 超时时间(秒) while (true) { // 检查程序是否存活 for (int i = 0; i < programs.size(); i++) { std::string cmd = "ps aux | grep '" + programs[i] + "' | grep -v grep"; if (system(cmd.c_str()) != 0) { // 程序已死亡,重启 LOG(WARNING) << "Program " << programs[i] << " has died, restarting..." << std::endl; std::stringstream pro(programs[i]); std::string name; pro >> name; system(("pkill -f " + name).c_str()); std::this_thread::sleep_for(std::chrono::seconds(1)); system(("./" + programs[i] + " &").c_str()); } } // 清理目录下文件 // 计算目录大小 for (int i = 0; i < logpaths.size(); i++) { std::uintmax_t size = calculateDirectorySize(logpaths.at(i)) / (1024 * 1024); LOG(INFO) << logpaths[i] << " size: " << size << "MB" << " max size:" << maxsizes[i] << "MB"; while (size > maxsizes[i]) { deleteOldestFile(logpaths[i]); size = calculateDirectorySize(logpaths[i]) / (1024 * 1024); } } // 等待一段时间后再次检测 std::this_thread::sleep_for(std::chrono::seconds(timeout_seconds)); } return 0; }