1 | // Licensed to the Apache Software Foundation (ASF) under one |
2 | // or more contributor license agreements. See the NOTICE file |
3 | // distributed with this work for additional information |
4 | // regarding copyright ownership. The ASF licenses this file |
5 | // to you under the Apache License, Version 2.0 (the |
6 | // "License"); you may not use this file except in compliance |
7 | // with the License. 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, |
12 | // software distributed under the License is distributed on an |
13 | // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
14 | // KIND, either express or implied. See the License for the |
15 | // specific language governing permissions and limitations |
16 | // under the License. |
17 | |
18 | // Date: 2014/09/22 11:57:43 |
19 | |
20 | #ifndef BVAR_LATENCY_RECORDER_H |
21 | #define BVAR_LATENCY_RECORDER_H |
22 | |
23 | #include "bvar/recorder.h" |
24 | #include "bvar/reducer.h" |
25 | #include "bvar/passive_status.h" |
26 | #include "bvar/detail/percentile.h" |
27 | |
28 | namespace bvar { |
29 | namespace detail { |
30 | |
31 | class Percentile; |
32 | typedef Window<IntRecorder, SERIES_IN_SECOND> RecorderWindow; |
33 | typedef Window<Maxer<int64_t>, SERIES_IN_SECOND> MaxWindow; |
34 | typedef Window<Percentile, SERIES_IN_SECOND> PercentileWindow; |
35 | |
36 | // NOTE: Always use int64_t in the interfaces no matter what the impl. is. |
37 | |
38 | class CDF : public Variable { |
39 | public: |
40 | explicit CDF(PercentileWindow* w); |
41 | ~CDF(); |
42 | void describe(std::ostream& os, bool quote_string) const override; |
43 | int describe_series(std::ostream& os, const SeriesOptions& options) const override; |
44 | private: |
45 | PercentileWindow* _w; |
46 | }; |
47 | |
48 | // For mimic constructor inheritance. |
49 | class LatencyRecorderBase { |
50 | public: |
51 | explicit LatencyRecorderBase(time_t window_size); |
52 | time_t window_size() const { return _latency_window.window_size(); } |
53 | protected: |
54 | IntRecorder _latency; |
55 | Maxer<int64_t> _max_latency; |
56 | Percentile _latency_percentile; |
57 | |
58 | RecorderWindow _latency_window; |
59 | MaxWindow _max_latency_window; |
60 | PassiveStatus<int64_t> _count; |
61 | PassiveStatus<int64_t> _qps; |
62 | PercentileWindow _latency_percentile_window; |
63 | PassiveStatus<int64_t> _latency_p1; |
64 | PassiveStatus<int64_t> _latency_p2; |
65 | PassiveStatus<int64_t> _latency_p3; |
66 | PassiveStatus<int64_t> _latency_999; // 99.9% |
67 | PassiveStatus<int64_t> _latency_9999; // 99.99% |
68 | CDF _latency_cdf; |
69 | PassiveStatus<Vector<int64_t, 4> > _latency_percentiles; |
70 | }; |
71 | } // namespace detail |
72 | |
73 | // Specialized structure to record latency. |
74 | // It's not a Variable, but it contains multiple bvar inside. |
75 | class LatencyRecorder : public detail::LatencyRecorderBase { |
76 | typedef detail::LatencyRecorderBase Base; |
77 | public: |
78 | LatencyRecorder() : Base(-1) {} |
79 | explicit LatencyRecorder(time_t window_size) : Base(window_size) {} |
80 | explicit LatencyRecorder(const butil::StringPiece& prefix) : Base(-1) { |
81 | expose(prefix); |
82 | } |
83 | LatencyRecorder(const butil::StringPiece& prefix, |
84 | time_t window_size) : Base(window_size) { |
85 | expose(prefix); |
86 | } |
87 | LatencyRecorder(const butil::StringPiece& prefix1, |
88 | const butil::StringPiece& prefix2) : Base(-1) { |
89 | expose(prefix1, prefix2); |
90 | } |
91 | LatencyRecorder(const butil::StringPiece& prefix1, |
92 | const butil::StringPiece& prefix2, |
93 | time_t window_size) : Base(window_size) { |
94 | expose(prefix1, prefix2); |
95 | } |
96 | |
97 | ~LatencyRecorder() { hide(); } |
98 | |
99 | // Record the latency. |
100 | LatencyRecorder& operator<<(int64_t latency); |
101 | |
102 | // Expose all internal variables using `prefix' as prefix. |
103 | // Returns 0 on success, -1 otherwise. |
104 | // Example: |
105 | // LatencyRecorder rec; |
106 | // rec.expose("foo_bar_write"); // foo_bar_write_latency |
107 | // // foo_bar_write_max_latency |
108 | // // foo_bar_write_count |
109 | // // foo_bar_write_qps |
110 | // rec.expose("foo_bar", "read"); // foo_bar_read_latency |
111 | // // foo_bar_read_max_latency |
112 | // // foo_bar_read_count |
113 | // // foo_bar_read_qps |
114 | int expose(const butil::StringPiece& prefix) { |
115 | return expose(butil::StringPiece(), prefix); |
116 | } |
117 | int expose(const butil::StringPiece& prefix1, |
118 | const butil::StringPiece& prefix2); |
119 | |
120 | // Hide all internal variables, called in dtor as well. |
121 | void hide(); |
122 | |
123 | // Get the average latency in recent |window_size| seconds |
124 | // If |window_size| is absent, use the window_size to ctor. |
125 | int64_t latency(time_t window_size) const |
126 | { return _latency_window.get_value(window_size).get_average_int(); } |
127 | int64_t latency() const |
128 | { return _latency_window.get_value().get_average_int(); } |
129 | |
130 | // Get p1/p2/p3/99.9-ile latencies in recent window_size-to-ctor seconds. |
131 | Vector<int64_t, 4> latency_percentiles() const; |
132 | |
133 | // Get the max latency in recent window_size-to-ctor seconds. |
134 | int64_t max_latency() const { return _max_latency_window.get_value(); } |
135 | |
136 | // Get the total number of recorded latencies. |
137 | int64_t count() const { return _latency.get_value().num; } |
138 | |
139 | // Get qps in recent |window_size| seconds. The `q' means latencies |
140 | // recorded by operator<<(). |
141 | // If |window_size| is absent, use the window_size to ctor. |
142 | int64_t qps(time_t window_size) const; |
143 | int64_t qps() const { return _qps.get_value(); } |
144 | |
145 | // Get |ratio|-ile latency in recent |window_size| seconds |
146 | // E.g. 0.99 means 99%-ile |
147 | int64_t latency_percentile(double ratio) const; |
148 | |
149 | // Get name of a sub-bvar. |
150 | const std::string& latency_name() const { return _latency_window.name(); } |
151 | const std::string& latency_percentiles_name() const |
152 | { return _latency_percentiles.name(); } |
153 | const std::string& latency_cdf_name() const { return _latency_cdf.name(); } |
154 | const std::string& max_latency_name() const |
155 | { return _max_latency_window.name(); } |
156 | const std::string& count_name() const { return _count.name(); } |
157 | const std::string& qps_name() const { return _qps.name(); } |
158 | }; |
159 | |
160 | std::ostream& operator<<(std::ostream& os, const LatencyRecorder&); |
161 | |
162 | } // namespace bvar |
163 | |
164 | #endif //BVAR_LATENCY_RECORDER_H |
165 | |