1 /*
2 *
3 * Copyright 2018 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 <grpc/support/port_platform.h>
20
21 #include "src/core/ext/filters/client_channel/client_channel.h"
22 #include "src/core/ext/filters/client_channel/client_channel_channelz.h"
23 #include "src/core/lib/channel/channelz_registry.h"
24 #include "src/core/lib/gpr/useful.h"
25 #include "src/core/lib/surface/channel.h"
26 #include "src/core/lib/transport/connectivity_state.h"
27
28 #include <grpc/support/string_util.h>
29
30 namespace grpc_core {
31 namespace channelz {
32
SubchannelNode(std::string target_address,size_t channel_tracer_max_nodes)33 SubchannelNode::SubchannelNode(std::string target_address,
34 size_t channel_tracer_max_nodes)
35 : BaseNode(EntityType::kSubchannel, target_address),
36 target_(std::move(target_address)),
37 trace_(channel_tracer_max_nodes) {}
38
~SubchannelNode()39 SubchannelNode::~SubchannelNode() {}
40
UpdateConnectivityState(grpc_connectivity_state state)41 void SubchannelNode::UpdateConnectivityState(grpc_connectivity_state state) {
42 connectivity_state_.Store(state, MemoryOrder::RELAXED);
43 }
44
SetChildSocket(RefCountedPtr<SocketNode> socket)45 void SubchannelNode::SetChildSocket(RefCountedPtr<SocketNode> socket) {
46 MutexLock lock(&socket_mu_);
47 child_socket_ = std::move(socket);
48 }
49
RenderJson()50 Json SubchannelNode::RenderJson() {
51 // Create and fill the data child.
52 grpc_connectivity_state state =
53 connectivity_state_.Load(MemoryOrder::RELAXED);
54 Json::Object data = {
55 {"state",
56 Json::Object{
57 {"state", ConnectivityStateName(state)},
58 }},
59 {"target", target_},
60 };
61
62 // Fill in the channel trace if applicable
63 Json trace_json = trace_.RenderJson();
64 if (trace_json.type() != Json::Type::JSON_NULL) {
65 data["trace"] = std::move(trace_json);
66 }
67 // Ask CallCountingHelper to populate call count data.
68 call_counter_.PopulateCallCounts(&data);
69 // Construct top-level object.
70 Json::Object object{
71 {"ref",
72 Json::Object{
73 {"subchannelId", std::to_string(uuid())},
74 }},
75 {"data", std::move(data)},
76 };
77 // Populate the child socket.
78 RefCountedPtr<SocketNode> child_socket;
79 {
80 MutexLock lock(&socket_mu_);
81 child_socket = child_socket_;
82 }
83 if (child_socket != nullptr && child_socket->uuid() != 0) {
84 object["socketRef"] = Json::Array{
85 Json::Object{
86 {"socketId", std::to_string(child_socket->uuid())},
87 {"name", child_socket->name()},
88 },
89 };
90 }
91 return object;
92 }
93
94 } // namespace channelz
95 } // namespace grpc_core
96