• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #ifndef MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_LOGGING_H_
12 #define MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_LOGGING_H_
13 
14 // To enable BWE logging, run this command from trunk/ :
15 // build/gyp_chromium --depth=. webrtc/modules/modules.gyp
16 //   -Denable_bwe_test_logging=1
17 #ifndef BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
18 #define BWE_TEST_LOGGING_COMPILE_TIME_ENABLE 0
19 #endif  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
20 
21 // BWE logging allows you to insert dynamically named log/plot points in the
22 // call tree. E.g. the function:
23 //  void f1() {
24 //    BWE_TEST_LOGGING_TIME(clock_->TimeInMilliseconds());
25 //    BWE_TEST_LOGGING_CONTEXT("stream");
26 //    for (uint32_t i=0; i<4; ++i) {
27 //      BWE_TEST_LOGGING_ENABLE(i & 1);
28 //      BWE_TEST_LOGGING_CONTEXT(i);
29 //      BWE_TEST_LOGGING_LOG1("weight", "%f tonnes", weights_[i]);
30 //      for (float j=0.0f; j<1.0; j+=0.4f) {
31 //        BWE_TEST_LOGGING_PLOT(0, "bps", -1, j);
32 //      }
33 //    }
34 //  }
35 //
36 // Might produce the output:
37 //   stream_00000001_weight 13.000000 tonnes
38 //   PLOT  stream_00000001_bps  1.000000  0.000000
39 //   PLOT  stream_00000001_bps  1.000000  0.400000
40 //   PLOT  stream_00000001_bps  1.000000  0.800000
41 //   stream_00000003_weight 39.000000 tonnes
42 //   PLOT  stream_00000003_bps  1.000000  0.000000
43 //   PLOT  stream_00000003_bps  1.000000  0.400000
44 //   PLOT  stream_00000003_bps  1.000000  0.800000
45 //
46 // Log *contexts* are names concatenated with '_' between them, with the name
47 // of the logged/plotted string/value last. Plot *time* is inherited down the
48 // tree. A branch is enabled by default but can be *disabled* to reduce output.
49 // The difference between the RTC_LOG and PLOT macros is that PLOT prefixes the
50 // line so it can be easily filtered, plus it outputs the current time.
51 
52 #if !(BWE_TEST_LOGGING_COMPILE_TIME_ENABLE)
53 
54 // Set a thread-global base logging context. This name will be prepended to all
55 // hierarchical contexts.
56 // |name| is a char*, std::string or uint32_t to name the context.
57 #define BWE_TEST_LOGGING_GLOBAL_CONTEXT(name)
58 
59 // Thread-globally allow/disallow logging.
60 // |enable| is expected to be a bool.
61 #define BWE_TEST_LOGGING_GLOBAL_ENABLE(enabled)
62 
63 // Insert a (hierarchical) logging context.
64 // |name| is a char*, std::string or uint32_t to name the context.
65 #define BWE_TEST_LOGGING_CONTEXT(name)
66 
67 // Allow/disallow logging down the call tree from this point. Logging must be
68 // enabled all the way to the root of the call tree to take place.
69 // |enable| is expected to be a bool.
70 #define BWE_TEST_LOGGING_ENABLE(enabled)
71 
72 // Set current time (only affects PLOT output). Down the call tree, the latest
73 // time set always takes precedence.
74 // |time| is an int64_t time in ms, or -1 to inherit time from previous context.
75 #define BWE_TEST_LOGGING_TIME(time)
76 
77 // Print to stdout, e.g.:
78 //   Context1_Context2_Name  printf-formated-string
79 // |name| is a char*, std::string or uint32_t to name the log line.
80 // |format| is a printf format string.
81 // |_1...| are arguments for printf.
82 #define BWE_TEST_LOGGING_LOG1(name, format, _1)
83 #define BWE_TEST_LOGGING_LOG2(name, format, _1, _2)
84 #define BWE_TEST_LOGGING_LOG3(name, format, _1, _2, _3)
85 #define BWE_TEST_LOGGING_LOG4(name, format, _1, _2, _3, _4)
86 #define BWE_TEST_LOGGING_LOG5(name, format, _1, _2, _3, _4, _5)
87 
88 // Print to stdout in tab-separated format suitable for plotting, e.g.:
89 //   PLOT figure Context1_Context2_Name  time  value
90 // |figure| is a figure id. Different figures are plotted in different windows.
91 // |name| is a char*, std::string or uint32_t to name the plotted value.
92 // |time| is an int64_t time in ms, or -1 to inherit time from previous context.
93 // |value| is a double precision float to be plotted.
94 // |ssrc| identifies the source of a stream
95 // |alg_name| is an optional argument, a string
96 #define BWE_TEST_LOGGING_PLOT(figure, name, time, value)
97 #define BWE_TEST_LOGGING_PLOT_WITH_NAME(figure, name, time, value, alg_name)
98 #define BWE_TEST_LOGGING_PLOT_WITH_SSRC(figure, name, time, value, ssrc)
99 #define BWE_TEST_LOGGING_PLOT_WITH_NAME_AND_SSRC(figure, name, time, value, \
100                                                  ssrc, alg_name)
101 
102 // Print to stdout in tab-separated format suitable for plotting, e.g.:
103 //   BAR figure Context1_Context2_Name  x_left  width  value
104 // |figure| is a figure id. Different figures are plotted in different windows.
105 // |name| is a char*, std::string or uint32_t to name the plotted value.
106 // |value| is a double precision float to be plotted.
107 // |ylow| and |yhigh| are double precision float for the error line.
108 // |title| is a string and refers to the error label.
109 // |ymax| is a double precision float for the limit horizontal line.
110 // |limit_title| is a string and refers to the limit label.
111 #define BWE_TEST_LOGGING_BAR(figure, name, value, flow_id)
112 #define BWE_TEST_LOGGING_ERRORBAR(figure, name, value, ylow, yhigh, \
113                                   error_title, flow_id)
114 #define BWE_TEST_LOGGING_LIMITERRORBAR( \
115     figure, name, value, ylow, yhigh, error_title, ymax, limit_title, flow_id)
116 
117 #define BWE_TEST_LOGGING_BASELINEBAR(figure, name, value, flow_id)
118 
119 // |num_flows| is an integer refering to the number of RMCAT flows in the
120 // scenario.
121 // Define |x_label| and |y_label| for plots.
122 #define BWE_TEST_LOGGING_LABEL(figure, x_label, y_label, num_flows)
123 
124 #else  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
125 
126 #include <map>
127 #include <memory>
128 #include <stack>
129 #include <string>
130 
131 #include "rtc_base/constructor_magic.h"
132 #include "rtc_base/synchronization/mutex.h"
133 
134 #define BWE_TEST_LOGGING_GLOBAL_CONTEXT(name)                             \
135   do {                                                                    \
136     webrtc::testing::bwe::Logging::GetInstance()->SetGlobalContext(name); \
137   } while (0)
138 
139 #define BWE_TEST_LOGGING_GLOBAL_ENABLE(enabled)                             \
140   do {                                                                      \
141     webrtc::testing::bwe::Logging::GetInstance()->SetGlobalEnable(enabled); \
142   } while (0)
143 
144 #define __BWE_TEST_LOGGING_CONTEXT_NAME(ctx, line) ctx##line
145 #define __BWE_TEST_LOGGING_CONTEXT_DECLARE(ctx, line, name, time, enabled) \
146   webrtc::testing::bwe::Logging::Context __BWE_TEST_LOGGING_CONTEXT_NAME(  \
147       ctx, line)(name, time, enabled)
148 
149 #define BWE_TEST_LOGGING_CONTEXT(name) \
150   __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, name, -1, true)
151 #define BWE_TEST_LOGGING_ENABLE(enabled)                           \
152   __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, "", -1, \
153                                      static_cast<bool>(enabled))
154 #define BWE_TEST_LOGGING_TIME(time)                            \
155   __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, "", \
156                                      static_cast<int64_t>(time), true)
157 
158 #define BWE_TEST_LOGGING_LOG1(name, format, _1)                    \
159   do {                                                             \
160     BWE_TEST_LOGGING_CONTEXT(name);                                \
161     webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1); \
162   } while (0)
163 #define BWE_TEST_LOGGING_LOG2(name, format, _1, _2)                    \
164   do {                                                                 \
165     BWE_TEST_LOGGING_CONTEXT(name);                                    \
166     webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2); \
167   } while (0)
168 #define BWE_TEST_LOGGING_LOG3(name, format, _1, _2, _3)                    \
169   do {                                                                     \
170     BWE_TEST_LOGGING_CONTEXT(name);                                        \
171     webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3); \
172   } while (0)
173 #define BWE_TEST_LOGGING_LOG4(name, format, _1, _2, _3, _4)                    \
174   do {                                                                         \
175     BWE_TEST_LOGGING_CONTEXT(name);                                            \
176     webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3, _4); \
177   } while (0)
178 #define BWE_TEST_LOGGING_LOG5(name, format, _1, _2, _3, _4, _5)               \
179   do {                                                                        \
180     BWE_TEST_LOGGING_CONTEXT(name);                                           \
181     webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3, _4, \
182                                                       _5);                    \
183   } while (0)
184 
185 #define BWE_TEST_LOGGING_PLOT(figure, name, time, value)                     \
186   do {                                                                       \
187     __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __PLOT__, name,           \
188                                        static_cast<int64_t>(time), true);    \
189     webrtc::testing::bwe::Logging::GetInstance()->Plot(figure, name, value); \
190   } while (0)
191 
192 #define BWE_TEST_LOGGING_PLOT_WITH_NAME(figure, name, time, value, alg_name) \
193   do {                                                                       \
194     __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __PLOT__, name,           \
195                                        static_cast<int64_t>(time), true);    \
196     webrtc::testing::bwe::Logging::GetInstance()->Plot(figure, name, value,  \
197                                                        alg_name);            \
198   } while (0)
199 
200 #define BWE_TEST_LOGGING_PLOT_WITH_SSRC(figure, name, time, value, ssrc)    \
201   do {                                                                      \
202     __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __PLOT__, name,          \
203                                        static_cast<int64_t>(time), true);   \
204     webrtc::testing::bwe::Logging::GetInstance()->Plot(figure, name, value, \
205                                                        ssrc);               \
206   } while (0)
207 
208 #define BWE_TEST_LOGGING_PLOT_WITH_NAME_AND_SSRC(figure, name, time, value, \
209                                                  ssrc, alg_name)            \
210   do {                                                                      \
211     __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __PLOT__, name,          \
212                                        static_cast<int64_t>(time), true);   \
213     webrtc::testing::bwe::Logging::GetInstance()->Plot(figure, name, value, \
214                                                        ssrc, alg_name);     \
215   } while (0)
216 
217 #define BWE_TEST_LOGGING_BAR(figure, name, value, flow_id)                     \
218   do {                                                                         \
219     BWE_TEST_LOGGING_CONTEXT(name);                                            \
220     webrtc::testing::bwe::Logging::GetInstance()->PlotBar(figure, name, value, \
221                                                           flow_id);            \
222   } while (0)
223 
224 #define BWE_TEST_LOGGING_BASELINEBAR(figure, name, value, flow_id) \
225   do {                                                             \
226     BWE_TEST_LOGGING_CONTEXT(name);                                \
227     webrtc::testing::bwe::Logging::GetInstance()->PlotBaselineBar( \
228         figure, name, value, flow_id);                             \
229   } while (0)
230 
231 #define BWE_TEST_LOGGING_ERRORBAR(figure, name, value, ylow, yhigh, title, \
232                                   flow_id)                                 \
233   do {                                                                     \
234     BWE_TEST_LOGGING_CONTEXT(name);                                        \
235     webrtc::testing::bwe::Logging::GetInstance()->PlotErrorBar(            \
236         figure, name, value, ylow, yhigh, title, flow_id);                 \
237   } while (0)
238 
239 #define BWE_TEST_LOGGING_LIMITERRORBAR(                                        \
240     figure, name, value, ylow, yhigh, error_title, ymax, limit_title, flow_id) \
241   do {                                                                         \
242     BWE_TEST_LOGGING_CONTEXT(name);                                            \
243     webrtc::testing::bwe::Logging::GetInstance()->PlotLimitErrorBar(           \
244         figure, name, value, ylow, yhigh, error_title, ymax, limit_title,      \
245         flow_id);                                                              \
246   } while (0)
247 
248 #define BWE_TEST_LOGGING_LABEL(figure, title, y_label, num_flows) \
249   do {                                                            \
250     BWE_TEST_LOGGING_CONTEXT(title);                              \
251     webrtc::testing::bwe::Logging::GetInstance()->PlotLabel(      \
252         figure, title, y_label, num_flows);                       \
253   } while (0)
254 
255 namespace webrtc {
256 namespace testing {
257 namespace bwe {
258 
259 class Logging {
260  public:
261   class Context {
262    public:
263     Context(uint32_t name, int64_t timestamp_ms, bool enabled);
264     Context(const std::string& name, int64_t timestamp_ms, bool enabled);
265     Context(const char* name, int64_t timestamp_ms, bool enabled);
266     ~Context();
267 
268    private:
269     RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Context);
270   };
271 
272   static Logging* GetInstance();
273 
274   void SetGlobalContext(uint32_t name);
275   void SetGlobalContext(const std::string& name);
276   void SetGlobalContext(const char* name);
277   void SetGlobalEnable(bool enabled);
278 
279 #if defined(__GNUC__)
280   // Note: Implicit |this| argument counts as the first argument.
281   __attribute__((__format__(__printf__, 2, 3)))
282 #endif
283   void
284   Log(const char format[], ...);
285   void Plot(int figure, const std::string& name, double value);
286   void Plot(int figure,
287             const std::string& name,
288             double value,
289             const std::string& alg_name);
290   void Plot(int figure, const std::string& name, double value, uint32_t ssrc);
291   void Plot(int figure,
292             const std::string& name,
293             double value,
294             uint32_t ssrc,
295             const std::string& alg_name);
296   void PlotBar(int figure, const std::string& name, double value, int flow_id);
297   void PlotBaselineBar(int figure,
298                        const std::string& name,
299                        double value,
300                        int flow_id);
301   void PlotErrorBar(int figure,
302                     const std::string& name,
303                     double value,
304                     double ylow,
305                     double yhigh,
306                     const std::string& error_title,
307                     int flow_id);
308 
309   void PlotLimitErrorBar(int figure,
310                          const std::string& name,
311                          double value,
312                          double ylow,
313                          double yhigh,
314                          const std::string& error_title,
315                          double ymax,
316                          const std::string& limit_title,
317                          int flow_id);
318   void PlotLabel(int figure,
319                  const std::string& title,
320                  const std::string& y_label,
321                  int num_flows);
322 
323  private:
324   struct State {
325     State();
326     State(const std::string& new_tag, int64_t timestamp_ms, bool enabled);
327     void MergePrevious(const State& previous);
328 
329     std::string tag;
330     int64_t timestamp_ms;
331     bool enabled;
332   };
333   struct ThreadState {
334     ThreadState();
335     ~ThreadState();
336     State global_state;
337     std::stack<State> stack;
338   };
339   typedef std::map<uint32_t, ThreadState> ThreadMap;
340 
341   Logging();
342   ~Logging();
343   void PushState(const std::string& append_to_tag,
344                  int64_t timestamp_ms,
345                  bool enabled);
346   void PopState();
347 
348   Mutex mutex_;
349   ThreadMap thread_map_;
350 
351   RTC_DISALLOW_COPY_AND_ASSIGN(Logging);
352 };
353 }  // namespace bwe
354 }  // namespace testing
355 }  // namespace webrtc
356 
357 #endif  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
358 #endif  // MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_LOGGING_H_
359