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("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 Context1_Context2_Name time value 90// |name| is a char*, std::string or uint32_t to name the plotted value. 91// |time| is an int64_t time in ms, or -1 to inherit time from previous context. 92// |value| is a double precision float to be plotted. 93#define BWE_TEST_LOGGING_PLOT(name, time, value) 94 95#else // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE 96 97#include <map> 98#include <stack> 99#include <string> 100 101#include "webrtc/base/constructormagic.h" 102#include "webrtc/common_types.h" 103#include "webrtc/system_wrappers/interface/scoped_ptr.h" 104 105#define BWE_TEST_LOGGING_GLOBAL_CONTEXT(name) \ 106 do { \ 107 webrtc::testing::bwe::Logging::GetInstance()->SetGlobalContext(name); \ 108 } while (0); 109 110#define BWE_TEST_LOGGING_GLOBAL_ENABLE(enabled) \ 111 do { \ 112 webrtc::testing::bwe::Logging::GetInstance()->SetGlobalEnable(enabled); \ 113 } while (0); 114 115#define __BWE_TEST_LOGGING_CONTEXT_NAME(ctx, line) ctx ## line 116#define __BWE_TEST_LOGGING_CONTEXT_DECLARE(ctx, line, name, time, enabled) \ 117 webrtc::testing::bwe::Logging::Context \ 118 __BWE_TEST_LOGGING_CONTEXT_NAME(ctx, line)(name, time, enabled) 119 120#define BWE_TEST_LOGGING_CONTEXT(name) \ 121 __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, name, -1, true) 122#define BWE_TEST_LOGGING_ENABLE(enabled) \ 123 __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, "", -1, \ 124 static_cast<bool>(enabled)) 125#define BWE_TEST_LOGGING_TIME(time) \ 126 __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, "", \ 127 static_cast<int64_t>(time), true) 128 129#define BWE_TEST_LOGGING_LOG1(name, format, _1) \ 130 do { \ 131 BWE_TEST_LOGGING_CONTEXT(name); \ 132 webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1); \ 133 } while (0); 134#define BWE_TEST_LOGGING_LOG2(name, format, _1, _2) \ 135 do { \ 136 BWE_TEST_LOGGING_CONTEXT(name); \ 137 webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2); \ 138 } while (0); 139#define BWE_TEST_LOGGING_LOG3(name, format, _1, _2, _3) \ 140 do { \ 141 BWE_TEST_LOGGING_CONTEXT(name); \ 142 webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3); \ 143 } while (0); 144#define BWE_TEST_LOGGING_LOG4(name, format, _1, _2, _3, _4) \ 145 do { \ 146 BWE_TEST_LOGGING_CONTEXT(name); \ 147 webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3, \ 148 _4); \ 149 } while (0); 150#define BWE_TEST_LOGGING_LOG5(name, format, _1, _2, _3, _4, _5) \ 151 do {\ 152 BWE_TEST_LOGGING_CONTEXT(name); \ 153 webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3, \ 154 _4, _5); \ 155 } while (0); 156 157#define BWE_TEST_LOGGING_PLOT(name, time, value)\ 158 do { \ 159 __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, name, \ 160 static_cast<int64_t>(time), true); \ 161 webrtc::testing::bwe::Logging::GetInstance()->Plot(value); \ 162 } while (0); 163 164namespace webrtc { 165 166class CriticalSectionWrapper; 167 168namespace testing { 169namespace bwe { 170 171class Logging { 172 public: 173 class Context { 174 public: 175 Context(uint32_t name, int64_t timestamp_ms, bool enabled); 176 Context(const std::string& name, int64_t timestamp_ms, bool enabled); 177 Context(const char* name, int64_t timestamp_ms, bool enabled); 178 ~Context(); 179 private: 180 DISALLOW_IMPLICIT_CONSTRUCTORS(Context); 181 }; 182 183 static Logging* GetInstance(); 184 185 void SetGlobalContext(uint32_t name); 186 void SetGlobalContext(const std::string& name); 187 void SetGlobalContext(const char* name); 188 void SetGlobalEnable(bool enabled); 189 190 void Log(const char format[], ...); 191 void Plot(double value); 192 193 private: 194 struct State { 195 State(); 196 State(const std::string& new_tag, int64_t timestamp_ms, bool enabled); 197 void MergePrevious(const State& previous); 198 199 std::string tag; 200 int64_t timestamp_ms; 201 bool enabled; 202 }; 203 struct ThreadState { 204 State global_state; 205 std::stack<State> stack; 206 }; 207 typedef std::map<uint32_t, ThreadState> ThreadMap; 208 209 Logging(); 210 void PushState(const std::string& append_to_tag, int64_t timestamp_ms, 211 bool enabled); 212 void PopState(); 213 214 static Logging g_Logging; 215 scoped_ptr<CriticalSectionWrapper> crit_sect_; 216 ThreadMap thread_map_; 217 218 DISALLOW_COPY_AND_ASSIGN(Logging); 219}; 220} // namespace bwe 221} // namespace testing 222} // namespace webrtc 223 224#endif // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE 225#endif // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_LOGGING_H_ 226