Apollo 应用与源码分析:Monitor监控-软件监控-channel时间延迟监控

news2025/1/14 18:36:20

目录

代码

分析

主要结构

判断逻辑

备注


代码

class ChannelMonitor : public RecurrentRunner {
 public:
  explicit ChannelMonitor(
      const std::shared_ptr<LatencyMonitor>& latency_monitor);
  void RunOnce(const double current_time) override;

 private:
  static void UpdateStatus(
      const apollo::dreamview::ChannelMonitorConfig& config,
      ComponentStatus* status, const bool update_freq, const double freq);
  std::shared_ptr<LatencyMonitor> latency_monitor_;
};

void ChannelMonitor::RunOnce(const double current_time) {
  auto manager = MonitorManager::Instance();
  const auto& mode = manager->GetHMIMode();
  auto* components = manager->GetStatus()->mutable_components();
  for (const auto& iter : mode.monitored_components()) {
    const std::string& name = iter.first;
    const auto& config = iter.second;
    if (config.has_channel()) {
      double freq;
      const auto update_freq =
          latency_monitor_->GetFrequency(config.channel().name(), &freq);
      UpdateStatus(config.channel(),
                   components->at(name).mutable_channel_status(), update_freq,
                   freq);
    }
  }
}

分析

主要结构

runOnce 中不变的套路:

  1. 先从HMI mode 中获取所有配置的监控项目;
  2. 遍历监控项目,使用latency_monitor_->GetFrequency 获取channel的频率;
  3. 使用UpdateStatus 更新状态,生成报警

判断逻辑

void ChannelMonitor::UpdateStatus(
    const apollo::dreamview::ChannelMonitorConfig& config,
    ComponentStatus* status, const bool update_freq, const double freq) {
  status->clear_status();

  const auto reader_message_pair = GetReaderAndLatestMessage(config.name());
  const auto reader = reader_message_pair.first;
  const auto message = reader_message_pair.second;

  if (reader == nullptr) {
    SummaryMonitor::EscalateStatus(
        ComponentStatus::UNKNOWN,
        absl::StrCat(config.name(), " is not registered in ChannelMonitor."),
        status);
    return;
  }

  if (message == nullptr || message->ByteSize() == 0) {
    SummaryMonitor::EscalateStatus(
        ComponentStatus::FATAL,
        absl::StrCat("the message ", config.name(), " reseived is empty."),
        status);
    return;
  }

  // Check channel delay
  const double delay = reader->GetDelaySec();
  if (delay < 0 || delay > config.delay_fatal()) {
    SummaryMonitor::EscalateStatus(
        ComponentStatus::FATAL,
        absl::StrCat(config.name(), " delayed for ", delay, " seconds."),
        status);
  }

  // Check channel fields
  const std::string field_sepr = ".";
  if (message != nullptr) {
    for (const auto& field : config.mandatory_fields()) {
      if (!ValidateFields(*message, absl::StrSplit(field, field_sepr), 0)) {
        SummaryMonitor::EscalateStatus(
            ComponentStatus::ERROR,
            absl::StrCat(config.name(), " missing field ", field), status);
      }
    }
  }

  // Check channel frequency
  if (update_freq) {
    if (freq > config.max_frequency_allowed()) {
      SummaryMonitor::EscalateStatus(
          ComponentStatus::WARN,
          absl::StrCat(config.name(), " has frequency ", freq,
                       " > max allowed ", config.max_frequency_allowed()),
          status);
    }
    if (freq < config.min_frequency_allowed()) {
      SummaryMonitor::EscalateStatus(
          ComponentStatus::WARN,
          absl::StrCat(config.name(), " has frequency ", freq,
                       " < min allowed ", config.max_frequency_allowed()),
          status);
    }
  }

  SummaryMonitor::EscalateStatus(ComponentStatus::OK, "", status);
}
  1. 通过channel 创建reader,获取最后一条msg;
  2. 如果reader 创建失败就把状态设置为unknow;
  3. 如果最后一帧消息是空,就把状态设置为FATAL;
  4. double delay = reader->GetDelaySec(); 获取延迟;如果延迟<0或者大于阈值就FATAL报警;
  5. 检查必要字段是否缺失,如果缺失就ERROR;
  6. 检查发送频率是否正常,如果不在阈值区间就报WARN;

备注

