diff options
Diffstat (limited to 'src/core/lib/transport/transport_op_string.cc')
-rw-r--r-- | src/core/lib/transport/transport_op_string.cc | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/core/lib/transport/transport_op_string.cc b/src/core/lib/transport/transport_op_string.cc new file mode 100644 index 0000000000..cc11b0cc49 --- /dev/null +++ b/src/core/lib/transport/transport_op_string.cc @@ -0,0 +1,208 @@ +/* + * + * Copyright 2015 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include <grpc/support/port_platform.h> + +#include "src/core/lib/channel/channel_stack.h" + +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> +#include <string.h> + +#include <grpc/support/alloc.h> +#include <grpc/support/string_util.h> +#include <grpc/support/useful.h> +#include "src/core/lib/slice/slice_string_helpers.h" +#include "src/core/lib/support/string.h" +#include "src/core/lib/transport/connectivity_state.h" + +/* These routines are here to facilitate debugging - they produce string + representations of various transport data structures */ + +static void put_metadata(gpr_strvec *b, grpc_mdelem md) { + gpr_strvec_add(b, gpr_strdup("key=")); + gpr_strvec_add( + b, grpc_dump_slice(GRPC_MDKEY(md), GPR_DUMP_HEX | GPR_DUMP_ASCII)); + + gpr_strvec_add(b, gpr_strdup(" value=")); + gpr_strvec_add( + b, grpc_dump_slice(GRPC_MDVALUE(md), GPR_DUMP_HEX | GPR_DUMP_ASCII)); +} + +static void put_metadata_list(gpr_strvec *b, grpc_metadata_batch md) { + grpc_linked_mdelem *m; + for (m = md.list.head; m != NULL; m = m->next) { + if (m != md.list.head) gpr_strvec_add(b, gpr_strdup(", ")); + put_metadata(b, m->md); + } + if (md.deadline != GRPC_MILLIS_INF_FUTURE) { + char *tmp; + gpr_asprintf(&tmp, " deadline=%" PRIdPTR, md.deadline); + gpr_strvec_add(b, tmp); + } +} + +char *grpc_transport_stream_op_batch_string( + grpc_transport_stream_op_batch *op) { + char *tmp; + char *out; + + gpr_strvec b; + gpr_strvec_init(&b); + + if (op->send_initial_metadata) { + gpr_strvec_add(&b, gpr_strdup(" ")); + gpr_strvec_add(&b, gpr_strdup("SEND_INITIAL_METADATA{")); + put_metadata_list( + &b, *op->payload->send_initial_metadata.send_initial_metadata); + gpr_strvec_add(&b, gpr_strdup("}")); + } + + if (op->send_message) { + gpr_strvec_add(&b, gpr_strdup(" ")); + gpr_asprintf(&tmp, "SEND_MESSAGE:flags=0x%08x:len=%d", + op->payload->send_message.send_message->flags, + op->payload->send_message.send_message->length); + gpr_strvec_add(&b, tmp); + } + + if (op->send_trailing_metadata) { + gpr_strvec_add(&b, gpr_strdup(" ")); + gpr_strvec_add(&b, gpr_strdup("SEND_TRAILING_METADATA{")); + put_metadata_list( + &b, *op->payload->send_trailing_metadata.send_trailing_metadata); + gpr_strvec_add(&b, gpr_strdup("}")); + } + + if (op->recv_initial_metadata) { + gpr_strvec_add(&b, gpr_strdup(" ")); + gpr_strvec_add(&b, gpr_strdup("RECV_INITIAL_METADATA")); + } + + if (op->recv_message) { + gpr_strvec_add(&b, gpr_strdup(" ")); + gpr_strvec_add(&b, gpr_strdup("RECV_MESSAGE")); + } + + if (op->recv_trailing_metadata) { + gpr_strvec_add(&b, gpr_strdup(" ")); + gpr_strvec_add(&b, gpr_strdup("RECV_TRAILING_METADATA")); + } + + if (op->cancel_stream) { + gpr_strvec_add(&b, gpr_strdup(" ")); + const char *msg = + grpc_error_string(op->payload->cancel_stream.cancel_error); + gpr_asprintf(&tmp, "CANCEL:%s", msg); + + gpr_strvec_add(&b, tmp); + } + + if (op->collect_stats) { + gpr_strvec_add(&b, gpr_strdup(" ")); + gpr_asprintf(&tmp, "COLLECT_STATS:%p", + op->payload->collect_stats.collect_stats); + gpr_strvec_add(&b, tmp); + } + + out = gpr_strvec_flatten(&b, NULL); + gpr_strvec_destroy(&b); + + return out; +} + +char *grpc_transport_op_string(grpc_transport_op *op) { + char *tmp; + char *out; + bool first = true; + + gpr_strvec b; + gpr_strvec_init(&b); + + if (op->on_connectivity_state_change != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = false; + if (op->connectivity_state != NULL) { + gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE:p=%p:from=%s", + op->on_connectivity_state_change, + grpc_connectivity_state_name(*op->connectivity_state)); + gpr_strvec_add(&b, tmp); + } else { + gpr_asprintf(&tmp, "ON_CONNECTIVITY_STATE_CHANGE:p=%p:unsubscribe", + op->on_connectivity_state_change); + gpr_strvec_add(&b, tmp); + } + } + + if (op->disconnect_with_error != GRPC_ERROR_NONE) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = false; + const char *err = grpc_error_string(op->disconnect_with_error); + gpr_asprintf(&tmp, "DISCONNECT:%s", err); + gpr_strvec_add(&b, tmp); + } + + if (op->goaway_error) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = false; + const char *msg = grpc_error_string(op->goaway_error); + gpr_asprintf(&tmp, "SEND_GOAWAY:%s", msg); + + gpr_strvec_add(&b, tmp); + } + + if (op->set_accept_stream) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = false; + gpr_asprintf(&tmp, "SET_ACCEPT_STREAM:%p(%p,...)", op->set_accept_stream_fn, + op->set_accept_stream_user_data); + gpr_strvec_add(&b, tmp); + } + + if (op->bind_pollset != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = false; + gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET")); + } + + if (op->bind_pollset_set != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = false; + gpr_strvec_add(&b, gpr_strdup("BIND_POLLSET_SET")); + } + + if (op->send_ping != NULL) { + if (!first) gpr_strvec_add(&b, gpr_strdup(" ")); + first = false; + gpr_strvec_add(&b, gpr_strdup("SEND_PING")); + } + + out = gpr_strvec_flatten(&b, NULL); + gpr_strvec_destroy(&b); + + return out; +} + +void grpc_call_log_op(const char *file, int line, gpr_log_severity severity, + grpc_call_element *elem, + grpc_transport_stream_op_batch *op) { + char *str = grpc_transport_stream_op_batch_string(op); + gpr_log(file, line, severity, "OP[%s:%p]: %s", elem->filter->name, elem, str); + gpr_free(str); +} |