• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //
2 //
3 // Copyright 2015 gRPC authors.
4 //
5 // Licensed under the Apache License, Version 2.0 (the "License");
6 // you may not use this file except in compliance with the License.
7 // You may obtain a copy of the License at
8 //
9 //     http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 //
17 //
18 
19 #include "src/core/lib/debug/trace.h"
20 
21 #include <grpc/grpc.h>
22 #include <grpc/support/port_platform.h>
23 
24 #include <string>
25 #include <type_traits>
26 #include <utility>
27 
28 #include "absl/log/log.h"
29 #include "absl/strings/match.h"
30 #include "absl/strings/str_cat.h"
31 #include "absl/strings/str_split.h"
32 #include "absl/strings/string_view.h"
33 #include "absl/strings/strip.h"
34 #include "src/core/config/config_vars.h"
35 #include "src/core/util/glob.h"
36 
37 int grpc_tracer_set_enabled(const char* name, int enabled);
38 
39 namespace grpc_core {
40 namespace {
LogAllTracers()41 void LogAllTracers() {
42   VLOG(2) << "available tracers:";
43   for (const auto& name : GetAllTraceFlags()) {
44     LOG(INFO) << "  " << name.first;
45   }
46 }
47 
48 }  // namespace
49 
50 // Flags register themselves on the list during construction
TraceFlag(bool default_enabled,const char * name)51 TraceFlag::TraceFlag(bool default_enabled, const char* name) : name_(name) {
52   static_assert(std::is_trivially_destructible<TraceFlag>::value,
53                 "TraceFlag needs to be trivially destructible.");
54   set_enabled(default_enabled);
55 }
56 
SavedTraceFlags()57 SavedTraceFlags::SavedTraceFlags() {
58   for (const auto& flag : GetAllTraceFlags()) {
59     values_[flag.first] = {flag.second->enabled(), flag.second};
60   }
61 }
62 
Restore()63 void SavedTraceFlags::Restore() {
64   for (const auto& flag : values_) {
65     flag.second.second->set_enabled(flag.second.first);
66   }
67 }
68 
ParseTracers(absl::string_view tracers)69 bool ParseTracers(absl::string_view tracers) {
70   std::string enabled_tracers;
71   bool some_trace_was_found = false;
72   for (auto trace_glob : absl::StrSplit(tracers, ',', absl::SkipWhitespace())) {
73     if (trace_glob == "list_tracers") {
74       LogAllTracers();
75       continue;
76     }
77     bool enabled = !absl::ConsumePrefix(&trace_glob, "-");
78     if (trace_glob == "all") trace_glob = "*";
79     if (trace_glob == "refcount") trace_glob = "*refcount*";
80     bool found = false;
81     for (const auto& flag : GetAllTraceFlags()) {
82       if (GlobMatch(flag.first, trace_glob)) {
83         flag.second->set_enabled(enabled);
84         if (enabled) absl::StrAppend(&enabled_tracers, flag.first, ", ");
85         found = true;
86         some_trace_was_found = true;
87       }
88     }
89     if (!found) LOG(ERROR) << "Unknown tracer: " << trace_glob;
90   }
91   if (!enabled_tracers.empty()) {
92     absl::string_view enabled_tracers_view(enabled_tracers);
93     absl::ConsumeSuffix(&enabled_tracers_view, ", ");
94     LOG(INFO) << "gRPC Tracers: " << enabled_tracers_view;
95   }
96   return some_trace_was_found;
97 }
98 
99 }  // namespace grpc_core
100 
grpc_tracer_init()101 void grpc_tracer_init() {
102   grpc_core::ParseTracers(grpc_core::ConfigVars::Get().Trace());
103 }
104 
grpc_tracer_set_enabled(const char * name,int enabled)105 int grpc_tracer_set_enabled(const char* name, int enabled) {
106   if (enabled != 0) return grpc_core::ParseTracers(name);
107   return grpc_core::ParseTracers(absl::StrCat("-", name));
108 }
109