template <typename MessageT>
double Reader<MessageT>::GetDelaySec() const {
  if (latest_recv_time_sec_ < 0) {
    return -1.0;
  }
  if (second_to_lastest_recv_time_sec_ < 0) {
    return Time::Now().ToSecond() - latest_recv_time_sec_;
  }
  return std::max((Time::Now().ToSecond() - latest_recv_time_sec_),
                  (latest_recv_time_sec_ - second_to_lastest_recv_time_sec_));
}

Reader 获取时间延迟的方法就是通过订阅接收到数据的然后做上一帧时间的差值

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/45151.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

有限元求解:结构应力法如何实现的网格不敏感呢?

作者&#xff1a;云兵老师&#xff0c;仿真秀专栏作者 一、导读 本人从大一时&#xff0c;上第一节力学课就开始接触有限元&#xff0c;那个时候老师曾说&#xff1a;“学会我讲的这门有限元&#xff0c;我可以保证你在毕业时候一定找到工作”。那个时候有限元很火&#xff0…

基于ANSYS Polyflow的逆向挤出模头设计攻略

摘要&#xff1a;内侧灯罩属于复杂截面塑料异型材&#xff0c;目前其挤出模头的设计主要依赖于经验&#xff0c;需要反复试模和修模&#xff0c;使得模具质量难以保证&#xff0c;生产周期长&#xff0c;成本高。 本文采用数值模拟方法对内侧灯罩进行了反向挤出模头设计。首先…

若依框架前后端打包到linux部署,踩坑

前后端分离版下载地址 https://gitee.com/y_project/RuoYi-Vue 打开前端项目 打开readme 初始化依赖 npm install --registryhttps://registry.npmmirror.com启动项目 npm run dev路由模式修改为hash 否则打包后请求路径会和后端冲突 src/router/index.jsexport default ne…

省 市 县 三级联动

大纲 一、导入省市县数据表(t_region) 二、引入jar包 三、导入所需util类&#xff08;整体框架&#xff09; 四、编写代码 1、配置数据库相关信息(数据库名、用户名、密码) config.propreties #oracle9i #driveroracle.jdbc.driver.OracleDriver #urljdbc:oracle:thin:loca…

Linux下redis安装教程

redis安装教程 首先需要安装gcc依赖 yum install -y gcc tcl注&#xff1a;这里如果安装失败可以百度解决 进入/usr/local/src目录&#xff0c;将下载的安装包放在该目录 cd /usr/local/src解压该目录 tar -zxvf redis-6.2.6.tar.gz解压后src下面多了一个redis-6.2.6 进入…

Redis 为什么这么快,你知道 I/O 多路复用吗?

今天我们讨论一下面试高频题&#xff0c;为什么 Redis 那么快&#xff1f; 首先&#xff0c;你可以先想一下答案&#xff0c;我先说下大家普遍的答案&#xff1a; 单线程基于内存操作&#xff0c;速度快I/O 多路复用 相信很多人第一时间回答出来上面这些&#xff0c;那么面试官…

从开发角度读懂公司卫生间一直有人窜稀的原理

不知道你有没有这样的经历&#xff0c;一直忙忙碌碌&#xff0c;需求不断&#xff0c;当你终于解决完手头的事情&#xff0c;突然特别着急想要去卫生间的时候&#xff0c;仅有的几个门总是关着的&#xff0c;于是怀疑&#xff0c;可能其他人更需要这次机会&#xff0c;他们也一…

最基础的协同过滤介绍

文章目录1.到底什么是协同过滤2.协同过滤的一般步骤3.基于用户的CF (User-CF)3.1 基本介绍3.2 用户相似度3.2.1 用户相似度基本介绍3.2.2 用户相似度改进&#xff1a;ICU3.3 User-CF的缺点4.基于项目的CF (Item-CF)4.1 基本介绍4.2 用户相似度4.2.1 用户相似度基本介绍4.2.2 用…

xss-labs/level6

我们输入平常的payload如下 <script>alert(xss)</script> 界面回显如下 源代码如下所示 可以发现后台服务器对特殊字符进行插入操作 我们寄希望于后台不要插入下划线到onxxx关键字中 所以构造如下 " onclickjavascript:alert(xss)>// 由于界面没有回…

教程七 在Go中使用Energy创建跨平台GUI - Cookies

教程-示例-文档 介绍 本文介绍在energy中的cookie操作 在energy中可以对cookie的增加、修改和删除以达到某种目的 对cookie操作时&#xff0c;是以调用功能函数后触发事件的方式返回调用功能函数的结果 运行此示例&#xff0c;需要安装好Go和Energy开发环境&#xff1a;教…

