Home | History | Annotate | Download | only in test
      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 
    164 namespace webrtc {
    165 
    166 class CriticalSectionWrapper;
    167 
    168 namespace testing {
    169 namespace bwe {
    170 
    171 class 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