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