• 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 WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_LOGGING_H_
12 #define WEBRTC_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 LOG and PLOT macros is that PLOT prefixes the line
50 // 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 // |alg_name| is an optional argument, a string
95 #define BWE_TEST_LOGGING_PLOT(figure, name, time, value)
96 #define BWE_TEST_LOGGING_PLOT_WITH_NAME(figure, name, time, value, alg_name)
97 
98 // Print to stdout in tab-separated format suitable for plotting, e.g.:
99 //   BAR figure Context1_Context2_Name  x_left  width  value
100 // |figure| is a figure id. Different figures are plotted in different windows.
101 // |name| is a char*, std::string or uint32_t to name the plotted value.
102 // |value| is a double precision float to be plotted.
103 // |ylow| and |yhigh| are double precision float for the error line.
104 // |title| is a string and refers to the error label.
105 // |ymax| is a double precision float for the limit horizontal line.
106 // |limit_title| is a string and refers to the limit label.
107 #define BWE_TEST_LOGGING_BAR(figure, name, value, flow_id)
108 #define BWE_TEST_LOGGING_ERRORBAR(figure, name, value, ylow, yhigh, \
109                                   error_title, flow_id)
110 #define BWE_TEST_LOGGING_LIMITERRORBAR( \
111     figure, name, value, ylow, yhigh, error_title, ymax, limit_title, flow_id)
112 
113 #define BWE_TEST_LOGGING_BASELINEBAR(figure, name, value, flow_id)
114 
115 // |num_flows| is an integer refering to the number of RMCAT flows in the
116 // scenario.
117 // Define |x_label| and |y_label| for plots.
118 #define BWE_TEST_LOGGING_LABEL(figure, x_label, y_label, num_flows)
119 
120 #else  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
121 
122 #include <map>
123 #include <stack>
124 #include <string>
125 
126 #include "webrtc/base/constructormagic.h"
127 #include "webrtc/base/scoped_ptr.h"
128 #include "webrtc/common_types.h"
129 
130 #define BWE_TEST_LOGGING_GLOBAL_CONTEXT(name) \
131     do { \
132       webrtc::testing::bwe::Logging::GetInstance()->SetGlobalContext(name); \
133     } while (0)
134 
135 #define BWE_TEST_LOGGING_GLOBAL_ENABLE(enabled) \
136     do { \
137       webrtc::testing::bwe::Logging::GetInstance()->SetGlobalEnable(enabled); \
138     } while (0)
139 
140 #define __BWE_TEST_LOGGING_CONTEXT_NAME(ctx, line) ctx ## line
141 #define __BWE_TEST_LOGGING_CONTEXT_DECLARE(ctx, line, name, time, enabled) \
142     webrtc::testing::bwe::Logging::Context \
143         __BWE_TEST_LOGGING_CONTEXT_NAME(ctx, line)(name, time, enabled)
144 
145 #define BWE_TEST_LOGGING_CONTEXT(name) \
146     __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, name, -1, true)
147 #define BWE_TEST_LOGGING_ENABLE(enabled) \
148     __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, "", -1, \
149                                        static_cast<bool>(enabled))
150 #define BWE_TEST_LOGGING_TIME(time) \
151     __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, "", \
152                                        static_cast<int64_t>(time), true)
153 
154 #define BWE_TEST_LOGGING_LOG1(name, format, _1) \
155     do { \
156       BWE_TEST_LOGGING_CONTEXT(name); \
157       webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1); \
158     } while (0)
159 #define BWE_TEST_LOGGING_LOG2(name, format, _1, _2) \
160     do { \
161       BWE_TEST_LOGGING_CONTEXT(name); \
162       webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2); \
163     } while (0)
164 #define BWE_TEST_LOGGING_LOG3(name, format, _1, _2, _3) \
165     do { \
166       BWE_TEST_LOGGING_CONTEXT(name); \
167       webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3); \
168     } while (0)
169 #define BWE_TEST_LOGGING_LOG4(name, format, _1, _2, _3, _4) \
170     do { \
171       BWE_TEST_LOGGING_CONTEXT(name); \
172       webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3, \
173                                                         _4); \
174     } while (0)
175 #define BWE_TEST_LOGGING_LOG5(name, format, _1, _2, _3, _4, _5) \
176     do {\
177       BWE_TEST_LOGGING_CONTEXT(name); \
178       webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3, \
179                                                         _4, _5); \
180     } while (0)
181 
182 #define BWE_TEST_LOGGING_PLOT(figure, name, time, value)                  \
183   do {                                                                    \
184     __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __PLOT__, name,        \
185                                        static_cast<int64_t>(time), true); \
186     webrtc::testing::bwe::Logging::GetInstance()->Plot(figure, value);    \
187   } while (0)
188 
189 #define BWE_TEST_LOGGING_PLOT_WITH_NAME(figure, name, time, value, alg_name) \
190   do {                                                                       \
191     __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __PLOT__, name,           \
192                                        static_cast<int64_t>(time), true);    \
193     webrtc::testing::bwe::Logging::GetInstance()->Plot(figure, value,        \
194                                                        alg_name);            \
195   } while (0)
196 
197 #define BWE_TEST_LOGGING_BAR(figure, name, value, flow_id)                     \
198   do {                                                                         \
199     BWE_TEST_LOGGING_CONTEXT(name);                                            \
200     webrtc::testing::bwe::Logging::GetInstance()->PlotBar(figure, name, value, \
201                                                           flow_id);            \
202   } while (0)
203 
204 #define BWE_TEST_LOGGING_BASELINEBAR(figure, name, value, flow_id) \
205   do {                                                             \
206     BWE_TEST_LOGGING_CONTEXT(name);                                \
207     webrtc::testing::bwe::Logging::GetInstance()->PlotBaselineBar( \
208         figure, name, value, flow_id);                             \
209   } while (0)
210 
211 #define BWE_TEST_LOGGING_ERRORBAR(figure, name, value, ylow, yhigh, title, \
212                                   flow_id)                                 \
213   do {                                                                     \
214     BWE_TEST_LOGGING_CONTEXT(name);                                        \
215     webrtc::testing::bwe::Logging::GetInstance()->PlotErrorBar(            \
216         figure, name, value, ylow, yhigh, title, flow_id);                 \
217   } while (0)
218 
219 #define BWE_TEST_LOGGING_LIMITERRORBAR(                                        \
220     figure, name, value, ylow, yhigh, error_title, ymax, limit_title, flow_id) \
221   do {                                                                         \
222     BWE_TEST_LOGGING_CONTEXT(name);                                            \
223     webrtc::testing::bwe::Logging::GetInstance()->PlotLimitErrorBar(           \
224         figure, name, value, ylow, yhigh, error_title, ymax, limit_title,      \
225         flow_id);                                                              \
226   } while (0)
227 
228 #define BWE_TEST_LOGGING_LABEL(figure, title, y_label, num_flows) \
229   do {                                                            \
230     BWE_TEST_LOGGING_CONTEXT(title);                              \
231     webrtc::testing::bwe::Logging::GetInstance()->PlotLabel(      \
232         figure, title, y_label, num_flows);                       \
233   } while (0)
234 
235 namespace webrtc {
236 
237 class CriticalSectionWrapper;
238 
239 namespace testing {
240 namespace bwe {
241 
242 class Logging {
243  public:
244   class Context {
245    public:
246     Context(uint32_t name, int64_t timestamp_ms, bool enabled);
247     Context(const std::string& name, int64_t timestamp_ms, bool enabled);
248     Context(const char* name, int64_t timestamp_ms, bool enabled);
249     ~Context();
250    private:
251     RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(Context);
252   };
253 
254   static Logging* GetInstance();
255 
256   void SetGlobalContext(uint32_t name);
257   void SetGlobalContext(const std::string& name);
258   void SetGlobalContext(const char* name);
259   void SetGlobalEnable(bool enabled);
260 
261   void Log(const char format[], ...);
262   void Plot(int figure, double value);
263   void Plot(int figure, double value, const std::string& alg_name);
264   void PlotBar(int figure, const std::string& name, double value, int flow_id);
265   void PlotBaselineBar(int figure,
266                        const std::string& name,
267                        double value,
268                        int flow_id);
269   void PlotErrorBar(int figure,
270                     const std::string& name,
271                     double value,
272                     double ylow,
273                     double yhigh,
274                     const std::string& error_title,
275                     int flow_id);
276 
277   void PlotLimitErrorBar(int figure,
278                          const std::string& name,
279                          double value,
280                          double ylow,
281                          double yhigh,
282                          const std::string& error_title,
283                          double ymax,
284                          const std::string& limit_title,
285                          int flow_id);
286   void PlotLabel(int figure,
287                  const std::string& title,
288                  const std::string& y_label,
289                  int num_flows);
290 
291  private:
292   struct State {
293     State();
294     State(const std::string& new_tag, int64_t timestamp_ms, bool enabled);
295     void MergePrevious(const State& previous);
296 
297     std::string tag;
298     int64_t timestamp_ms;
299     bool enabled;
300   };
301   struct ThreadState {
302     State global_state;
303     std::stack<State> stack;
304   };
305   typedef std::map<uint32_t, ThreadState> ThreadMap;
306 
307   Logging();
308   void PushState(const std::string& append_to_tag, int64_t timestamp_ms,
309                  bool enabled);
310   void PopState();
311 
312   static Logging g_Logging;
313   rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_;
314   ThreadMap thread_map_;
315 
316   RTC_DISALLOW_COPY_AND_ASSIGN(Logging);
317 };
318 }  // namespace bwe
319 }  // namespace testing
320 }  // namespace webrtc
321 
322 #endif  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE
323 #endif  // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_LOGGING_H_
324