| /* | 
 |  *  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("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  Context1_Context2_Name  time  value | 
 | // |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(name, time, value) | 
 |  | 
 | #else  // BWE_TEST_LOGGING_COMPILE_TIME_ENABLE | 
 |  | 
 | #include <map> | 
 | #include <stack> | 
 | #include <string> | 
 |  | 
 | #include "webrtc/common_types.h" | 
 | #include "webrtc/system_wrappers/interface/constructor_magic.h" | 
 | #include "webrtc/system_wrappers/interface/scoped_ptr.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(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(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(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; | 
 |   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_ |