Kea 2.5.9
perfmon_mgr.cc
Go to the documentation of this file.
1// Copyright (C) 2024 Internet Systems Consortium, Inc. ("ISC")
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7// Functions accessed by the hooks framework use C linkage to avoid the name
8// mangling that accompanies use of the C++ compiler as well as to avoid
9// issues related to namespaces.
10#include <config.h>
11
12#include <perfmon_log.h>
13#include <perfmon_mgr.h>
14#include <stats/stats_mgr.h>
15#include <dhcp/dhcp6.h>
17
18namespace isc {
19namespace perfmon {
20
21using namespace isc::data;
22using namespace isc::dhcp;
23using namespace isc::log;
24using namespace isc::stats;
25using namespace isc::util;
26using namespace boost::posix_time;
27
28PerfMonMgr::PerfMonMgr(uint16_t family_)
29 : PerfMonConfig(family_) {
30 init();
31}
32
33void
35 // Set convenience values.
38
39 // Re-create the duration store.
41}
42
43void
45 if (!params) {
46 // User wants passive logging only.
48 return;
49 }
50
51 if (params->getType() != Element::map) {
52 isc_throw(dhcp::DhcpConfigError, "params must be an Element::map");
53 return;
54 }
55
56 // Parse 'parameters' map.
57 try {
58 parse(params);
59 } catch (std::exception& ex) {
61 "PerfMonMgr::configure failed - " << ex.what());
62 }
63
64 init();
65}
66
67void
69 if (!query) {
70 isc_throw(Unexpected, "PerfMonMgr::processPktEventStack - query is empty!");
71 }
72 uint16_t query_type = query->getType();
73
74 // Response is optional to allow for future support of responseless queries
75 // such as declines or releases.
76 uint16_t response_type;
77 if (!response) {
78 response_type = (family_ == AF_INET ? static_cast<uint16_t>(DHCP_NOTYPE)
79 : static_cast<uint16_t>(DHCPV6_NOTYPE));
80 } else {
81 response_type = response->getType();
82 }
83
84 // Sanity check the message types.
85 DurationKey::validateMessagePair(family_, query_type, response_type);
86
87 auto events = query->getPktEvents();
88 if (events.size() < 2) {
89 isc_throw(Unexpected, "PerfMonMgr::processPtkEventStack - incomplete stack, size: "
90 << events.size());
91 }
92
93 // If we're here without a selected subnet, use global subnet id.
94 SubnetID subnet_id = (subnet ? subnet->getID() : SUBNET_ID_GLOBAL);
95
98 .arg(query->getLabel())
99 .arg(query->dumpPktEvents());
100
101 // If monitoring is disabled, then punt.
102 if (!enable_monitoring_) {
103 return;
104 }
105
106 boost::posix_time::ptime start_time;
107 boost::posix_time::ptime prev_time;
108 std::string prev_event_label;
109 bool first_pass = true;
110 for (auto const& event : events) {
111 if (first_pass) {
112 prev_event_label = event.label_;
113 prev_time = event.timestamp_;
114 start_time = prev_time;
115 first_pass = false;
116 } else {
117 Duration sample = event.timestamp_ - prev_time;
118 DurationKeyPtr key(new DurationKey(family_, query_type, response_type,
119 prev_event_label, event.label_, subnet_id));
120 addDurationSample(key, sample);
121
122 // Update global duration.
123 if (subnet_id != SUBNET_ID_GLOBAL) {
124 key->setSubnetId(SUBNET_ID_GLOBAL);
125 addDurationSample(key, sample);
126 }
127
128 prev_event_label = event.label_;
129 prev_time = event.timestamp_;
130 }
131 }
132
133 // Generate composite total.
134 Duration sample = prev_time - start_time;
135 DurationKeyPtr key(new DurationKey(family_, query_type, response_type,
136 "composite", "total_response", subnet_id));
137 addDurationSample(key, sample);
138 // Update global duration.
139 if (subnet_id != SUBNET_ID_GLOBAL) {
140 key->setSubnetId(SUBNET_ID_GLOBAL);
141 addDurationSample(key, sample);
142 }
143}
144
145void
147 // Update duration - duration is only returned if its time to report.
148 MonitoredDurationPtr duration = duration_store_->addDurationSample(key, sample);
149 if (duration) {
150 // Report to stat mgr, returns average duration.
151 Duration average = reportToStatsMgr(duration);
152
153 // Check the average against an alarm, if one exists.
154 AlarmPtr alarm = alarm_store_->checkDurationSample(duration, average, alarm_report_interval_);
155
156 // If an alarm had a reportable outcome, report it.
157 if (alarm) {
158 reportAlarm(alarm, average);
159 }
160 }
161}
162
165 if (!duration) {
166 isc_throw(BadValue, "reportToStatsMgr - duration is empty!");
167 }
168
169 auto previous_interval = duration->getPreviousInterval();
170 if (!previous_interval) {
171 isc_throw(BadValue, "reportToStatsMgr - duration previous interval is empty!");
172 }
173
174 auto average = previous_interval->getAverageDuration();
175 if (getStatsMgrReporting()) {
176 StatsMgr::instance().setValue(duration->getStatName("average-ms"),
177 static_cast<int64_t>(average.total_milliseconds()));
178 }
179
181
182 return (average);
183}
184
185void
187 std::string label = alarm->getLabel();
188 switch(alarm->getState()) {
189 case Alarm::CLEAR:
191 .arg(alarm->getLabel())
192 .arg(average)
193 .arg(alarm->getLowWater().total_milliseconds());
194 break;
195
196 case Alarm::TRIGGERED:
198 .arg(alarm->getLabel())
199 .arg(ptimeToText(alarm->getStosTime(), 3))
200 .arg(average)
201 .arg(alarm->getHighWater().total_milliseconds());
202 alarm->setLastHighWaterReport();
203 alarm_store_->updateAlarm(alarm);
204 break;
205
206 case Alarm::DISABLED:
207 // Shouldn't happen. We'll silently ignore for now.
208 break;
209 }
210}
211
212void
214 isc_throw (NotImplemented, __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__);
215}
216
217void
219 isc_throw (NotImplemented, __FILE__ << ":" << __LINE__ << ":" << __FUNCTION__);
220}
221
222} // end of namespace perfmon
223} // end of namespace isc
A generic exception that is thrown if a parameter given to a method is considered invalid in that con...
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown when a function is not implemented.
A generic exception that is thrown when an unexpected error condition occurs.
To be removed. Please use ConfigError instead.
Houses the composite key that uniquely identifies a duration:
static void validateMessagePair(uint16_t family, uint8_t query_type, uint8_t response_type)
Validates that a query and response message type pair is sane.
Maintains an in-memory store of durations.
Houses the PerfMon configuration parameters for a single scope (e.g.
uint32_t interval_width_secs_
Number of seconds a duration accumulates samples until reporting.
uint32_t alarm_report_secs_
Number of seconds between reports of a raised alarm.
void setEnableMonitoring(bool value)
Sets the value of enable-monitoring.
uint16_t family_
Protocol family AF_INET or AF_INET6.
bool getStatsMgrReporting() const
Fetches the value of stats-mgr-reporting.
void parse(data::ConstElementPtr config)
Extracts member values from an Element::map.
bool enable_monitoring_
If true, performance data is processed/reported.
AlarmStorePtr alarm_store_
Stores the configured alarms.
void processPktEventStack(isc::dhcp::PktPtr query, isc::dhcp::PktPtr response, const isc::dhcp::SubnetPtr subnet)
Processes the event stack of a query packet.
Definition: perfmon_mgr.cc:68
void reportTimerExpired()
Handler invoked when the report timer expires.
Definition: perfmon_mgr.cc:213
Duration interval_duration_
Length of time a MonitoredDuration accumulates samples until reporting.
Definition: perfmon_mgr.h:131
void setNextReportExpiration()
Updates the report timer.
Definition: perfmon_mgr.cc:218
void addDurationSample(DurationKeyPtr key, const Duration &sample)
Adds a duration sample to a MonitoredDuration.
Definition: perfmon_mgr.cc:146
PerfMonMgr(uint16_t family)
Constructor.
Definition: perfmon_mgr.cc:28
Duration reportToStatsMgr(MonitoredDurationPtr duration)
Emits an entry to StatsMgr for a given duration.
Definition: perfmon_mgr.cc:164
void configure(const isc::data::ConstElementPtr &params)
Parses the hook library 'parameters' element.
Definition: perfmon_mgr.cc:44
MonitoredDurationStorePtr duration_store_
In-memory store of MonitoredDurations.
Definition: perfmon_mgr.h:139
void reportAlarm(AlarmPtr alarm, const Duration &average)
Emits a report for a given alarm.
Definition: perfmon_mgr.cc:186
Duration alarm_report_interval_
Length of time between raised Alarm reports.
Definition: perfmon_mgr.h:136
virtual void init()
Sets convenience values and (re)creates the duration store.
Definition: perfmon_mgr.cc:34
static StatsMgr & instance()
Statistics Manager accessor method.
@ DHCPV6_NOTYPE
Definition: dhcp6.h:197
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
void setValue(const std::string &name, const int64_t value)
Records absolute integer observation.
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
Definition: macros.h:20
#define LOG_WARN(LOGGER, MESSAGE)
Macro to conveniently test warn output and log it.
Definition: macros.h:26
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
Definition: macros.h:14
boost::shared_ptr< const Element > ConstElementPtr
Definition: data.h:29
boost::shared_ptr< isc::dhcp::Pkt > PktPtr
A pointer to either Pkt4 or Pkt6 packet.
Definition: pkt.h:982
boost::shared_ptr< Subnet > SubnetPtr
A generic pointer to either Subnet4 or Subnet6 object.
Definition: subnet.h:449
uint32_t SubnetID
Defines unique IPv4 or IPv6 subnet identifier.
Definition: subnet_id.h:25
@ DHCP_NOTYPE
Message Type option missing.
Definition: dhcp4.h:235
const int DBGLVL_TRACE_DETAIL
Trace detailed operations.
Definition: log_dbglevels.h:75
boost::posix_time::time_duration Duration
boost::shared_ptr< DurationKey > DurationKeyPtr
Defines a pointer to a DurationKey instance.
boost::shared_ptr< MonitoredDuration > MonitoredDurationPtr
boost::shared_ptr< Alarm > AlarmPtr
Defines a pointer to an Alarm instance.
Definition: alarm.h:168
isc::log::Logger perfmon_logger("perfmon-hooks")
Definition: perfmon_log.h:17
std::string ptimeToText(boost::posix_time::ptime t, size_t fsecs_precision=MAX_FSECS_PRECISION)
Converts ptime structure to text.
Defines the logger used by the top-level component of kea-lfc.
const isc::log::MessageID PERFMON_ALARM_CLEARED
const isc::log::MessageID PERFMON_ALARM_TRIGGERED
const isc::log::MessageID PERFMON_DHCP4_PKT_EVENTS
const isc::log::MessageID PERFMON_DHCP6_PKT_EVENTS