aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/core/lib/channel
diff options
context:
space:
mode:
authorGravatar ncteisen <ncteisen@gmail.com>2018-07-18 07:38:15 -0700
committerGravatar ncteisen <ncteisen@gmail.com>2018-07-18 07:45:59 -0700
commitf87b9551c232fcc986ede271f496d3812c2b7b80 (patch)
tree5dc46d3492af5e4630ea32ec8ac7a6f9337ece99 /src/core/lib/channel
parent5d373c40bdd616d2d0e65b1c6936cc2d07ba4044 (diff)
parenta9f3d78c6ef4897816f696366814967fd5db2ad6 (diff)
Merge branch 'master' of https://github.com/grpc/grpc into channelz-get-top-channels
Diffstat (limited to 'src/core/lib/channel')
-rw-r--r--src/core/lib/channel/channel_trace.cc44
-rw-r--r--src/core/lib/channel/channelz.cc77
-rw-r--r--src/core/lib/channel/channelz.h20
-rw-r--r--src/core/lib/channel/channelz_registry.h17
4 files changed, 65 insertions, 93 deletions
diff --git a/src/core/lib/channel/channel_trace.cc b/src/core/lib/channel/channel_trace.cc
index 5a4cf8c7e1..b3443310ac 100644
--- a/src/core/lib/channel/channel_trace.cc
+++ b/src/core/lib/channel/channel_trace.cc
@@ -131,38 +131,6 @@ void ChannelTrace::AddTraceEventReferencingSubchannel(
namespace {
-// returns an allocated string that represents tm according to RFC-3339, and,
-// more specifically, follows:
-// https://developers.google.com/protocol-buffers/docs/proto3#json
-//
-// "Uses RFC 3339, where generated output will always be Z-normalized and uses
-// 0, 3, 6 or 9 fractional digits."
-char* fmt_time(gpr_timespec tm) {
- char time_buffer[35];
- char ns_buffer[11]; // '.' + 9 digits of precision
- struct tm* tm_info = localtime((const time_t*)&tm.tv_sec);
- strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%dT%H:%M:%S", tm_info);
- snprintf(ns_buffer, 11, ".%09d", tm.tv_nsec);
- // This loop trims off trailing zeros by inserting a null character that the
- // right point. We iterate in chunks of three because we want 0, 3, 6, or 9
- // fractional digits.
- for (int i = 7; i >= 1; i -= 3) {
- if (ns_buffer[i] == '0' && ns_buffer[i + 1] == '0' &&
- ns_buffer[i + 2] == '0') {
- ns_buffer[i] = '\0';
- // Edge case in which all fractional digits were 0.
- if (i == 1) {
- ns_buffer[0] = '\0';
- }
- } else {
- break;
- }
- }
- char* full_time_str;
- gpr_asprintf(&full_time_str, "%s%sZ", time_buffer, ns_buffer);
- return full_time_str;
-}
-
const char* severity_string(ChannelTrace::Severity severity) {
switch (severity) {
case ChannelTrace::Severity::Info:
@@ -186,9 +154,9 @@ void ChannelTrace::TraceEvent::RenderTraceEvent(grpc_json* json) const {
json_iterator = grpc_json_create_child(json_iterator, json, "severity",
severity_string(severity_),
GRPC_JSON_STRING, false);
- json_iterator =
- grpc_json_create_child(json_iterator, json, "timestamp",
- fmt_time(timestamp_), GRPC_JSON_STRING, true);
+ json_iterator = grpc_json_create_child(json_iterator, json, "timestamp",
+ gpr_format_timespec(timestamp_),
+ GRPC_JSON_STRING, true);
if (referenced_channel_ != nullptr) {
char* uuid_str;
gpr_asprintf(&uuid_str, "%" PRIdPTR, referenced_channel_->channel_uuid());
@@ -216,9 +184,9 @@ grpc_json* ChannelTrace::RenderJson() const {
json_iterator =
grpc_json_create_child(json_iterator, json, "numEventsLogged",
num_events_logged_str, GRPC_JSON_STRING, true);
- json_iterator =
- grpc_json_create_child(json_iterator, json, "creationTimestamp",
- fmt_time(time_created_), GRPC_JSON_STRING, true);
+ json_iterator = grpc_json_create_child(
+ json_iterator, json, "creationTimestamp",
+ gpr_format_timespec(time_created_), GRPC_JSON_STRING, true);
grpc_json* events = grpc_json_create_child(json_iterator, json, "events",
nullptr, GRPC_JSON_ARRAY, false);
json_iterator = nullptr;
diff --git a/src/core/lib/channel/channelz.cc b/src/core/lib/channel/channelz.cc
index c78ea99e63..df85b89ad0 100644
--- a/src/core/lib/channel/channelz.cc
+++ b/src/core/lib/channel/channelz.cc
@@ -41,53 +41,6 @@
namespace grpc_core {
namespace channelz {
-namespace {
-
-// TODO(ncteisen): move this function to a common helper location.
-//
-// returns an allocated string that represents tm according to RFC-3339, and,
-// more specifically, follows:
-// https://developers.google.com/protocol-buffers/docs/proto3#json
-//
-// "Uses RFC 3339, where generated output will always be Z-normalized and uses
-// 0, 3, 6 or 9 fractional digits."
-char* fmt_time(gpr_timespec tm) {
- char time_buffer[35];
- char ns_buffer[11]; // '.' + 9 digits of precision
- struct tm* tm_info = localtime((const time_t*)&tm.tv_sec);
- strftime(time_buffer, sizeof(time_buffer), "%Y-%m-%dT%H:%M:%S", tm_info);
- snprintf(ns_buffer, 11, ".%09d", tm.tv_nsec);
- // This loop trims off trailing zeros by inserting a null character that the
- // right point. We iterate in chunks of three because we want 0, 3, 6, or 9
- // fractional digits.
- for (int i = 7; i >= 1; i -= 3) {
- if (ns_buffer[i] == '0' && ns_buffer[i + 1] == '0' &&
- ns_buffer[i + 2] == '0') {
- ns_buffer[i] = '\0';
- // Edge case in which all fractional digits were 0.
- if (i == 1) {
- ns_buffer[0] = '\0';
- }
- } else {
- break;
- }
- }
- char* full_time_str;
- gpr_asprintf(&full_time_str, "%s%sZ", time_buffer, ns_buffer);
- return full_time_str;
-}
-
-// TODO(ncteisen); move this to json library
-grpc_json* add_num_str(grpc_json* parent, grpc_json* it, const char* name,
- int64_t num) {
- char* num_str;
- gpr_asprintf(&num_str, "%" PRId64, num);
- return grpc_json_create_child(it, parent, name, num_str, GRPC_JSON_STRING,
- true);
-}
-
-} // namespace
-
ChannelNode::ChannelNode(grpc_channel* channel, size_t channel_tracer_max_nodes,
bool is_top_level_channel)
: channel_(channel),
@@ -114,6 +67,8 @@ void ChannelNode::RecordCallStarted() {
void ChannelNode::PopulateConnectivityState(grpc_json* json) {}
+void ChannelNode::PopulateChildRefs(grpc_json* json) {}
+
grpc_json* ChannelNode::RenderJson() {
// We need to track these three json objects to build our object
grpc_json* top_level_json = grpc_json_create(GRPC_JSON_OBJECT);
@@ -124,7 +79,8 @@ grpc_json* ChannelNode::RenderJson() {
GRPC_JSON_OBJECT, false);
json = json_iterator;
json_iterator = nullptr;
- json_iterator = add_num_str(json, json_iterator, "channelId", channel_uuid_);
+ json_iterator = grpc_json_add_number_string_child(json, json_iterator,
+ "channelId", channel_uuid_);
// reset json iterators to top level object
json = top_level_json;
json_iterator = nullptr;
@@ -152,22 +108,25 @@ grpc_json* ChannelNode::RenderJson() {
json = data;
json_iterator = nullptr;
if (calls_started_ != 0) {
- json_iterator =
- add_num_str(json, json_iterator, "callsStarted", calls_started_);
+ json_iterator = grpc_json_add_number_string_child(
+ json, json_iterator, "callsStarted", calls_started_);
}
if (calls_succeeded_ != 0) {
- json_iterator =
- add_num_str(json, json_iterator, "callsSucceeded", calls_succeeded_);
+ json_iterator = grpc_json_add_number_string_child(
+ json, json_iterator, "callsSucceeded", calls_succeeded_);
}
if (calls_failed_) {
- json_iterator =
- add_num_str(json, json_iterator, "callsFailed", calls_failed_);
+ json_iterator = grpc_json_add_number_string_child(
+ json, json_iterator, "callsFailed", calls_failed_);
}
gpr_timespec ts =
grpc_millis_to_timespec(last_call_started_millis_, GPR_CLOCK_REALTIME);
json_iterator =
grpc_json_create_child(json_iterator, json, "lastCallStartedTimestamp",
- fmt_time(ts), GRPC_JSON_STRING, true);
+ gpr_format_timespec(ts), GRPC_JSON_STRING, true);
+ json = top_level_json;
+ json_iterator = nullptr;
+ PopulateChildRefs(json);
return top_level_json;
}
@@ -185,5 +144,13 @@ RefCountedPtr<ChannelNode> ChannelNode::MakeChannelNode(
channel, channel_tracer_max_nodes, is_top_level_channel);
}
+SubchannelNode::SubchannelNode() {
+ subchannel_uuid_ = ChannelzRegistry::RegisterSubchannelNode(this);
+}
+
+SubchannelNode::~SubchannelNode() {
+ ChannelzRegistry::UnregisterSubchannelNode(subchannel_uuid_);
+}
+
} // namespace channelz
} // namespace grpc_core
diff --git a/src/core/lib/channel/channelz.h b/src/core/lib/channel/channelz.h
index 4794a280d0..07eb73d626 100644
--- a/src/core/lib/channel/channelz.h
+++ b/src/core/lib/channel/channelz.h
@@ -68,6 +68,8 @@ class ChannelNode : public RefCounted<ChannelNode> {
// instead of lib/
virtual void PopulateConnectivityState(grpc_json* json);
+ virtual void PopulateChildRefs(grpc_json* json);
+
ChannelTrace* trace() { return trace_.get(); }
void MarkChannelDestroyed() {
@@ -102,6 +104,24 @@ class ChannelNode : public RefCounted<ChannelNode> {
ManualConstructor<ChannelTrace> trace_;
};
+// Placeholds channelz class for subchannels. All this can do now is track its
+// uuid (this information is needed by the parent channelz class).
+// TODO(ncteisen): build this out to support the GetSubchannel channelz request.
+class SubchannelNode : public RefCounted<SubchannelNode> {
+ public:
+ SubchannelNode();
+ virtual ~SubchannelNode();
+
+ intptr_t subchannel_uuid() { return subchannel_uuid_; }
+
+ protected:
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_DELETE
+ GPRC_ALLOW_CLASS_TO_USE_NON_PUBLIC_NEW
+
+ private:
+ intptr_t subchannel_uuid_;
+};
+
// Creation functions
typedef RefCountedPtr<ChannelNode> (*ChannelNodeCreationFunc)(grpc_channel*,
diff --git a/src/core/lib/channel/channelz_registry.h b/src/core/lib/channel/channelz_registry.h
index c378467f34..5d7c936726 100644
--- a/src/core/lib/channel/channelz_registry.h
+++ b/src/core/lib/channel/channelz_registry.h
@@ -22,6 +22,7 @@
#include <grpc/impl/codegen/port_platform.h>
#include "src/core/lib/channel/channel_trace.h"
+#include "src/core/lib/channel/channelz.h"
#include "src/core/lib/gprpp/inlined_vector.h"
#include <stdint.h>
@@ -39,6 +40,7 @@ class ChannelzRegistry {
// To be called in grpc_shutdown();
static void Shutdown();
+ // Register/Unregister/Get for ChannelNode
static intptr_t RegisterChannelNode(ChannelNode* channel_node) {
RegistryEntry entry(channel_node, EntityType::kChannelNode);
return Default()->InternalRegisterEntry(entry);
@@ -51,6 +53,20 @@ class ChannelzRegistry {
return gotten == nullptr ? nullptr : static_cast<ChannelNode*>(gotten);
}
+ // Register/Unregister/Get for SubchannelNode
+ static intptr_t RegisterSubchannelNode(SubchannelNode* channel_node) {
+ RegistryEntry entry(channel_node, EntityType::kSubchannelNode);
+ return Default()->InternalRegisterEntry(entry);
+ }
+ static void UnregisterSubchannelNode(intptr_t uuid) {
+ Default()->InternalUnregisterEntry(uuid, EntityType::kSubchannelNode);
+ }
+ static SubchannelNode* GetSubchannelNode(intptr_t uuid) {
+ void* gotten =
+ Default()->InternalGetEntry(uuid, EntityType::kSubchannelNode);
+ return gotten == nullptr ? nullptr : static_cast<SubchannelNode*>(gotten);
+ }
+
// Returns the allocated JSON string that represents the proto
// GetTopChannelsResponse as per channelz.proto.
static char* GetTopChannels(intptr_t start_channel_id) {
@@ -60,6 +76,7 @@ class ChannelzRegistry {
private:
enum class EntityType {
kChannelNode,
+ kSubchannelNode,
kUnset,
};