123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125 |
- #include <iostream>
- #include <string>
- #include <cstdlib>
- #include <chrono>
- #include <thread>
- #include <boost/filesystem.hpp>
- #include "json/json.h"
- #include "defines.hpp"
- const char* DEFAULT_WATCH_DOG_CONFIG_PATH = ETC_PATH"WatchDog/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<std::time_t>::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." << oldestFilePath << 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"WatchDog/WatchDogLog/");
- 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<double> 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<std::string> programs;
- for (int i = 0; i < config_json["process"].size(); i++) {
- programs.push_back(config_json["process"][i]["program"].asString());
- }
- std::vector<std::string> logpaths;
- std::vector<std::uintmax_t> 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;
- }
|