Example #1
0
void BcmPort::updateStats() {
  // TODO: It would be nicer to use a monotonic clock, but unfortunately
  // the ServiceData code currently expects everyone to use system time.
  auto now = duration_cast<seconds>(system_clock::now().time_since_epoch());

  updateStat(now, &inBytes_, opennsl_spl_snmpIfHCInOctets);
  updateStat(now, &inUnicastPkts_, opennsl_spl_snmpIfHCInUcastPkts);
  updateStat(now, &inMulticastPkts_, opennsl_spl_snmpIfHCInMulticastPkts);
  updateStat(now, &inBroadcastPkts_, opennsl_spl_snmpIfHCInBroadcastPkts);
  updateStat(now, &inDiscards_, opennsl_spl_snmpIfInDiscards);
  updateStat(now, &inErrors_, opennsl_spl_snmpIfInErrors);

  updateStat(now, &outBytes_, opennsl_spl_snmpIfHCOutOctets);
  updateStat(now, &outUnicastPkts_, opennsl_spl_snmpIfHCOutUcastPkts);
  updateStat(now, &outMulticastPkts_, opennsl_spl_snmpIfHCOutMulticastPkts);
  updateStat(now, &outBroadcastPkts_, opennsl_spl_snmpIfHCOutBroadcastPckts);
  updateStat(now, &outDiscards_, opennsl_spl_snmpIfOutDiscards);
  updateStat(now, &outErrors_, opennsl_spl_snmpIfOutErrors);

  setAdditionalStats(now);

  // Update the queue length stat
  uint32_t qlength;
  auto ret = opennsl_port_queued_count_get(unit_, port_, &qlength);
  if (OPENNSL_FAILURE(ret)) {
    LOG(ERROR) << "Failed to get queue length for port " << port_
               << " :" << opennsl_errmsg(ret);
  } else {
    SpinLockHolder guard(outQueueLen_.first.get());
    outQueueLen_.second->addValue(now, qlength);
    // TODO: outQueueLen_ only exports the average queue length over the last
    // 60 seconds, 10 minutes, etc.
    // We should also export the current value.  We could use a simple counter
    // or a dynamic counter for this.
  }

  // Update the packet length histograms
  updatePktLenHist(now, &inPktLengths_, kInPktLengthStats);
  updatePktLenHist(now, &outPktLengths_, kOutPktLengthStats);
};
Example #2
0
void BcmPort::updateStats() {
  // TODO: It would be nicer to use a monotonic clock, but unfortunately
  // the ServiceData code currently expects everyone to use system time.
  if (!shouldReportStats()) {
    return;
  }
  auto now = duration_cast<seconds>(system_clock::now().time_since_epoch());
  HwPortStats curPortStats;
  updateStat(
      now, kInBytes, opennsl_spl_snmpIfHCInOctets, &curPortStats.inBytes_);
  updateStat(
      now,
      kInUnicastPkts,
      opennsl_spl_snmpIfHCInUcastPkts,
      &curPortStats.inUnicastPkts_);
  updateStat(
      now,
      kInMulticastPkts,
      opennsl_spl_snmpIfHCInMulticastPkts,
      &curPortStats.inMulticastPkts_);
  updateStat(
      now,
      kInBroadcastPkts,
      opennsl_spl_snmpIfHCInBroadcastPkts,
      &curPortStats.inBroadcastPkts_);
  updateStat(
      now,
      kInDiscards,
      opennsl_spl_snmpIfInDiscards,
      &curPortStats.inDiscards_);
  updateStat(
      now, kInErrors, opennsl_spl_snmpIfInErrors, &curPortStats.inErrors_);
  updateStat(
      now,
      kInIpv4HdrErrors,
      opennsl_spl_snmpIpInHdrErrors,
      &curPortStats.inIpv4HdrErrors_);
  updateStat(
      now,
      kInIpv6HdrErrors,
      opennsl_spl_snmpIpv6IfStatsInHdrErrors,
      &curPortStats.inIpv6HdrErrors_);
  updateStat(
      now,
      kInPause,
      opennsl_spl_snmpDot3InPauseFrames,
      &curPortStats.inPause_);
  // Egress Stats
  updateStat(
      now, kOutBytes, opennsl_spl_snmpIfHCOutOctets, &curPortStats.outBytes_);
  updateStat(
      now,
      kOutUnicastPkts,
      opennsl_spl_snmpIfHCOutUcastPkts,
      &curPortStats.outUnicastPkts_);
  updateStat(
      now,
      kOutMulticastPkts,
      opennsl_spl_snmpIfHCOutMulticastPkts,
      &curPortStats.outMulticastPkts_);
  updateStat(
      now,
      kOutBroadcastPkts,
      opennsl_spl_snmpIfHCOutBroadcastPckts,
      &curPortStats.outBroadcastPkts_);
  updateStat(
      now,
      kOutDiscards,
      opennsl_spl_snmpIfOutDiscards,
      &curPortStats.outDiscards_);
  updateStat(
      now, kOutErrors, opennsl_spl_snmpIfOutErrors, &curPortStats.outErrors_);
  updateStat(
      now,
      kOutPause,
      opennsl_spl_snmpDot3OutPauseFrames,
      &curPortStats.outPause_);

  setAdditionalStats(now, &curPortStats);
  // Compute non pause discards
  const auto kUninit = hardware_stats_constants::STAT_UNINITIALIZED();
  if (isMmuLossy() && portStats_.inDiscards_ != kUninit &&
      portStats_.inPause_ != kUninit) {
    // If MMU setup as lossy, all incoming pause frames will be
    // discarded and will count towards in discards. This makes in discards
    // counter somewhat useless. So instead calculate "in_non_pause_discards",
    // as std::max(0, (inDiscardsSincePrev - inPauseSincePrev)).
    // std::max(..) is used, since stats from  h/w are synced non atomically,
    // So depending on what get synced later # of pause maybe be slightly
    // higher than # of discards.
    auto inPauseSincePrev = curPortStats.inPause_ - portStats_.inPause_;
    auto inDiscardsSincePrev =
        curPortStats.inDiscards_ - portStats_.inDiscards_;
    if (inPauseSincePrev >= 0 && inDiscardsSincePrev >=0) {
      // Account for counter rollover.
      auto inNonPauseDiscardsSincePrev =
          std::max(0L, (inDiscardsSincePrev - inPauseSincePrev));
      // Init current port stats from prev value or 0
      curPortStats.inNonPauseDiscards_ =
          (portStats_.inNonPauseDiscards_ == kUninit
               ? 0
               : portStats_.inNonPauseDiscards_);
      // Counters are cumalative
      curPortStats.inNonPauseDiscards_ += inNonPauseDiscardsSincePrev;
      auto inNonPauseDiscards = getPortCounterIf(kInNonPauseDiscards);
      inNonPauseDiscards->updateValue(now, curPortStats.inNonPauseDiscards_);
    }
  }
  portStats_ = curPortStats;

  // Update the queue length stat
  uint32_t qlength;
  auto ret = opennsl_port_queued_count_get(unit_, port_, &qlength);
  if (OPENNSL_FAILURE(ret)) {
    LOG(ERROR) << "Failed to get queue length for port " << port_
               << " :" << opennsl_errmsg(ret);
  } else {
    outQueueLen_.addValue(now.count(), qlength);
    // TODO: outQueueLen_ only exports the average queue length over the last
    // 60 seconds, 10 minutes, etc.
    // We should also export the current value.  We could use a simple counter
    // or a dynamic counter for this.
  }

  // Update the packet length histograms
  updatePktLenHist(now, &inPktLengths_, kInPktLengthStats);
  updatePktLenHist(now, &outPktLengths_, kOutPktLengthStats);
};