}
/// @brief Registers hooks in the hook manager.
+ ///
/// Normally this is done by the server core code.
void registerHooks() {
if (isc::dhcp::CfgMgr::instance().getFamily() == AF_INET) {
hook_index_dhcpx_srv_configured_ = HooksManager::registerHook("dhcp4_srv_configured");
- hook_index_pktx_send_ = HooksManager::registerHook("pkt4_send");
+ hook_index_pktx_send_ = HooksManager::registerHook("pkt4_send");
} else {
hook_index_dhcpx_srv_configured_ = HooksManager::registerHook("dhcp6_srv_configured");
- hook_index_pktx_send_ = HooksManager::registerHook("pkt6_send");
+ hook_index_pktx_send_ = HooksManager::registerHook("pkt6_send");
}
}
<< "." << subnet_id_;
return (oss.str());
-};
+}
std::string
DurationKey::getStatName(const std::string& value_name) const {
std::ostringstream oss;
if (subnet_id_ != SUBNET_ID_GLOBAL) {
- oss << "subnet-id[" << subnet_id_ << "].";
+ oss << "subnet-id[" << subnet_id_ << "].";
}
oss << "perfmon."
<< "." << value_name;
return (oss.str());
-};
+}
bool
DurationKey::operator==(const DurationKey& other) const {
/// @brief Set the subnet id.
///
- /// @param subnet_id new value for subnet id.x
+ /// @param subnet_id new value for subnet id.
void setSubnetId(dhcp::SubnetID subnet_id) {
subnet_id_ = subnet_id;
}
/// @return the composite label.
std::string getLabel() const;
- /// @brief Get the StatsMgr formatted compatible name
+ /// @brief Get the StatsMgr formatted compatible name.
///
- /// @param value_name name of the specific value (e.g. "average-ms", "min-duration-ms")
+ /// @param value_name name of the specific value (e.g. "average-ms", "min-duration-ms").
/// The format of the string:
///
/// @code
///
/// {subnet-id[x]}.perfmon.<query type>-<response type>.<start event>-<end event>.<value-name>
///
- /// Example:
+ /// Examples:
///
/// perfmon.discover-offer.socket_received-buffer_read.average-ms
///
if (ret.second == false) {
isc_throw(DuplicateDurationKey,
"MonitoredDurationStore::addDuration: duration already exists for: "
- << key->getLabel());
+ << mond->getLabel());
}
}
int dhcp4_srv_configured(CalloutHandle& /* handle */) {
// We do this here rather than in load() to ensure we check after the
// packet filter has been determined.
- LOG_DEBUG(perfmon_logger, DBGLVL_TRACE_BASIC,
- PERFMON_DHCP4_SOCKET_RECEIVED_TIME_SUPPORT)
- .arg(IfaceMgr::instance().isSocketReceivedTimeSupported() ? "Yes" : "No");
+ LOG_DEBUG(perfmon_logger, DBGLVL_TRACE_BASIC, PERFMON_DHCP4_SOCKET_RECEIVED_TIME_SUPPORT)
+ .arg(IfaceMgr::instance().isSocketReceivedTimeSupported() ? "Yes" : "No");
return (0);
}
int dhcp6_srv_configured(CalloutHandle& /* handle */) {
// We do this here rather than in load() to ensure we check after the
// packet filter has been determined.
- LOG_DEBUG(perfmon_logger, DBGLVL_TRACE_BASIC,
- PERFMON_DHCP6_SOCKET_RECEIVED_TIME_SUPPORT)
- .arg(IfaceMgr::instance().isSocketReceivedTimeSupported() ? "Yes" : "No");
+ LOG_DEBUG(perfmon_logger, DBGLVL_TRACE_BASIC, PERFMON_DHCP6_SOCKET_RECEIVED_TIME_SUPPORT)
+ .arg(IfaceMgr::instance().isSocketReceivedTimeSupported() ? "Yes" : "No");
return (0);
}
mgr->processPktEventStack(query, response, subnet->getID());
} catch (const std::exception& ex) {
LOG_DEBUG(perfmon_logger, DBGLVL_TRACE_DETAIL, PERFMON_DHCP4_PKT_PROCESS_ERROR)
- .arg(query->getLabel())
- .arg(ex.what());
+ .arg(query->getLabel())
+ .arg(ex.what());
}
return (0);
mgr->processPktEventStack(query, response, subnet->getID());
} catch (const std::exception& ex) {
LOG_DEBUG(perfmon_logger, DBGLVL_TRACE_DETAIL, PERFMON_DHCP6_PKT_PROCESS_ERROR)
- .arg(query->getLabel())
- .arg(ex.what());
+ .arg(query->getLabel())
+ .arg(ex.what());
}
return (0);
/// @todo register commands
/// handle.registerCommandCallout("command-here", handler_here);
} catch (const std::exception& ex) {
- LOG_ERROR(perfmon_logger, PERFMON_INIT_FAILED).arg(ex.what());
+ LOG_ERROR(perfmon_logger, PERFMON_INIT_FAILED)
+ .arg(ex.what());
return (1);
}
This info message indicates that the PerfMon hooks library has been
loaded successfully. Enjoy!
-% PERFMON_ALARM_CLEARED Alarm for %1 has been cleared, reported average duration %2 is now beloe low-water-ms: %3
+% PERFMON_ALARM_CLEARED Alarm for %1 has been cleared, reported average duration %2 is now below low-water-ms: %3
This info message is emitted when the reported average duration for
an alarm that has been triggered has fallen below the value of its
low-water-ms parameter. The arguments detail the alarm's key and
averges remain above the low-water-ms value, the alarm will remain
triggered and this message will be repeated every alarm-report-secs.
Arguments detail the alarm's key, the time the alarm was first
-triggered, the most recent reported average, and the high-watr-ms
+triggered, the most recent reported average, and the high-water-ms
value.
% PERFMON_DHCP4_PKT_PROCESS_ERROR Packet event stack was not processed for query %1, reason %2
-This debug message is emitted when the a query's event stack could not
+This debug message is emitted when the query's event stack could not
be processed. This is most likely a programmatic error and should be
reported. The arguments identify the query and the reason it could
not be processed. These errors should not affect server's normal
operations.
% PERFMON_DHCP6_PKT_PROCESS_ERROR Packet event stack was not processed for query %1, reason %2
-This debug message is emitted when the a query's event stack could not
+This debug message is emitted when the query's event stack could not
be processed. This is most likely a programmatic error and should be
reported. The arguments identify the query and the reason it could
not be processed. These errors should not affect server's normal
LOG_DEBUG(perfmon_logger, DBGLVL_TRACE_DETAIL,
(family_ == AF_INET ? PERFMON_DHCP4_PKT_EVENTS : PERFMON_DHCP6_PKT_EVENTS))
- .arg(query->getLabel())
- .arg(query->dumpPktEvents());
+ .arg(query->getLabel())
+ .arg(query->dumpPktEvents());
// If monitoring is disabled, then punt.
if (!enable_monitoring_) {
} else {
Duration sample = event.timestamp_ - prev_time;
DurationKeyPtr key(new DurationKey(family_, query_type, response_type,
- prev_event_label, event.label_, subnet_id));
+ prev_event_label, event.label_, subnet_id));
addDurationSample(key, sample);
// Update global duration.
// Generate composite total.
Duration sample = prev_time - start_time;
DurationKeyPtr key(new DurationKey(family_, query_type, response_type,
- "composite", "total_response", subnet_id));
+ "composite", "total_response", subnet_id));
addDurationSample(key, sample);
// Update global duration.
if (subnet_id != SUBNET_ID_GLOBAL) {
Duration
PerfMonMgr::reportToStatsMgr(MonitoredDurationPtr duration) {
if (!duration) {
- isc_throw(BadValue, "reportToStatsMgr - duration is empty");
+ isc_throw(BadValue, "reportToStatsMgr - duration is empty!");
}
auto previous_interval = duration->getPreviousInterval();
if (!previous_interval) {
- isc_throw(BadValue, "reportToStatsMgr - duration previous interval is empty");
+ isc_throw(BadValue, "reportToStatsMgr - duration previous interval is empty!");
}
auto average = previous_interval->getAverageDuration();
/// @todo - decide if we want to report min and max values too.
- return(average);
+ return (average);
}
void
void configure(const isc::data::ConstElementPtr& params);
/// @brief Sets convenience values and (re)creates the duration store.
+ ///
/// Called by the constructor and also by configure().
virtual void init();
" -00:00:00.005000, must be greater than zero");
}
-/// @brief Text fixture class for @c MonitoredDurationStore
+/// @brief Text fixture class for @c MonitoredDurationStore.
///
/// In order to facilitate single and multi threaded testing,
/// individual tests are implemented as methods that are called
class MonitoredDurationStoreTest : public ::testing::Test {
public:
- /// @brief Constructor
+ /// @brief Constructor.
MonitoredDurationStoreTest() = default;
- /// @brief Destructor
+ /// @brief Destructor.
virtual ~MonitoredDurationStoreTest() = default;
- /// @brief Creates a protocol-specific DurationKey for a given subnet
+ /// @brief Creates a protocol-specific DurationKey for a given subnet.
///
/// The message-pair and socket-event pairs are fixed.
///
- /// @param family protocol family to test, AF_INET or AF_INET6
- /// @param subnet SubnetID of the duration
+ /// @param family protocol family to test, AF_INET or AF_INET6.
+ /// @param subnet SubnetID of the duration.
DurationKeyPtr makeKey(uint16_t family, SubnetID subnet = 1) {
DurationKeyPtr key;
if (family == AF_INET) {
/// @brief Verifies that durations can be added to the store and fetched
/// by DurationKey.
///
- /// @param family protocol family to test, AF_INET or AF_INET6
+ /// @param family protocol family to test, AF_INET or AF_INET6.
void addDurationTest(uint16_t family) {
Duration interval_duration(milliseconds(10));
MonitoredDurationStore store(family, interval_duration);
/// @brief Verifies that duplicate durations cannot be added to the store.
///
- /// @param family protocol family to test, AF_INET or AF_INET6
+ /// @param family protocol family to test, AF_INET or AF_INET6.
void addDurationDuplicateTest(uint16_t family) {
Duration interval_duration(milliseconds(10));
MonitoredDurationStore store(family, interval_duration);
/// @brief Verify that durations can be deleted from the store.
///
- /// @param family protocol family to test, AF_INET or AF_INET6
+ /// @param family protocol family to test, AF_INET or AF_INET6.
void deleteDurationTest(uint16_t family) {
MonitoredDurationStore store(family, milliseconds(5));
/// @brief Verify that durations in the store can be updated.
///
- /// @param family protocol family to test, AF_INET or AF_INET6
+ /// @param family protocol family to test, AF_INET or AF_INET6.
void updateDurationTest(uint16_t family) {
Duration interval_duration(seconds(60));
MonitoredDurationStore store(family, interval_duration);
/// @brief Exercises addDurationSample() valid behavior.
///
- /// @param family protocol family to test, AF_INET or AF_INET6
+ /// @param family protocol family to test, AF_INET or AF_INET6.
void addDurationSampleTest(uint16_t family) {
// Create a store.
Duration interval_duration(milliseconds(50));
EXPECT_EQ(previous_interval->getTotalDuration(), (five_ms) * 2);
}
- /// @brief Veriries getReportsNext and getOverdueReports
+ /// @brief Veriries getReportsNext and getOverdueReports.
///
- /// @param family protocol family to test, AF_INET or AF_INET6
+ /// @param family protocol family to test, AF_INET or AF_INET6.
void reportDueTest(uint16_t family) {
// Create a store.
Duration interval_duration(milliseconds(100));
/// of adding duration samples. It does not pass or fail and thus is not
/// included in explicit UTs.
///
- /// @param family protocol family to test, AF_INET or AF_INET6
+ /// @param family protocol family to test, AF_INET or AF_INET6.
void speedCheck(uint16_t family) {
// Create a store.
Duration interval_duration(microseconds(100));
/// @brief Verifies that composite key index compares correctly with adjacent events.
///
- /// @param family protocol family to test, AF_INET or AF_INET6
+ /// @param family protocol family to test, AF_INET or AF_INET6.
void adjacentEventTest(uint16_t family) {
Duration interval_duration(milliseconds(10));
MonitoredDurationStore store(family, interval_duration);
};
-TEST_F(MonitoredDurationStoreTest, addDuration) {
+TEST_F(MonitoredDurationStoreTest, addDuration4) {
addDurationTest(AF_INET);
}
-TEST_F(MonitoredDurationStoreTest, addDurationMultiThreading) {
+TEST_F(MonitoredDurationStoreTest, addDuration4MultiThreading) {
MultiThreadingTest mt;
addDurationTest(AF_INET);
}
addDurationTest(AF_INET6);
}
-TEST_F(MonitoredDurationStoreTest, addDurationDuplicate) {
+TEST_F(MonitoredDurationStoreTest, addDuration4Duplicate) {
addDurationDuplicateTest(AF_INET);
}
-TEST_F(MonitoredDurationStoreTest, addDurationDuplicateMultiThreading) {
+TEST_F(MonitoredDurationStoreTest, addDuration4DuplicateMultiThreading) {
MultiThreadingTest mt;
addDurationDuplicateTest(AF_INET);
}
addDurationInvalidTest();
}
-TEST_F(MonitoredDurationStoreTest, deleteDuration) {
+TEST_F(MonitoredDurationStoreTest, deleteDuration4) {
deleteDurationTest(AF_INET);
}
-TEST_F(MonitoredDurationStoreTest, deleteDurationMultiThreading) {
+TEST_F(MonitoredDurationStoreTest, deleteDuration4MultiThreading) {
MultiThreadingTest mt;
deleteDurationTest(AF_INET);
}
deleteDurationInvalidTest();
}
-TEST_F(MonitoredDurationStoreTest, updateDuration) {
+TEST_F(MonitoredDurationStoreTest, updateDuration4) {
updateDurationTest(AF_INET);
}
-TEST_F(MonitoredDurationStoreTest, updateDurationMultiThreading) {
+TEST_F(MonitoredDurationStoreTest, updateDuration4MultiThreading) {
MultiThreadingTest mt;
updateDurationTest(AF_INET);
}
updateDurationInvalidTest();
}
-TEST_F(MonitoredDurationStoreTest, addDurationSample) {
+TEST_F(MonitoredDurationStoreTest, addDurationSample4) {
addDurationSampleTest(AF_INET);
}
-TEST_F(MonitoredDurationStoreTest, addDurationSampleMultiThreading) {
+TEST_F(MonitoredDurationStoreTest, addDurationSample4MultiThreading) {
MultiThreadingTest mt;
addDurationSampleTest(AF_INET);
}
addDurationSampleTest(AF_INET6);
}
-TEST_F(MonitoredDurationStoreTest, reportDue) {
+TEST_F(MonitoredDurationStoreTest, reportDue4) {
reportDueTest(AF_INET);
}
-TEST_F(MonitoredDurationStoreTest, reportDueMultiThreading) {
+TEST_F(MonitoredDurationStoreTest, reportDue4MultiThreading) {
MultiThreadingTest mt;
reportDueTest(AF_INET);
}
reportDueTest(AF_INET6);
}
-TEST_F(MonitoredDurationStoreTest, adjacentEvent) {
+TEST_F(MonitoredDurationStoreTest, adjacentEvent4) {
adjacentEventTest(AF_INET);
}
// No use case for this (yet).
break;
}
-
} else {
// State should have changed.
ASSERT_LT(before->getStosTime(), after->getStosTime());
// No use case for this (yet).
break;
}
-
}
before = after;
/// @brief Check the content of a stored MonitoredDuration.
///
- /// @param line_no source line of the invocation
- /// @param key DurationKey of the target duration
- /// @param exp_current_total_ms expected value of the current interval's total_duration_
- /// @param exp_previous true if the duration should have previous interval, defaults to false
- /// @param exp_previous_total_ms expected value of the previous interval's total_duration_
+ /// @param line_no source line of the invocation.
+ /// @param key DurationKey of the target duration.
+ /// @param exp_current_total_ms expected value of the current interval's total_duration_.
+ /// @param exp_previous true if the duration should have previous interval, defaults to false.
+ /// @param exp_previous_total_ms expected value of the previous interval's total_duration_.
void checkDuration(int line_no, DurationKeyPtr key, uint64_t exp_current_total_ms,
bool exp_previous = false, uint64_t exp_previous_total_ms = 0) {
std::ostringstream oss;
ASSERT_EQ(durations->size(), 0);
}
- /// @brief Exercises PerfMonMgr::reportToStatsMgr().
+ /// @brief Exercises PerfMonMgr::reportToStatsMgr().
void testReportToStatsMgr() {
// Minimal valid configuration.
std::string valid_config =
MonitoredDurationPtr mond;
ASSERT_THROW_MSG(mgr_->reportToStatsMgr(mond), BadValue,
- "reportToStatsMgr - duration is empty");
+ "reportToStatsMgr - duration is empty!");
ASSERT_NO_THROW_LOG(
mond.reset(new MonitoredDuration(family_, 0, 0,
"process-started", "process-completed",
- 70, seconds(60))));
+ 70, seconds(60))));
ASSERT_THROW_MSG(mgr_->reportToStatsMgr(mond), BadValue,
- "reportToStatsMgr - duration previous interval is empty");
+ "reportToStatsMgr - duration previous interval is empty!");
mond->addSample(milliseconds(100));
mond->addSample(milliseconds(250));
ASSERT_TRUE(before_alarm);
EXPECT_EQ(Alarm::CLEAR, before_alarm->getState());
- // 1. Add two samples to the duratson inside the current interval
+ // 1. Add two samples to the duratson inside the current interval.
// This should create the duration in the store. Note both samples above
// high-water-ms.
ASSERT_NO_THROW_LOG(mgr_->addDurationSample(key, milliseconds(75)));
// Duration should have a current total of 95 ms, and a previous total of 160.
checkDuration(__LINE__, key, 95, true, 160);
- // Should have one stat reported with a average value of 80.
+ // Should have one stat reported with a average value of 80.
EXPECT_EQ(1, StatsMgr::instance().count());
auto obs = StatsMgr::instance().getObservation(key->getStatName("average-ms"));
ASSERT_TRUE(obs);
beforeAndAfterAlarm(__LINE__, before_alarm, Alarm::TRIGGERED, true);
addString("reported average duration 00:00:00.100000 exceeds high-water-ms: 50");
- // Should have one stat reported with a value of 100.
+ // Should have one stat reported with a value of 100.
EXPECT_EQ(1, StatsMgr::instance().count());
obs = StatsMgr::instance().getObservation(key->getStatName("average-ms"));
ASSERT_TRUE(obs);
// The Alarm should now be CLEAR since the newly completed interval is
// below high water. The alarm should low-water report.
beforeAndAfterAlarm(__LINE__, before_alarm, Alarm::CLEAR, false);
- addString("reported average duration 00:00:00.010000 is now beloe low-water-ms: 25");
+ addString("reported average duration 00:00:00.010000 is now below low-water-ms: 25");
- // Should have one stat reported with a value of 10.
+ // Should have one stat reported with a value of 10.
EXPECT_EQ(1, StatsMgr::instance().count());
obs = StatsMgr::instance().getObservation(key->getStatName("average-ms"));
ASSERT_TRUE(obs);