|  | /* | 
|  | *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved. | 
|  | * | 
|  | *  Use of this source code is governed by a BSD-style license | 
|  | *  that can be found in the LICENSE file in the root of the source | 
|  | *  tree. An additional intellectual property rights grant can be found | 
|  | *  in the file PATENTS.  All contributing project authors may | 
|  | *  be found in the AUTHORS file in the root of the source tree. | 
|  | */ | 
|  |  | 
|  | #ifndef WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_LOGGING_H_ | 
|  | #define WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_LOGGING_H_ | 
|  |  | 
|  | // To enable BWE logging, run this command from trunk/ : | 
|  | // build/gyp_chromium --depth=. webrtc/modules/modules.gyp | 
|  | //   -Denable_bwe_test_logging=1 | 
|  | #ifndef BWE_TEST_LOGGING_COMPILE_TIME_ENABLE | 
|  | #define BWE_TEST_LOGGING_COMPILE_TIME_ENABLE 0 | 
|  | #endif  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE | 
|  |  | 
|  | // BWE logging allows you to insert dynamically named log/plot points in the | 
|  | // call tree. E.g. the function: | 
|  | //  void f1() { | 
|  | //    BWE_TEST_LOGGING_TIME(clock_->TimeInMilliseconds()); | 
|  | //    BWE_TEST_LOGGING_CONTEXT("stream"); | 
|  | //    for (uint32_t i=0; i<4; ++i) { | 
|  | //      BWE_TEST_LOGGING_ENABLE(i & 1); | 
|  | //      BWE_TEST_LOGGING_CONTEXT(i); | 
|  | //      BWE_TEST_LOGGING_LOG1("weight", "%f tonnes", weights_[i]); | 
|  | //      for (float j=0.0f; j<1.0; j+=0.4f) { | 
|  | //        BWE_TEST_LOGGING_PLOT(0, "bps", -1, j); | 
|  | //      } | 
|  | //    } | 
|  | //  } | 
|  | // | 
|  | // Might produce the output: | 
|  | //   stream_00000001_weight 13.000000 tonnes | 
|  | //   PLOT  stream_00000001_bps  1.000000  0.000000 | 
|  | //   PLOT  stream_00000001_bps  1.000000  0.400000 | 
|  | //   PLOT  stream_00000001_bps  1.000000  0.800000 | 
|  | //   stream_00000003_weight 39.000000 tonnes | 
|  | //   PLOT  stream_00000003_bps  1.000000  0.000000 | 
|  | //   PLOT  stream_00000003_bps  1.000000  0.400000 | 
|  | //   PLOT  stream_00000003_bps  1.000000  0.800000 | 
|  | // | 
|  | // Log *contexts* are names concatenated with '_' between them, with the name | 
|  | // of the logged/plotted string/value last. Plot *time* is inherited down the | 
|  | // tree. A branch is enabled by default but can be *disabled* to reduce output. | 
|  | // The difference between the LOG and PLOT macros is that PLOT prefixes the line | 
|  | // so it can be easily filtered, plus it outputs the current time. | 
|  |  | 
|  | #if !(BWE_TEST_LOGGING_COMPILE_TIME_ENABLE) | 
|  |  | 
|  | // Set a thread-global base logging context. This name will be prepended to all | 
|  | // hierarchical contexts. | 
|  | // |name| is a char*, std::string or uint32_t to name the context. | 
|  | #define BWE_TEST_LOGGING_GLOBAL_CONTEXT(name) | 
|  |  | 
|  | // Thread-globally allow/disallow logging. | 
|  | // |enable| is expected to be a bool. | 
|  | #define BWE_TEST_LOGGING_GLOBAL_ENABLE(enabled) | 
|  |  | 
|  | // Insert a (hierarchical) logging context. | 
|  | // |name| is a char*, std::string or uint32_t to name the context. | 
|  | #define BWE_TEST_LOGGING_CONTEXT(name) | 
|  |  | 
|  | // Allow/disallow logging down the call tree from this point. Logging must be | 
|  | // enabled all the way to the root of the call tree to take place. | 
|  | // |enable| is expected to be a bool. | 
|  | #define BWE_TEST_LOGGING_ENABLE(enabled) | 
|  |  | 
|  | // Set current time (only affects PLOT output). Down the call tree, the latest | 
|  | // time set always takes precedence. | 
|  | // |time| is an int64_t time in ms, or -1 to inherit time from previous context. | 
|  | #define BWE_TEST_LOGGING_TIME(time) | 
|  |  | 
|  | // Print to stdout, e.g.: | 
|  | //   Context1_Context2_Name  printf-formated-string | 
|  | // |name| is a char*, std::string or uint32_t to name the log line. | 
|  | // |format| is a printf format string. | 
|  | // |_1...| are arguments for printf. | 
|  | #define BWE_TEST_LOGGING_LOG1(name, format, _1) | 
|  | #define BWE_TEST_LOGGING_LOG2(name, format, _1, _2) | 
|  | #define BWE_TEST_LOGGING_LOG3(name, format, _1, _2, _3) | 
|  | #define BWE_TEST_LOGGING_LOG4(name, format, _1, _2, _3, _4) | 
|  | #define BWE_TEST_LOGGING_LOG5(name, format, _1, _2, _3, _4, _5) | 
|  |  | 
|  | // Print to stdout in tab-separated format suitable for plotting, e.g.: | 
|  | //   PLOT figure Context1_Context2_Name  time  value | 
|  | // |figure| is a figure id. Different figures are plotted in different windows. | 
|  | // |name| is a char*, std::string or uint32_t to name the plotted value. | 
|  | // |time| is an int64_t time in ms, or -1 to inherit time from previous context. | 
|  | // |value| is a double precision float to be plotted. | 
|  | #define BWE_TEST_LOGGING_PLOT(figure, name, time, value) | 
|  |  | 
|  | #else  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE | 
|  |  | 
|  | #include <map> | 
|  | #include <stack> | 
|  | #include <string> | 
|  |  | 
|  | #include "webrtc/base/constructormagic.h" | 
|  | #include "webrtc/base/scoped_ptr.h" | 
|  | #include "webrtc/common_types.h" | 
|  |  | 
|  | #define BWE_TEST_LOGGING_GLOBAL_CONTEXT(name) \ | 
|  | do { \ | 
|  | webrtc::testing::bwe::Logging::GetInstance()->SetGlobalContext(name); \ | 
|  | } while (0); | 
|  |  | 
|  | #define BWE_TEST_LOGGING_GLOBAL_ENABLE(enabled) \ | 
|  | do { \ | 
|  | webrtc::testing::bwe::Logging::GetInstance()->SetGlobalEnable(enabled); \ | 
|  | } while (0); | 
|  |  | 
|  | #define __BWE_TEST_LOGGING_CONTEXT_NAME(ctx, line) ctx ## line | 
|  | #define __BWE_TEST_LOGGING_CONTEXT_DECLARE(ctx, line, name, time, enabled) \ | 
|  | webrtc::testing::bwe::Logging::Context \ | 
|  | __BWE_TEST_LOGGING_CONTEXT_NAME(ctx, line)(name, time, enabled) | 
|  |  | 
|  | #define BWE_TEST_LOGGING_CONTEXT(name) \ | 
|  | __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, name, -1, true) | 
|  | #define BWE_TEST_LOGGING_ENABLE(enabled) \ | 
|  | __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, "", -1, \ | 
|  | static_cast<bool>(enabled)) | 
|  | #define BWE_TEST_LOGGING_TIME(time) \ | 
|  | __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, "", \ | 
|  | static_cast<int64_t>(time), true) | 
|  |  | 
|  | #define BWE_TEST_LOGGING_LOG1(name, format, _1) \ | 
|  | do { \ | 
|  | BWE_TEST_LOGGING_CONTEXT(name); \ | 
|  | webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1); \ | 
|  | } while (0); | 
|  | #define BWE_TEST_LOGGING_LOG2(name, format, _1, _2) \ | 
|  | do { \ | 
|  | BWE_TEST_LOGGING_CONTEXT(name); \ | 
|  | webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2); \ | 
|  | } while (0); | 
|  | #define BWE_TEST_LOGGING_LOG3(name, format, _1, _2, _3) \ | 
|  | do { \ | 
|  | BWE_TEST_LOGGING_CONTEXT(name); \ | 
|  | webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3); \ | 
|  | } while (0); | 
|  | #define BWE_TEST_LOGGING_LOG4(name, format, _1, _2, _3, _4) \ | 
|  | do { \ | 
|  | BWE_TEST_LOGGING_CONTEXT(name); \ | 
|  | webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3, \ | 
|  | _4); \ | 
|  | } while (0); | 
|  | #define BWE_TEST_LOGGING_LOG5(name, format, _1, _2, _3, _4, _5) \ | 
|  | do {\ | 
|  | BWE_TEST_LOGGING_CONTEXT(name); \ | 
|  | webrtc::testing::bwe::Logging::GetInstance()->Log(format, _1, _2, _3, \ | 
|  | _4, _5); \ | 
|  | } while (0); | 
|  |  | 
|  | #define BWE_TEST_LOGGING_PLOT(figure, name, time, value)                  \ | 
|  | do {                                                                    \ | 
|  | __BWE_TEST_LOGGING_CONTEXT_DECLARE(__bwe_log_, __LINE__, name,        \ | 
|  | static_cast<int64_t>(time), true); \ | 
|  | webrtc::testing::bwe::Logging::GetInstance()->Plot(figure, value);    \ | 
|  | } while (0); | 
|  |  | 
|  | namespace webrtc { | 
|  |  | 
|  | class CriticalSectionWrapper; | 
|  |  | 
|  | namespace testing { | 
|  | namespace bwe { | 
|  |  | 
|  | class Logging { | 
|  | public: | 
|  | class Context { | 
|  | public: | 
|  | Context(uint32_t name, int64_t timestamp_ms, bool enabled); | 
|  | Context(const std::string& name, int64_t timestamp_ms, bool enabled); | 
|  | Context(const char* name, int64_t timestamp_ms, bool enabled); | 
|  | ~Context(); | 
|  | private: | 
|  | DISALLOW_IMPLICIT_CONSTRUCTORS(Context); | 
|  | }; | 
|  |  | 
|  | static Logging* GetInstance(); | 
|  |  | 
|  | void SetGlobalContext(uint32_t name); | 
|  | void SetGlobalContext(const std::string& name); | 
|  | void SetGlobalContext(const char* name); | 
|  | void SetGlobalEnable(bool enabled); | 
|  |  | 
|  | void Log(const char format[], ...); | 
|  | void Plot(int figure, double value); | 
|  |  | 
|  | private: | 
|  | struct State { | 
|  | State(); | 
|  | State(const std::string& new_tag, int64_t timestamp_ms, bool enabled); | 
|  | void MergePrevious(const State& previous); | 
|  |  | 
|  | std::string tag; | 
|  | int64_t timestamp_ms; | 
|  | bool enabled; | 
|  | }; | 
|  | struct ThreadState { | 
|  | State global_state; | 
|  | std::stack<State> stack; | 
|  | }; | 
|  | typedef std::map<uint32_t, ThreadState> ThreadMap; | 
|  |  | 
|  | Logging(); | 
|  | void PushState(const std::string& append_to_tag, int64_t timestamp_ms, | 
|  | bool enabled); | 
|  | void PopState(); | 
|  |  | 
|  | static Logging g_Logging; | 
|  | rtc::scoped_ptr<CriticalSectionWrapper> crit_sect_; | 
|  | ThreadMap thread_map_; | 
|  |  | 
|  | DISALLOW_COPY_AND_ASSIGN(Logging); | 
|  | }; | 
|  | }  // namespace bwe | 
|  | }  // namespace testing | 
|  | }  // namespace webrtc | 
|  |  | 
|  | #endif  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE | 
|  | #endif  // WEBRTC_MODULES_REMOTE_BITRATE_ESTIMATOR_TEST_BWE_TEST_LOGGING_H_ |