1 //
2 //
3 // Copyright 2023 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #ifndef GRPCPP_EXT_SERVER_METRIC_RECORDER_H
20 #define GRPCPP_EXT_SERVER_METRIC_RECORDER_H
21 
22 #include <functional>
23 #include <map>
24 #include <memory>
25 
26 #include <grpcpp/impl/sync.h>
27 #include <grpcpp/support/string_ref.h>
28 
29 namespace grpc_core {
30 struct BackendMetricData;
31 }  // namespace grpc_core
32 
33 namespace grpc {
34 class BackendMetricState;
35 
36 namespace experimental {
37 /// Records server wide metrics to be reported to the client.
38 /// Server implementation creates an instance and reports server metrics to it,
39 /// and then passes it to
40 /// ServerBuilder::experimental_type::EnableCallMetricRecording or
41 /// experimental::OrcaService that read metrics to include in the report.
42 class ServerMetricRecorder {
43  public:
44   // Factory method. Use this to create.
45   static std::unique_ptr<ServerMetricRecorder> Create();
46   /// Records the server CPU utilization in the range [0, infy).
47   /// Values may be larger than 1.0 when the usage exceeds the reporter
48   /// dependent notion of soft limits. Values outside of the valid range are
49   /// rejected. Overrides the stored value when called again with a valid value.
50   void SetCpuUtilization(double value);
51   /// Records the server memory utilization in the range [0, 1].
52   /// Values outside of the valid range are rejected.
53   /// Overrides the stored value when called again with a valid value.
54   void SetMemoryUtilization(double value);
55   /// Records the application specific utilization in the range [0, infy].
56   /// Values outside of the valid range are rejected.
57   /// Overrides the stored value when called again with a valid value.
58   void SetApplicationUtilization(double value);
59   /// Records number of queries per second to the server in the range [0, infy).
60   /// Values outside of the valid range are rejected.
61   /// Overrides the stored value when called again with a valid value.
62   void SetQps(double value);
63   /// Records number of errors per second to the server in the range [0, infy).
64   /// Values outside of the valid range are rejected.
65   /// Overrides the stored value when called again with a valid value.
66   void SetEps(double value);
67   /// Records a named resource utilization value in the range [0, 1].
68   /// Values outside of the valid range are rejected.
69   /// Overrides the stored value when called again with the same name.
70   /// The name string should remain valid while this utilization remains
71   /// in this recorder. It is assumed that strings are common names that are
72   /// global constants.
73   void SetNamedUtilization(string_ref name, double value);
74   /// Replaces all named resource utilization values. No range validation.
75   /// The name strings should remain valid while utilization values remain
76   /// in this recorder. It is assumed that strings are common names that are
77   /// global constants.
78   void SetAllNamedUtilization(std::map<string_ref, double> named_utilization);
79 
80   /// Clears the server CPU utilization if recorded.
81   void ClearCpuUtilization();
82   /// Clears the server memory utilization if recorded.
83   void ClearMemoryUtilization();
84   /// Clears the application specific utilization if recorded.
85   void ClearApplicationUtilization();
86   /// Clears number of queries per second to the server if recorded.
87   void ClearQps();
88   /// Clears number of errors per second to the server if recorded.
89   void ClearEps();
90   /// Clears a named utilization value if exists.
91   void ClearNamedUtilization(string_ref name);
92 
93  private:
94   // To access GetMetrics().
95   friend class grpc::BackendMetricState;
96   friend class OrcaService;
97 
98   struct BackendMetricDataState;
99 
100   // No direct creation, use the factory method Create() above.
101   ServerMetricRecorder();
102 
103   // Updates the metric state by applying `updater` to the data and incrementing
104   // the sequence number.
105   void UpdateBackendMetricDataState(
106       std::function<void(grpc_core::BackendMetricData*)> updater);
107 
108   grpc_core::BackendMetricData GetMetrics() const;
109   // Returned metric data is guaranteed to be identical between two calls if the
110   // sequence numbers match.
111   std::shared_ptr<const BackendMetricDataState> GetMetricsIfChanged() const;
112 
113   mutable grpc::internal::Mutex mu_;
114   std::shared_ptr<const BackendMetricDataState> metric_state_
115       ABSL_GUARDED_BY(mu_);
116 };
117 
118 }  // namespace experimental
119 }  // namespace grpc
120 
121 #endif  // GRPCPP_EXT_SERVER_METRIC_RECORDER_H
122