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

 

9d19bbdcc540b0d301bcadeed734fc5b.png

目录

 

代码

分析

主要结构

判断逻辑

备注


 

代码

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 获取时间延迟的方法就是通过订阅接收到数据的然后做上一帧时间的差值

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ym影子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值