diff options
author | 2018-07-18 07:38:15 -0700 | |
---|---|---|
committer | 2018-07-18 07:45:59 -0700 | |
commit | f87b9551c232fcc986ede271f496d3812c2b7b80 (patch) | |
tree | 5dc46d3492af5e4630ea32ec8ac7a6f9337ece99 /src/core/lib/channel | |
parent | 5d373c40bdd616d2d0e65b1c6936cc2d07ba4044 (diff) | |
parent | a9f3d78c6ef4897816f696366814967fd5db2ad6 (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.cc | 44 | ||||
-rw-r--r-- | src/core/lib/channel/channelz.cc | 77 | ||||
-rw-r--r-- | src/core/lib/channel/channelz.h | 20 | ||||
-rw-r--r-- | src/core/lib/channel/channelz_registry.h | 17 |
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, }; |