Line data Source code
1 : /*
2 : * If not stated otherwise in this file or this component's LICENSE file the
3 : * following copyright and licenses apply:
4 : *
5 : * Copyright 2026 Sky UK
6 : *
7 : * Licensed under the Apache License, Version 2.0 (the "License");
8 : * you may not use this file except in compliance with the License.
9 : * You may obtain a copy of the License at
10 : *
11 : * http://www.apache.org/licenses/LICENSE-2.0
12 : *
13 : * Unless required by applicable law or agreed to in writing, software
14 : * distributed under the License is distributed on an "AS IS" BASIS,
15 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 : * See the License for the specific language governing permissions and
17 : * limitations under the License.
18 : */
19 :
20 : #include "MetricsThresholdChecker.h"
21 :
22 : namespace firebolt::rialto::server
23 : {
24 7 : MetricsThresholdChecker::MetricsThresholdChecker(MetricsThresholdConfig &config, IMetricsReporter *reporter)
25 7 : : m_config{config}, m_reporter{reporter}
26 : {
27 : }
28 :
29 14 : void MetricsThresholdChecker::checkSample(double clientCpu, double serverCpu, double combinedCpu,
30 : std::uint64_t clientMemKb, std::uint64_t serverMemKb,
31 : std::uint64_t cgroupUsageKb, std::uint64_t cgroupLimitKb)
32 : {
33 14 : if (!m_reporter)
34 : {
35 1 : return;
36 : }
37 :
38 13 : checkMetric(m_config.clientCpu, clientCpu, m_clientCpuState);
39 13 : checkMetric(m_config.serverCpu, serverCpu, m_serverCpuState);
40 13 : checkMetric(m_config.combinedCpu, combinedCpu, m_combinedCpuState);
41 13 : checkMetric(m_config.clientMemoryKb, static_cast<double>(clientMemKb), m_clientMemState);
42 13 : checkMetric(m_config.serverMemoryKb, static_cast<double>(serverMemKb), m_serverMemState);
43 :
44 : // Cgroup memory as percentage of limit
45 13 : if (cgroupLimitKb > 0)
46 : {
47 1 : const double cgroupPct{(static_cast<double>(cgroupUsageKb) / static_cast<double>(cgroupLimitKb)) * 100.0};
48 1 : checkMetric(m_config.cgroupMemoryPercent, cgroupPct, m_cgroupMemState);
49 : }
50 : }
51 :
52 66 : void MetricsThresholdChecker::checkMetric(const MetricsThreshold &threshold, double value, ThresholdState &state)
53 : {
54 : // Critical check
55 66 : if (value >= threshold.criticalLevel)
56 : {
57 4 : state.belowCriticalCount = 0;
58 4 : state.belowWarningCount = 0;
59 4 : state.warningFired = true;
60 4 : if (!state.criticalFired)
61 : {
62 3 : state.criticalFired = true;
63 3 : ThresholdAlert alert;
64 3 : alert.metricName = threshold.metricName;
65 3 : alert.currentValue = value;
66 3 : alert.thresholdValue = threshold.criticalLevel;
67 3 : alert.severity = ThresholdSeverity::CRITICAL;
68 3 : m_reporter->reportThresholdExceeded(alert);
69 : }
70 4 : return;
71 : }
72 :
73 62 : ++state.belowCriticalCount;
74 62 : if (state.belowCriticalCount >= kDebounceSamples)
75 : {
76 40 : state.criticalFired = false;
77 : }
78 :
79 : // Warning check
80 62 : if (value >= threshold.warningLevel)
81 : {
82 9 : state.belowWarningCount = 0;
83 9 : if (!state.warningFired)
84 : {
85 8 : state.warningFired = true;
86 8 : ThresholdAlert alert;
87 8 : alert.metricName = threshold.metricName;
88 8 : alert.currentValue = value;
89 8 : alert.thresholdValue = threshold.warningLevel;
90 8 : alert.severity = ThresholdSeverity::WARNING;
91 8 : m_reporter->reportThresholdExceeded(alert);
92 : }
93 : }
94 : else
95 : {
96 53 : ++state.belowWarningCount;
97 53 : if (state.belowWarningCount >= kDebounceSamples)
98 : {
99 38 : state.warningFired = false;
100 : }
101 : }
102 : }
103 : } // namespace firebolt::rialto::server
|