• Apollo 应用与源码分析:Monitor监控-软件监控-进程存活监控-process_monitor


    目录

    流程

    代码

    分析

    获取可以运行的进程的信息

    检查HMI 的模块信息

    检查被监控的组件

    检查其他组件

    判断进程状态UpdateStatus


    流程

    代码

    1. class ProcessMonitor : public RecurrentRunner {
    2. public:
    3. ProcessMonitor();
    4. void RunOnce(const double current_time) override;
    5. private:
    6. static void UpdateStatus(
    7. const std::vector& running_processes,
    8. const apollo::dreamview::ProcessMonitorConfig& config,
    9. ComponentStatus* status);
    10. };
    11. void ProcessMonitor::RunOnce(const double current_time) {
    12. // Get running processes.
    13. std::vector running_processes;
    14. for (const auto& cmd_file : cyber::common::Glob("/proc/*/cmdline")) {
    15. // Get process command string.
    16. std::string cmd_string;
    17. if (cyber::common::GetContent(cmd_file, &cmd_string) &&
    18. !cmd_string.empty()) {
    19. // In /proc//cmdline, the parts are separated with \0, which will be
    20. // converted back to whitespaces here.
    21. std::replace(cmd_string.begin(), cmd_string.end(), '\0', ' ');
    22. running_processes.push_back(cmd_string);
    23. }
    24. }
    25. auto manager = MonitorManager::Instance();
    26. const auto& mode = manager->GetHMIMode();
    27. // Check HMI modules.
    28. auto* hmi_modules = manager->GetStatus()->mutable_hmi_modules();
    29. for (const auto& iter : mode.modules()) {
    30. const std::string& module_name = iter.first;
    31. const auto& config = iter.second.process_monitor_config();
    32. UpdateStatus(running_processes, config, &hmi_modules->at(module_name));
    33. }
    34. // Check monitored components.
    35. auto* components = manager->GetStatus()->mutable_components();
    36. for (const auto& iter : mode.monitored_components()) {
    37. const std::string& name = iter.first;
    38. if (iter.second.has_process() &&
    39. apollo::common::util::ContainsKey(*components, name)) {
    40. const auto& config = iter.second.process();
    41. auto* status = components->at(name).mutable_process_status();
    42. UpdateStatus(running_processes, config, status);
    43. }
    44. }
    45. // Check other components.
    46. auto* other_components = manager->GetStatus()->mutable_other_components();
    47. for (const auto& iter : mode.other_components()) {
    48. const std::string& name = iter.first;
    49. const auto& config = iter.second;
    50. UpdateStatus(running_processes, config, &other_components->at(name));
    51. }
    52. }

    分析

    核心的处理逻辑还在runOnce 中

    获取可以运行的进程的信息

    1. // Get running processes.
    2. std::vector running_processes;
    3. for (const auto& cmd_file : cyber::common::Glob("/proc/*/cmdline")) {
    4. // Get process command string.
    5. std::string cmd_string;
    6. if (cyber::common::GetContent(cmd_file, &cmd_string) &&
    7. !cmd_string.empty()) {
    8. // In /proc//cmdline, the parts are separated with \0, which will be
    9. // converted back to whitespaces here.
    10. std::replace(cmd_string.begin(), cmd_string.end(), '\0', ' ');
    11. running_processes.push_back(cmd_string);
    12. }
    13. }

    首先迭代遍历所有的/proc/*/cmdline 文件,这个文件是描述进程相关信息的,中间的*就是pid关于该文件的具体内容可以参考:https://blog.csdn.net/whatday/article/details/108897457

    上述文件中可以获取该进程的命令行参数,包括进程的启动路径(argv[0])

    检查HMI 的模块信息

    1. // Check HMI modules.
    2. auto* hmi_modules = manager->GetStatus()->mutable_hmi_modules();
    3. for (const auto& iter : mode.modules()) {
    4. const std::string& module_name = iter.first;
    5. const auto& config = iter.second.process_monitor_config();
    6. UpdateStatus(running_processes, config, &hmi_modules->at(module_name));
    7. }
    1. 获取所有的HMI配置的module;
    2. 将系统中检查到的运行的进程与配置的运行的module 进行检查对比,把最终的检查状态给到&hmi_modules->at(module_name)

    检查被监控的组件

    1. // Check monitored components.
    2. auto* components = manager->GetStatus()->mutable_components();
    3. for (const auto& iter : mode.monitored_components()) {
    4. const std::string& name = iter.first;
    5. if (iter.second.has_process() &&
    6. apollo::common::util::ContainsKey(*components, name)) {
    7. const auto& config = iter.second.process();
    8. auto* status = components->at(name).mutable_process_status();
    9. UpdateStatus(running_processes, config, status);
    10. }
    11. }
    1. 首先获取所有的组件;
    2. 遍历要监控的组件,获取到进程的config 信息;
    3. 给到UpdateStatus进行最终的判断;

    检查其他组件

    1. auto* other_components = manager->GetStatus()->mutable_other_components();
    2. for (const auto& iter : mode.other_components()) {
    3. const std::string& name = iter.first;
    4. const auto& config = iter.second;
    5. UpdateStatus(running_processes, config, &other_components->at(name));
    6. }
    7. }

    逻辑同上

    判断进程状态UpdateStatus

    1. void ProcessMonitor::UpdateStatus(
    2. const std::vector& running_processes,
    3. const apollo::dreamview::ProcessMonitorConfig& config,
    4. ComponentStatus* status) {
    5. status->clear_status();
    6. for (const std::string& command : running_processes) {
    7. bool all_keywords_matched = true;
    8. for (const std::string& keyword : config.command_keywords()) {
    9. if (command.find(keyword) == std::string::npos) {
    10. all_keywords_matched = false;
    11. break;
    12. }
    13. }
    14. if (all_keywords_matched) {
    15. // Process command keywords are all matched. The process is running.
    16. SummaryMonitor::EscalateStatus(ComponentStatus::OK, command, status);
    17. return;
    18. }
    19. }
    20. SummaryMonitor::EscalateStatus(ComponentStatus::FATAL, "", status);
    21. }

    这就是整个进程监控的核心判断函数了。

    1. 遍历之前从/proc/*/cmdline中获取到的running_processes;
    2. 从config 中遍历command_keywords,并看running_processes中是否能找到一个程序名(启动位置),命名行参数都能匹配上的item
    3. 如果找到就是true,如果找不到就是false
  • 相关阅读:
    2021年Java进阶面试题总结
    Android修行手册 - 官方SearchView搭配Toolbar/样式/其他/开源项目
    【java】[maven]每次创建一个maven模块时java compiler版本就是1.6与实际版本不一致(解决本质问题)
    springboot actuator jvm监控丢失
    【c语言编程题一】促销计算、反序数、进制转换、排版类问题、杨辉三角形、日期类问题
    win10修改截图快捷键
    Unity坐标系入门
    C/C++ C语言 C++语言 当一个文件会和很多个编译单元一起编译时,而这个文件又引用了某些编译单元内独有的函数、全局变量,怎么办?
    DC-DC升压变换器 直流隔离低压升高压输出60V/100V/200V/250V/300V/400V/500V/800V
    智慧商业:探索分布式云技术为企业创造商业价值,减少成本,提升生产力的秘诀!
  • 原文地址:https://blog.csdn.net/qq_32378713/article/details/128094813