有问题直接说问题,问什么在不在???

有什么问题可以直接说&#xff0c; 比如把你的项目地址、需求、错误复现步骤通过任何方式告诉我 比如&#xff1a; CSDN&#xff1a;发送消息&#xff0c;博客评论等&#xff0c;禁止发"在吗" 发邮件&#xff1a;xuxiaoweixuxiaowei.com.cn。 微信群&#xff1a; 禁…

麦芽糖-紫杉醇maltose-Paclitaxel

麦芽糖-紫杉醇maltose-Paclitaxel 中文名称&#xff1a;麦芽糖-紫杉醇 英文名称&#xff1a;maltose-Paclitaxel 别称&#xff1a;紫杉醇修饰麦芽糖&#xff0c;PTX-麦芽糖 还可以提供PEG接枝修饰麦芽糖&#xff0c;麦芽糖-聚乙二醇-紫杉醇,Paclitaxel-PEG-maltose,紫杉…

redis配置文件详解

一、概述 redis的配置文件中&#xff0c;有着许多说明和可配置项&#xff0c;了解它们能够更好的使用redis去解决开发中遇到的困难。 此配置文件基于linux下的redis-6.2.4版本。 二、单位换算描述-units 在配置文件开头就有这么一段&#xff1a; 这里描述了一些基本的度量…

信息流广告投放的技巧

随着互联网的发展&#xff0c;信息时代已经到来&#xff0c;信息流广告逐渐受到众多广告主的青睐。 做广告&#xff0c;不仅需要投入大量的精力&#xff0c;还需要一定的资金&#xff0c;花这么多&#xff0c;自然是要收获不错的收益。广告主在广告信息流的时候都追求高ROI&am…

蓝牙耳机什么牌子好?安卓蓝牙耳机性价比推荐

戴耳机所听到的音效是完全不同的&#xff0c;体验感也是完全不一样&#xff01;而有线的耳机戴起来一点也不方便&#xff0c;因此更多的人选择无线蓝牙耳机&#xff0c;但是很多新手发帖不知道蓝牙耳机啥牌子好&#xff1f;安卓手机的配置越来越好&#xff0c;深受大众的欢迎&a…

Python中的dump() 、load()和dumps()、loads()使用及示例

Python中的dump() 、load()和dumps()、loads() 结论&#xff1a; 1.不加s的标识对json文件的读写&#xff0c;将内存中值读取写入到json后缀文件&#xff0c;或者将json后缀文件中内容读取到内存 2.加了s的主要是字符串类型和其他数据类型的互转 JSON(JavaScript Object No…

KubeSphere 社区双周报 | KubeKey v3.0.2 发布 | 2022-11-24

KubeSphere 从诞生的第一天起便秉持着开源、开放的理念&#xff0c;并且以社区的方式成长&#xff0c;如今 KubeSphere 已经成为全球最受欢迎的开源容器平台之一。这些都离不开社区小伙伴的共同努力&#xff0c;你们为 KubeSphere 提出了很多建设性意见&#xff0c;也贡献了很多…

扫除知识共享障碍,天翎知识文档管理系统+群晖NAS一体化解决方案

编者按&#xff1a;知识共享是企业知识管理的重要模块&#xff0c;本文阐述了企业知识共享中常遇到的障碍&#xff0c;并指出知识文档管理系统可以帮助解决这些问题&#xff0c;而NAS与知识文档系统的结合更是锦上添花。 关键词&#xff1a;文档分类&#xff0c;版本管理&…

你想要知道的“全电发票接口”

老规矩&#xff0c;即使你看到此文前&#xff0c;你多少知道点“全电发票”的一些知识&#xff0c;这里方便那些还没得空抢先获取的知友小伙伴们梳理下相关知识点。 ** 一、全电发票具体的定义 ** 全电发票是国家税务总局随着金税四期推出的全国统一的电子发票服务平台&…

护眼台灯该怎么样选择?2022如何选择一款好的护眼台灯

随着社会的高度发展&#xff0c;人们的生活水平也渐渐得到提高&#xff0c;大家也慢慢开始在意平时生活中的健康问题了&#xff0c;比如眼睛健康就是一个很重要的点。现在的年轻人&#xff0c;尤其是青少年儿童&#xff0c;走在大街上普遍都能看见带着眼睛&#xff0c;近视情况…