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_CORE_LIB_CHANNEL_CHANNEL_TRACE_H
20 #define GRPC_CORE_LIB_CHANNEL_CHANNEL_TRACE_H
21 
22 #include <grpc/impl/codegen/port_platform.h>
23 
24 #include <grpc/grpc.h>
25 #include "src/core/lib/gprpp/ref_counted.h"
26 #include "src/core/lib/gprpp/ref_counted_ptr.h"
27 #include "src/core/lib/iomgr/error.h"
28 #include "src/core/lib/json/json.h"
29 
30 namespace grpc_core {
31 namespace channelz {
32 
33 class BaseNode;
34 
35 // Object used to hold live data for a channel. This data is exposed via the
36 // channelz service:
37 // https://github.com/grpc/proposal/blob/master/A14-channelz.md
38 class ChannelTrace {
39  public:
40   ChannelTrace(size_t max_events);
41   ~ChannelTrace();
42 
43   enum Severity {
44     Unset = 0,  // never to be used
45     Info,       // we start at 1 to avoid using proto default values
46     Warning,
47     Error
48   };
49 
50   // Adds a new trace event to the tracing object
51   //
52   // TODO(ncteisen): as this call is used more and more throughout the gRPC
53   // stack, determine if it makes more sense to accept a char* instead of a
54   // slice.
55   void AddTraceEvent(Severity severity, grpc_slice data);
56 
57   // Adds a new trace event to the tracing object. This trace event refers to a
58   // an event that concerns a different channelz entity. For example, if this
59   // channel has created a new subchannel, then it would record that with
60   // a TraceEvent referencing the new subchannel.
61   //
62   // TODO(ncteisen): as this call is used more and more throughout the gRPC
63   // stack, determine if it makes more sense to accept a char* instead of a
64   // slice.
65   void AddTraceEventWithReference(Severity severity, grpc_slice data,
66                                   RefCountedPtr<BaseNode> referenced_entity);
67 
68   // Creates and returns the raw grpc_json object, so a parent channelz
69   // object may incorporate the json before rendering.
70   grpc_json* RenderJson() const;
71 
72  private:
73   // Private class to encapsulate all the data and bookkeeping needed for a
74   // a trace event.
75   class TraceEvent {
76    public:
77     // Constructor for a TraceEvent that references a channel.
78     TraceEvent(Severity severity, grpc_slice data,
79                RefCountedPtr<BaseNode> referenced_entity_);
80 
81     // Constructor for a TraceEvent that does not reverence a different
82     // channel.
83     TraceEvent(Severity severity, grpc_slice data);
84 
85     ~TraceEvent();
86 
87     // Renders the data inside of this TraceEvent into a json object. This is
88     // used by the ChannelTrace, when it is rendering itself.
89     void RenderTraceEvent(grpc_json* json) const;
90 
91     // set and get for the next_ pointer.
next()92     TraceEvent* next() const { return next_; }
set_next(TraceEvent * next)93     void set_next(TraceEvent* next) { next_ = next; }
94 
95    private:
96     Severity severity_;
97     grpc_slice data_;
98     gpr_timespec timestamp_;
99     TraceEvent* next_;
100     // the tracer object for the (sub)channel that this trace event refers to.
101     RefCountedPtr<BaseNode> referenced_entity_;
102   };  // TraceEvent
103 
104   // Internal helper to add and link in a trace event
105   void AddTraceEventHelper(TraceEvent* new_trace_event);
106 
107   gpr_mu tracer_mu_;
108   uint64_t num_events_logged_;
109   size_t list_size_;
110   size_t max_list_size_;
111   TraceEvent* head_trace_;
112   TraceEvent* tail_trace_;
113   gpr_timespec time_created_;
114 };
115 
116 }  // namespace channelz
117 }  // namespace grpc_core
118 
119 #endif /* GRPC_CORE_LIB_CHANNEL_CHANNEL_TRACE_H */
120