1 // 2 // 3 // Copyright 2017 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 #ifndef GRPC_SRC_CORE_CHANNELZ_CHANNEL_TRACE_H 20 #define GRPC_SRC_CORE_CHANNELZ_CHANNEL_TRACE_H 21 22 #include <grpc/slice.h> 23 #include <grpc/support/port_platform.h> 24 #include <grpc/support/time.h> 25 #include <stddef.h> 26 #include <stdint.h> 27 28 #include "absl/base/thread_annotations.h" 29 #include "src/core/util/json/json.h" 30 #include "src/core/util/ref_counted_ptr.h" 31 #include "src/core/util/sync.h" 32 33 namespace grpc_core { 34 namespace channelz { 35 36 namespace testing { 37 size_t GetSizeofTraceEvent(void); 38 } 39 40 class BaseNode; 41 42 // Object used to hold live data for a channel. This data is exposed via the 43 // channelz service: 44 // https://github.com/grpc/proposal/blob/master/A14-channelz.md 45 class ChannelTrace { 46 public: 47 explicit ChannelTrace(size_t max_event_memory); 48 ~ChannelTrace(); 49 50 enum Severity { 51 Unset = 0, // never to be used 52 Info, // we start at 1 to avoid using proto default values 53 Warning, 54 Error 55 }; 56 57 // Adds a new trace event to the tracing object 58 // 59 // NOTE: each ChannelTrace tracks the memory used by its list of trace 60 // events, so adding an event with a large amount of data could cause other 61 // trace event to be evicted. If a single trace is larger than the limit, it 62 // will cause all events to be evicted. The limit is set with the arg: 63 // GRPC_ARG_MAX_CHANNEL_TRACE_EVENT_MEMORY_PER_NODE. 64 // 65 // TODO(ncteisen): as this call is used more and more throughout the gRPC 66 // stack, determine if it makes more sense to accept a char* instead of a 67 // slice. 68 void AddTraceEvent(Severity severity, const grpc_slice& data); 69 70 // Adds a new trace event to the tracing object. This trace event refers to a 71 // an event that concerns a different channelz entity. For example, if this 72 // channel has created a new subchannel, then it would record that with 73 // a TraceEvent referencing the new subchannel. 74 // 75 // NOTE: see the note in the method above. 76 // 77 // TODO(ncteisen): see the todo in the method above. 78 void AddTraceEventWithReference(Severity severity, const grpc_slice& data, 79 RefCountedPtr<BaseNode> referenced_entity); 80 81 // Creates and returns the raw Json object, so a parent channelz 82 // object may incorporate the json before rendering. 83 Json RenderJson() const; 84 85 private: 86 friend size_t testing::GetSizeofTraceEvent(void); 87 88 // Private class to encapsulate all the data and bookkeeping needed for a 89 // a trace event. 90 class TraceEvent { 91 public: 92 // Constructor for a TraceEvent that references a channel. 93 TraceEvent(Severity severity, const grpc_slice& data, 94 RefCountedPtr<BaseNode> referenced_entity_); 95 96 // Constructor for a TraceEvent that does not reverence a different 97 // channel. 98 TraceEvent(Severity severity, const grpc_slice& data); 99 100 ~TraceEvent(); 101 102 // Renders the data inside of this TraceEvent into a json object. This is 103 // used by the ChannelTrace, when it is rendering itself. 104 Json RenderTraceEvent() const; 105 106 // set and get for the next_ pointer. next()107 TraceEvent* next() const { return next_; } set_next(TraceEvent * next)108 void set_next(TraceEvent* next) { next_ = next; } 109 memory_usage()110 size_t memory_usage() const { return memory_usage_; } 111 112 private: 113 const gpr_timespec timestamp_; 114 const Severity severity_; 115 const grpc_slice data_; 116 const size_t memory_usage_; 117 // the tracer object for the (sub)channel that this trace event refers to. 118 const RefCountedPtr<BaseNode> referenced_entity_; 119 TraceEvent* next_ = nullptr; 120 }; // TraceEvent 121 122 // Internal helper to add and link in a trace event 123 void AddTraceEventHelper(TraceEvent* new_trace_event); 124 125 const size_t max_event_memory_; 126 const gpr_timespec time_created_; 127 128 mutable Mutex mu_; 129 uint64_t num_events_logged_ ABSL_GUARDED_BY(mu_) = 0; 130 size_t event_list_memory_usage_ ABSL_GUARDED_BY(mu_) = 0; 131 TraceEvent* head_trace_ ABSL_GUARDED_BY(mu_) = nullptr; 132 TraceEvent* tail_trace_ ABSL_GUARDED_BY(mu_) = nullptr; 133 }; 134 135 } // namespace channelz 136 } // namespace grpc_core 137 138 #endif // GRPC_SRC_CORE_CHANNELZ_CHANNEL_TRACE_H 139