blob: df85b89ad0c5a86b531012d52fc4358ec7c1c3a3 [file] [log] [blame]
ncteisenc3c6e062018-05-09 11:10:21 -07001/*
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#include <grpc/impl/codegen/port_platform.h>
20
21#include "src/core/lib/channel/channelz.h"
22
23#include <grpc/grpc.h>
24#include <grpc/support/alloc.h>
25#include <grpc/support/log.h>
26#include <grpc/support/string_util.h>
27#include <stdio.h>
28#include <stdlib.h>
29#include <string.h>
30
31#include "src/core/lib/channel/channelz_registry.h"
32#include "src/core/lib/channel/status_util.h"
33#include "src/core/lib/gpr/string.h"
34#include "src/core/lib/gpr/useful.h"
35#include "src/core/lib/gprpp/memory.h"
36#include "src/core/lib/iomgr/error.h"
37#include "src/core/lib/slice/slice_internal.h"
38#include "src/core/lib/surface/channel.h"
ncteisenc3c6e062018-05-09 11:10:21 -070039#include "src/core/lib/transport/error_utils.h"
40
ncteisenc3c6e062018-05-09 11:10:21 -070041namespace grpc_core {
42namespace channelz {
43
ncteisen5d373c42018-07-17 11:57:31 -070044ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
45 bool is_top_level_channel)
46 : channel_(channel),
47 target_(nullptr),
48 channel_uuid_(-1),
49 is_top_level_channel_(is_top_level_channel) {
ncteisen23c50fd2018-05-18 16:38:29 -070050 trace_.Init(channel_tracer_max_nodes);
ncteisenc7166ae2018-06-15 11:04:37 -040051 target_ = UniquePtr<char>(grpc_channel_get_target(channel_));
ncteisen9a6c7222018-07-13 12:09:55 -070052 channel_uuid_ = ChannelzRegistry::RegisterChannelNode(this);
Noah Eisenea424b82018-06-07 13:02:48 -070053 gpr_atm_no_barrier_store(&last_call_started_millis_,
54 (gpr_atm)ExecCtx::Get()->Now());
ncteisenc3c6e062018-05-09 11:10:21 -070055}
56
ncteisen6c987cb2018-06-08 09:30:12 -070057ChannelNode::~ChannelNode() {
ncteisen9a1bb052018-05-30 16:17:06 -070058 trace_.Destroy();
ncteisen9a6c7222018-07-13 12:09:55 -070059 ChannelzRegistry::UnregisterChannelNode(channel_uuid_);
ncteisenc3c6e062018-05-09 11:10:21 -070060}
61
ncteisen6c987cb2018-06-08 09:30:12 -070062void ChannelNode::RecordCallStarted() {
ncteisena8717042018-06-05 08:26:34 -070063 gpr_atm_no_barrier_fetch_add(&calls_started_, (gpr_atm)1);
Noah Eisenea424b82018-06-07 13:02:48 -070064 gpr_atm_no_barrier_store(&last_call_started_millis_,
65 (gpr_atm)ExecCtx::Get()->Now());
ncteisenc3c6e062018-05-09 11:10:21 -070066}
67
ncteisen23003512018-06-29 12:00:15 -070068void ChannelNode::PopulateConnectivityState(grpc_json* json) {}
ncteisenc3c6e062018-05-09 11:10:21 -070069
ncteisen018498a2018-06-29 14:48:05 -070070void ChannelNode::PopulateChildRefs(grpc_json* json) {}
71
ncteisen97066fd2018-07-13 14:05:27 -070072grpc_json* ChannelNode::RenderJson() {
ncteisenc3c6e062018-05-09 11:10:21 -070073 // We need to track these three json objects to build our object
74 grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
75 grpc_json* json = top_level_json;
76 grpc_json* json_iterator = nullptr;
ncteisenc3c6e062018-05-09 11:10:21 -070077 // create and fill the ref child
78 json_iterator = grpc_json_create_child(json_iterator, json, "ref", nullptr,
ncteisen9a1bb052018-05-30 16:17:06 -070079 GRPC_JSON_OBJECT, false);
ncteisenc3c6e062018-05-09 11:10:21 -070080 json = json_iterator;
81 json_iterator = nullptr;
ncteisen018498a2018-06-29 14:48:05 -070082 json_iterator = grpc_json_add_number_string_child(json, json_iterator,
83 "channelId", channel_uuid_);
ncteisenc3c6e062018-05-09 11:10:21 -070084 // reset json iterators to top level object
85 json = top_level_json;
86 json_iterator = nullptr;
ncteisen9a1bb052018-05-30 16:17:06 -070087 // create and fill the data child.
88 grpc_json* data = grpc_json_create_child(json_iterator, json, "data", nullptr,
89 GRPC_JSON_OBJECT, false);
ncteisen9a1bb052018-05-30 16:17:06 -070090 json = data;
ncteisenc3c6e062018-05-09 11:10:21 -070091 json_iterator = nullptr;
ncteisen23003512018-06-29 12:00:15 -070092 PopulateConnectivityState(json);
ncteisen97066fd2018-07-13 14:05:27 -070093 GPR_ASSERT(target_.get() != nullptr);
Noah Eisenea424b82018-06-07 13:02:48 -070094 json_iterator = grpc_json_create_child(
95 json_iterator, json, "target", target_.get(), GRPC_JSON_STRING, false);
ncteisen9a1bb052018-05-30 16:17:06 -070096 // fill in the channel trace if applicable
ncteisen97066fd2018-07-13 14:05:27 -070097 grpc_json* trace = trace_->RenderJson();
ncteisen9a1bb052018-05-30 16:17:06 -070098 if (trace != nullptr) {
ncteisen5d373c42018-07-17 11:57:31 -070099 // we manually link up and fill the child since it was created for us in
ncteisen97066fd2018-07-13 14:05:27 -0700100 // ChannelTrace::RenderJson
ncteisen9a1bb052018-05-30 16:17:06 -0700101 json_iterator = grpc_json_link_child(json, trace, json_iterator);
102 trace->parent = json;
103 trace->value = nullptr;
104 trace->key = "trace";
105 trace->owns_value = false;
106 }
ncteisen9a1bb052018-05-30 16:17:06 -0700107 // reset the parent to be the data object.
108 json = data;
109 json_iterator = nullptr;
ncteisen97066fd2018-07-13 14:05:27 -0700110 if (calls_started_ != 0) {
ncteisenf87b9552018-07-18 07:38:15 -0700111 json_iterator = grpc_json_add_number_string_child(
112 json, json_iterator, "callsStarted", calls_started_);
ncteisen97066fd2018-07-13 14:05:27 -0700113 }
114 if (calls_succeeded_ != 0) {
ncteisenf87b9552018-07-18 07:38:15 -0700115 json_iterator = grpc_json_add_number_string_child(
116 json, json_iterator, "callsSucceeded", calls_succeeded_);
ncteisen97066fd2018-07-13 14:05:27 -0700117 }
118 if (calls_failed_) {
ncteisenf87b9552018-07-18 07:38:15 -0700119 json_iterator = grpc_json_add_number_string_child(
120 json, json_iterator, "callsFailed", calls_failed_);
ncteisen97066fd2018-07-13 14:05:27 -0700121 }
Noah Eisenea424b82018-06-07 13:02:48 -0700122 gpr_timespec ts =
123 grpc_millis_to_timespec(last_call_started_millis_, GPR_CLOCK_REALTIME);
124 json_iterator =
125 grpc_json_create_child(json_iterator, json, "lastCallStartedTimestamp",
ncteisen018498a2018-06-29 14:48:05 -0700126 gpr_format_timespec(ts), GRPC_JSON_STRING, true);
ncteisen018498a2018-06-29 14:48:05 -0700127 json = top_level_json;
128 json_iterator = nullptr;
129 PopulateChildRefs(json);
ncteisen97066fd2018-07-13 14:05:27 -0700130 return top_level_json;
131}
132
133char* ChannelNode::RenderJsonString() {
134 grpc_json* json = RenderJson();
135 char* json_str = grpc_json_dump_to_string(json, 0);
136 grpc_json_destroy(json);
ncteisenc3c6e062018-05-09 11:10:21 -0700137 return json_str;
138}
139
ncteisencaa85b22018-07-03 11:25:41 -0700140RefCountedPtr<ChannelNode> ChannelNode::MakeChannelNode(
ncteisen5d373c42018-07-17 11:57:31 -0700141 grpc_channel* channel, size_t channel_tracer_max_nodes,
142 bool is_top_level_channel) {
ncteisenafb98292018-06-28 18:04:24 -0700143 return MakeRefCounted<grpc_core::channelz::ChannelNode>(
ncteisen5d373c42018-07-17 11:57:31 -0700144 channel, channel_tracer_max_nodes, is_top_level_channel);
ncteisenafb98292018-06-28 18:04:24 -0700145}
146
ncteisen0f6e4dd2018-07-17 11:26:55 -0700147SubchannelNode::SubchannelNode() {
ncteisenf87b9552018-07-18 07:38:15 -0700148 subchannel_uuid_ = ChannelzRegistry::RegisterSubchannelNode(this);
ncteisen1e6c0b42018-07-13 11:22:08 -0700149}
150
151SubchannelNode::~SubchannelNode() {
ncteisenf87b9552018-07-18 07:38:15 -0700152 ChannelzRegistry::UnregisterSubchannelNode(subchannel_uuid_);
ncteisen1e6c0b42018-07-13 11:22:08 -0700153}
154
ncteisenc3c6e062018-05-09 11:10:21 -0700155} // namespace channelz
156} // namespace grpc_core