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(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