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