• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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