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 : #ifndef FIREBOLT_RIALTO_SERVER_METRICS_COLLECTOR_H_
21 : #define FIREBOLT_RIALTO_SERVER_METRICS_COLLECTOR_H_
22 :
23 : #include "IMetricsCollector.h"
24 : #include "IMetricsReporter.h"
25 : #include "ITimer.h"
26 : #include "MetricsThresholdChecker.h"
27 : #include "StateMetricsAggregator.h"
28 : #include <cstdint>
29 : #include <map>
30 : #include <memory>
31 : #include <mutex>
32 : #include <optional>
33 : #include <string>
34 :
35 : namespace firebolt::rialto::server
36 : {
37 : class MetricsCollectorFactory : public IMetricsCollectorFactory
38 : {
39 : public:
40 7 : MetricsCollectorFactory() = default;
41 7 : ~MetricsCollectorFactory() override = default;
42 :
43 : std::unique_ptr<IMetricsCollector> create(int clientId, const std::shared_ptr<IMetricsCollectorClient> &client,
44 : ApplicationState initialApplicationState) override;
45 : };
46 :
47 : class MetricsCollector : public IMetricsCollector
48 : {
49 : public:
50 : MetricsCollector(int clientId, const std::shared_ptr<IMetricsCollectorClient> &client,
51 : const std::shared_ptr<firebolt::rialto::common::ITimerFactory> &timerFactory,
52 : ApplicationState initialApplicationState = ApplicationState::UNKNOWN);
53 : ~MetricsCollector() override;
54 :
55 : void processMetrics(const ClientMetricsData &metrics) override;
56 : void notifyPlaybackStateChanged(int sessionId, PlaybackState oldState, PlaybackState newState) override;
57 : void notifyWebAudioPlayerStateChanged(int handle, WebAudioPlayerState oldState, WebAudioPlayerState newState) override;
58 : void notifyApplicationStateChanged(ApplicationState oldState, ApplicationState newState) override;
59 :
60 : private:
61 : struct ProcessMetricsSample
62 : {
63 : std::uint64_t monotonicTimeMs{0};
64 : std::uint64_t epochTimeMs{0};
65 : std::uint64_t processCpuTimeMs{0};
66 : std::uint64_t processMemoryKb{0};
67 : std::uint64_t cgroupMemoryUsageKb{0};
68 : std::uint64_t cgroupMemoryLimitKb{0};
69 : std::uint64_t shmMemoryKb{0};
70 : };
71 :
72 : struct PreviousSample
73 : {
74 : std::uint64_t clientMonotonicTimeMs{0};
75 : std::uint64_t clientCpuTimeMs{0};
76 : std::uint64_t clientMemoryKb{0};
77 : ProcessMetricsSample serverMetrics;
78 : };
79 :
80 : struct SessionMetricsState
81 : {
82 : std::string currentState;
83 : StateMetricsAggregator aggregator;
84 : };
85 :
86 : void onTimerFired();
87 : ProcessMetricsSample getServerMetrics() const;
88 : double calculateCpuPercentage(std::uint64_t currentCpuTimeMs, std::uint64_t previousCpuTimeMs,
89 : std::uint64_t currentMonotonicTimeMs, std::uint64_t previousMonotonicTimeMs) const;
90 : static const char *sampleReasonToString(MetricsSampleReason reason);
91 : static const char *playbackStateToString(PlaybackState state);
92 : static const char *webAudioPlayerStateToString(WebAudioPlayerState state);
93 : static const char *applicationStateToString(ApplicationState state);
94 : void notifyPlayerStateChanged(const std::string &context, const char *oldState, const char *newState,
95 : bool terminalState);
96 :
97 : const int m_clientId;
98 : std::shared_ptr<IMetricsCollectorClient> m_client;
99 : std::unique_ptr<firebolt::rialto::common::ITimer> m_timer;
100 : std::uint64_t m_nextSampleId{1};
101 : std::optional<std::uint64_t> m_pendingPeriodicSampleId;
102 : unsigned int m_pendingPeriodicTimerCount{0};
103 : bool m_clientResponsive{true};
104 :
105 : std::mutex m_mutex;
106 : std::optional<PreviousSample> m_previousSample;
107 :
108 : // Per-player state tracking (typed context -> state)
109 : std::map<std::string, SessionMetricsState> m_sessionStates;
110 :
111 : // Global aggregator (active across all sessions while RUNNING)
112 : StateMetricsAggregator m_globalAggregator;
113 : ApplicationState m_currentApplicationState{ApplicationState::UNKNOWN};
114 :
115 : // Pluggable metrics reporter (log, telemetry, or composite)
116 : std::unique_ptr<IMetricsReporter> m_reporter;
117 :
118 : // Threshold checker
119 : MetricsThresholdConfig m_thresholdConfig;
120 : MetricsThresholdChecker m_thresholdChecker;
121 : };
122 : } // namespace firebolt::rialto::server
123 :
124 : #endif // FIREBOLT_RIALTO_SERVER_METRICS_COLLECTOR_H_
|