• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2015 gRPC authors.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //     http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #ifndef GRPC_SRC_CORE_LIB_DEBUG_TRACE_IMPL_H
16 #define GRPC_SRC_CORE_LIB_DEBUG_TRACE_IMPL_H
17 
18 #include <grpc/support/port_platform.h>
19 
20 #include <atomic>
21 #include <map>
22 #include <string>
23 
24 #include "absl/container/flat_hash_map.h"
25 #include "absl/log/log.h"
26 #include "absl/strings/string_view.h"
27 
28 #ifdef _WIN32
29 #undef ERROR
30 #endif
31 
32 void grpc_tracer_init();
33 void grpc_tracer_shutdown(void);
34 
35 namespace grpc_core {
36 bool ParseTracers(absl::string_view tracers);
37 class SavedTraceFlags;
38 
39 class TraceFlag;
40 
41 namespace testing {
42 void grpc_tracer_enable_flag(TraceFlag* flag);
43 }
44 
45 class TraceFlag {
46  public:
47   TraceFlag(bool default_enabled, const char* name);
48   // TraceFlag needs to be trivially destructible since it is used as global
49   // variable.
50   ~TraceFlag() = default;
51 
name()52   const char* name() const { return name_; }
53 
54 // Use the symbol GRPC_USE_TRACERS to determine if tracers will be enabled in
55 // opt builds (tracers are always on in dbg builds). The default in OSS is for
56 // tracers to be on since we support binary distributions of gRPC for the
57 // wrapped language (wr don't want to force recompilation to get tracing).
58 // Internally, however, for performance reasons, we compile them out by
59 // default, since internal build systems make recompiling trivial.
60 //
61 // Prefer GRPC_TRACE_FLAG_ENABLED() macro instead of using enabled() directly.
62 #define GRPC_USE_TRACERS  // tracers on by default in OSS
63 #if defined(GRPC_USE_TRACERS) || !defined(NDEBUG)
enabled()64   bool enabled() { return value_.load(std::memory_order_relaxed); }
65 #else
enabled()66   bool enabled() { return false; }
67 #endif  // defined(GRPC_USE_TRACERS) || !defined(NDEBUG)
68 
69  private:
70   friend void testing::grpc_tracer_enable_flag(TraceFlag* flag);
71   friend bool ParseTracers(absl::string_view tracers);
72   friend SavedTraceFlags;
73 
set_enabled(bool enabled)74   void set_enabled(bool enabled) {
75     value_.store(enabled, std::memory_order_relaxed);
76   }
77 
78   TraceFlag* next_tracer_;
79   const char* const name_;
80   std::atomic<bool> value_;
81 };
82 
83 #define GRPC_TRACE_FLAG_ENABLED_OBJ(obj) GPR_UNLIKELY((obj).enabled())
84 
85 #define GRPC_TRACE_FLAG_ENABLED(tracer) \
86   GPR_UNLIKELY((grpc_core::tracer##_trace).enabled())
87 
88 #define GRPC_TRACE_LOG(tracer, level) \
89   LOG_IF(level, GRPC_TRACE_FLAG_ENABLED(tracer))
90 
91 #define GRPC_TRACE_DLOG(tracer, level) \
92   DLOG_IF(level, GRPC_TRACE_FLAG_ENABLED(tracer))
93 
94 #define GRPC_TRACE_VLOG(tracer, level) \
95   if (GRPC_TRACE_FLAG_ENABLED(tracer)) VLOG(level)
96 
97 #ifndef NDEBUG
98 typedef TraceFlag DebugOnlyTraceFlag;
99 #else
100 class DebugOnlyTraceFlag {
101  public:
DebugOnlyTraceFlag(bool,const char *)102   constexpr DebugOnlyTraceFlag(bool /*default_enabled*/, const char* /*name*/) {
103   }
enabled()104   constexpr bool enabled() const { return false; }
name()105   constexpr const char* name() const { return "DebugOnlyTraceFlag"; }
106 
107  private:
set_enabled(bool)108   void set_enabled(bool /*enabled*/) {}
109 };
110 #endif
111 
112 class SavedTraceFlags {
113  public:
114   SavedTraceFlags();
115   void Restore();
116 
117  private:
118   std::map<std::string, std::pair<bool, TraceFlag*>> values_;
119 };
120 
121 const absl::flat_hash_map<std::string, TraceFlag*>& GetAllTraceFlags();
122 
123 }  // namespace grpc_core
124 
125 #endif  // GRPC_SRC_CORE_LIB_DEBUG_TRACE_IMPL_H
126