From 491a9d455f05d26489128bcd60f853300ca95ebf Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Tue, 21 Jul 2015 10:08:37 -0700 Subject: [PATCH 1/9] checkpoint api --- include/grpc/census.h | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/include/grpc/census.h b/include/grpc/census.h index 3fc07affc84..a32da6f364d 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -100,6 +100,27 @@ int census_context_deserialize(const char *buffer, census_context **context); * future census calls will result in undefined behavior. */ void census_context_destroy(census_context *context); +/* Start a new logical tracing "operation". The operation ends when + * census_trace_end_op() is called. */ +void census_trace_start_op(census_context *context); ++ service method start time, + peer ? +sampled ? + + /* End a tracing operation. Must be matched with an earlier + * census_start_op(). + */ + void + census_trace_end_op(census_context *context); ++ status + + /* Insert a trace record into the trace stream. The record consists of an + * arbitrary size buffer, the size of which is provided in 'n'. */ + void + census_trace_print(census_context *context, const char *buffer, size_t n); + +census_active_ops_as_html() + struct or char *query ops + census_sampled_ops_as_html() + #ifdef __cplusplus } #endif From af5002f9ae647f8d82ec3b1cdaef4438cd6d2ad0 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Sun, 26 Jul 2015 15:11:50 -0700 Subject: [PATCH 2/9] initial --- include/grpc/census.h | 174 ++++++++++++++++++++++++++++++++++++------ 1 file changed, 149 insertions(+), 25 deletions(-) diff --git a/include/grpc/census.h b/include/grpc/census.h index a32da6f364d..e2bef9add3b 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -46,11 +46,12 @@ extern "C" { /* Identify census functionality that can be enabled via census_initialize(). */ enum census_functions { - CENSUS_NONE = 0, /* Do not enable census. */ - CENSUS_TRACING = 1, /* Enable census tracing. */ - CENSUS_STATS = 2, /* Enable Census stats collection. */ - CENSUS_CPU = 4, /* Enable Census CPU usage collection. */ - CENSUS_ALL = CENSUS_TRACING | CENSUS_STATS | CENSUS_CPU + CENSUS_NONE = 0, /* Do not enable census. */ + CENSUS_TRACING = 1, /* Enable distributed tracing. */ + CENSUS_STATS = 2, /* Enable stats collection. */ + CENSUS_CPU = 4, /* Enable CPU usage collection. */ + CENSUS_ACTIVE_OPS = 8, /* Trace Active operations. */ + CENSUS_ALL = CENSUS_TRACING | CENSUS_STATS | CENSUS_CPU | CENSUS_ACTIVE_OPS }; /* Shutdown and startup census subsystem. The 'functions' argument should be @@ -100,26 +101,149 @@ int census_context_deserialize(const char *buffer, census_context **context); * future census calls will result in undefined behavior. */ void census_context_destroy(census_context *context); -/* Start a new logical tracing "operation". The operation ends when - * census_trace_end_op() is called. */ -void census_trace_start_op(census_context *context); -+ service method start time, - peer ? +sampled ? - - /* End a tracing operation. Must be matched with an earlier - * census_start_op(). - */ - void - census_trace_end_op(census_context *context); -+ status - - /* Insert a trace record into the trace stream. The record consists of an - * arbitrary size buffer, the size of which is provided in 'n'. */ - void - census_trace_print(census_context *context, const char *buffer, size_t n); - -census_active_ops_as_html() + struct or char *query ops - census_sampled_ops_as_html() +/* Distributed traces can have a number of options. */ +enum census_trace_mask_values { + CENSUS_TRACE_MASK_NONE = 0, /* Default, empty flags */ + CENSUS_TRACE_MASK_IS_SAMPLED = 1, /* RPC tracing enabled for this context. */ +}; + +/** Get the current trace mask associated with this context. The value returned + will be the logical or of census_trace_mask_values values. */ +int census_trace_mask(const census_context *context); + +/* The concept of "operation" is a fundamental concept for Census. An + operation is a logical representation of a action in a RPC-using system. It + is most typically used to represent a single RPC, or a significant sub-part + thereof (e.g. a single logical "read" RPC to a distributed storage system + might do several other actions in parallel, from looking up metadata + indices to making requests of other services - each of these could be a + sub-operation with the larger RPC operation. Census uses operations for the + following: + + CPU accounting: If enabled, census will measure the thread CPU time + consumed between operation start and end times. + + Active operations: Census will maintain information on all currently + active operations. + + Distributed tracing: Each operation serves as a logical trace span. + + Stats collection: Stats are broken down operation (e.g. latency + breakdown for each service/method combination). + + The following functions serve to delineate the start and stop points for + each logical operation. */ +/** + Start a client rpc operation. This function will create a new context. If + the context argument is non-null, then the new context will inherit all + its properties, with the following changes: + - create a new operation ID for the new context, marking it as a child of + the previous operation. + - use the new RPC service/method/peer information for tracing and stats + collection purposes, rather than those from the original context + - if trace_mask is non-zero, update the trace mask entries associated with + the original context. + + If the context argument is NULL, then a new root context is created. This + is particularly important for tracing purposes (the trace spans generated + will be unassociated with any other trace spans, except those + downstream). Whatever it's value, the trace_mask will be used for tracing + operations associated with the new context. + + @param context The base context. Can be NULL. + @param service RPC service name. On some systems, may include other + parts of RPC identification (e.g. host on gRPC systems). + @param method RPC method name + @param peer RPC peer + @param trace_mask An or of census_trace_mask_values values + @param start_time If NULL, the time of function call is used as the + start time for the operation. If non-NULL, then the time should be in the + past, when the operation was deemed to have started. This is used when + the other information used as arguments is not yet available. + + @return A new census context. + */ +census_context *census_start_client_rpc_op(census_context *context, + const char *service, + const char *method, const char *peer, + int trace_mask, + gpr_timespec *start_time); + +/** + Indicate the start of a server rpc operation, updating the current + context (which should have been created from census_context_deserialize() + (as passed from the client side of the RPC operation) or census_start_op(). + - if trace_mask is non-zero, update the trace mask entries associated with + the original context. + + @param context The base context. Cannot be NULL. + @param service RPC service name. On some systems, may include other + parts of RPC identification (e.g. host on gRPC systems). + @param method RPC method name + @param peer RPC peer + @param trace_mask An or of census_trace_mask_values values + @param start_time If NULL, the time of function call is used as the + start time for the operation. If non-NULL, then the time should be in the + past, when the operation was deemed to have started. This is used when + the other information used as arguments is not yet available. + */ +void census_start_server_rpc_op(census_context *context, const char *service, + const char *method, const char *peer, + int trace_mask, gpr_timespec *start_time); + +/** + Start a new, non-RPC census operation. In general, this function works very + similarly to census_start_client_rpc_op, with the primary differennce being + the abscence of peer information, and the replacement of service and method + names with the more general family/name. If the context argument is + non-null, then the new context will inherit all its properties, with the + following changes: + - create a new operation ID for the new context, marking it as a child of + the previous operation. + - use the family and name information for tracing and stats collection + purposes, rather than those from the original context + - if trace_mask is non-zero, update the trace mask entries associated with + the original context. + + If the context argument is NULL, then a new root context is created. This + is particularly important for tracing purposes (the trace spans generated + will be unassociated with any other trace spans, except those + downstream). Whatever it's value, the trace_mask will be used for tracing + operations associated with the new context. + + @param context The base context. Can be NULL. + @param family Family name to associate with the trace + @param name Name within family to associated with traces/stats + @param trace_mask An or of census_trace_mask_values values + @param start_time If NULL, the time of function call is used as the + start time for the operation. If non-NULL, then the time should be in the + past, when the operation was deemed to have started. This is used when + the other information used as arguments is not yet available. + + @return A new census context. + */ +census_context *census_start_op(census_context *context, const char *family, + const char *name, int trace_mask, + gpr_timespec *start_time); + +/** End a tracing operation. Must be matched with an earlier + * census_start_*_op*() call. */ +void census_trace_end_op(census_context *context, int status); + +/** Insert a trace record into the trace stream. The record consists of an + * arbitrary size buffer, the size of which is provided in 'n'. */ +void census_trace_print(census_context *context, const char *buffer, size_t n); + +/** Retrieve active ops as a proto. Note that since we don't have proto + manipulation available in the grpc core yet, arguments etc. are left + unspecified for now. */ +void census_get_active_ops_as_proto(/* pointer to proto */); + +/** Retrieve all active trace records as a proto. Note that since we don't + have proto manipulation available in the grpc core yet, arguments etc. are + left unspecified for now. This function will clear existing trace + records. */ +void census_get_trace_as_proto(/* pointer to proto */); #ifdef __cplusplus } From 0383d494c4fd0c97a113359348d5136b641c789f Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Sun, 26 Jul 2015 15:29:00 -0700 Subject: [PATCH 3/9] version 1 --- BUILD | 3 +++ Makefile | 2 ++ build.json | 3 ++- gRPC.podspec | 3 ++- include/grpc/census.h | 4 ++-- tools/doxygen/Doxyfile.core.internal | 1 + tools/run_tests/sources_and_headers.json | 2 ++ vsprojects/grpc/grpc.vcxproj | 2 ++ vsprojects/grpc/grpc.vcxproj.filters | 3 +++ vsprojects/grpc_unsecure/grpc_unsecure.vcxproj | 2 ++ vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters | 3 +++ 11 files changed, 24 insertions(+), 4 deletions(-) diff --git a/BUILD b/BUILD index a19631e6df6..a958922e464 100644 --- a/BUILD +++ b/BUILD @@ -383,6 +383,7 @@ cc_library( "src/core/census/context.c", "src/core/census/initialize.c", "src/core/census/record_stat.c", + "src/core/census/tracing.c", ], hdrs = [ "include/grpc/grpc_security.h", @@ -618,6 +619,7 @@ cc_library( "src/core/census/context.c", "src/core/census/initialize.c", "src/core/census/record_stat.c", + "src/core/census/tracing.c", ], hdrs = [ "include/grpc/byte_buffer.h", @@ -1101,6 +1103,7 @@ objc_library( "src/core/census/context.c", "src/core/census/initialize.c", "src/core/census/record_stat.c", + "src/core/census/tracing.c", ], hdrs = [ "include/grpc/grpc_security.h", diff --git a/Makefile b/Makefile index 996fcfa1fc4..65840bb5910 100644 --- a/Makefile +++ b/Makefile @@ -3615,6 +3615,7 @@ LIBGRPC_SRC = \ src/core/census/context.c \ src/core/census/initialize.c \ src/core/census/record_stat.c \ + src/core/census/tracing.c \ PUBLIC_HEADERS_C += \ include/grpc/grpc_security.h \ @@ -3880,6 +3881,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/census/context.c \ src/core/census/initialize.c \ src/core/census/record_stat.c \ + src/core/census/tracing.c \ PUBLIC_HEADERS_C += \ include/grpc/byte_buffer.h \ diff --git a/build.json b/build.json index dd633070ff9..b053e47ae05 100644 --- a/build.json +++ b/build.json @@ -24,7 +24,8 @@ "src": [ "src/core/census/context.c", "src/core/census/initialize.c", - "src/core/census/record_stat.c" + "src/core/census/record_stat.c", + "src/core/census/tracing.c" ] }, { diff --git a/gRPC.podspec b/gRPC.podspec index f47b44fe9d6..63394dbd39e 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -391,7 +391,8 @@ Pod::Spec.new do |s| 'src/core/transport/transport_op_string.c', 'src/core/census/context.c', 'src/core/census/initialize.c', - 'src/core/census/record_stat.c' + 'src/core/census/record_stat.c', + 'src/core/census/tracing.c' ss.private_header_files = 'src/core/support/env.h', 'src/core/support/file.h', diff --git a/include/grpc/census.h b/include/grpc/census.h index 6baad53f154..4c6263ec863 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -103,8 +103,8 @@ void census_context_destroy(census_context *context); /* Distributed traces can have a number of options. */ enum census_trace_mask_values { - CENSUS_TRACE_MASK_NONE = 0, /* Default, empty flags */ - CENSUS_TRACE_MASK_IS_SAMPLED = 1, /* RPC tracing enabled for this context. */ + CENSUS_TRACE_MASK_NONE = 0, /* Default, empty flags */ + CENSUS_TRACE_MASK_IS_SAMPLED = 1 /* RPC tracing enabled for this context. */ }; /** Get the current trace mask associated with this context. The value returned diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index 3e578c171b9..e2c206cfd21 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1018,6 +1018,7 @@ src/core/transport/transport_op_string.c \ src/core/census/context.c \ src/core/census/initialize.c \ src/core/census/record_stat.c \ +src/core/census/tracing.c \ include/grpc/support/alloc.h \ include/grpc/support/atm.h \ include/grpc/support/atm_gcc_atomic.h \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 84c1099a2ae..57665336b39 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -9995,6 +9995,7 @@ "src/core/census/initialize.c", "src/core/census/record_stat.c", "src/core/census/rpc_stat_id.h", + "src/core/census/tracing.c", "src/core/channel/census_filter.h", "src/core/channel/channel_args.c", "src/core/channel/channel_args.h", @@ -10442,6 +10443,7 @@ "src/core/census/initialize.c", "src/core/census/record_stat.c", "src/core/census/rpc_stat_id.h", + "src/core/census/tracing.c", "src/core/channel/census_filter.h", "src/core/channel/channel_args.c", "src/core/channel/channel_args.h", diff --git a/vsprojects/grpc/grpc.vcxproj b/vsprojects/grpc/grpc.vcxproj index 744627e388d..a826402ed0e 100644 --- a/vsprojects/grpc/grpc.vcxproj +++ b/vsprojects/grpc/grpc.vcxproj @@ -545,6 +545,8 @@ + + diff --git a/vsprojects/grpc/grpc.vcxproj.filters b/vsprojects/grpc/grpc.vcxproj.filters index 84a7823b2d2..f7e163adc9f 100644 --- a/vsprojects/grpc/grpc.vcxproj.filters +++ b/vsprojects/grpc/grpc.vcxproj.filters @@ -409,6 +409,9 @@ src\core\census + + src\core\census + diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj index a5730235fba..7ac0ba89a03 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj @@ -480,6 +480,8 @@ + + diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters index c7790431dfa..c79a37f059e 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -340,6 +340,9 @@ src\core\census + + src\core\census + From e6d0ad317ed820b29f709c8273ed3fec7463db11 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Thu, 13 Aug 2015 09:59:48 -0700 Subject: [PATCH 4/9] add all new content --- BUILD | 3 + Makefile | 3 +- build.json | 1 + gRPC.podspec | 1 + include/grpc/census.h | 220 ++++++++++-------- src/core/census/context.c | 13 -- src/core/census/grpc_context.c | 15 +- src/core/census/operation.c | 57 +++++ src/core/census/tracing.c | 24 +- tools/doxygen/Doxyfile.core.internal | 1 + tools/run_tests/sources_and_headers.json | 2 + vsprojects/grpc/grpc.vcxproj | 2 + vsprojects/grpc/grpc.vcxproj.filters | 3 + .../grpc_unsecure/grpc_unsecure.vcxproj | 2 + .../grpc_unsecure.vcxproj.filters | 3 + 15 files changed, 199 insertions(+), 151 deletions(-) create mode 100644 src/core/census/operation.c diff --git a/BUILD b/BUILD index 21da008dc8c..bfad5b25183 100644 --- a/BUILD +++ b/BUILD @@ -386,6 +386,7 @@ cc_library( "src/core/transport/transport_op_string.c", "src/core/census/context.c", "src/core/census/initialize.c", + "src/core/census/operation.c", "src/core/census/record_stat.c", "src/core/census/tracing.c", ], @@ -626,6 +627,7 @@ cc_library( "src/core/transport/transport_op_string.c", "src/core/census/context.c", "src/core/census/initialize.c", + "src/core/census/operation.c", "src/core/census/record_stat.c", "src/core/census/tracing.c", ], @@ -1113,6 +1115,7 @@ objc_library( "src/core/transport/transport_op_string.c", "src/core/census/context.c", "src/core/census/initialize.c", + "src/core/census/operation.c", "src/core/census/record_stat.c", "src/core/census/tracing.c", ], diff --git a/Makefile b/Makefile index 94e81556805..0f60fbd35bb 100644 --- a/Makefile +++ b/Makefile @@ -3856,6 +3856,7 @@ LIBGRPC_SRC = \ src/core/transport/transport_op_string.c \ src/core/census/context.c \ src/core/census/initialize.c \ + src/core/census/operation.c \ src/core/census/record_stat.c \ src/core/census/tracing.c \ @@ -4125,6 +4126,7 @@ LIBGRPC_UNSECURE_SRC = \ src/core/transport/transport_op_string.c \ src/core/census/context.c \ src/core/census/initialize.c \ + src/core/census/operation.c \ src/core/census/record_stat.c \ src/core/census/tracing.c \ @@ -18761,7 +18763,6 @@ test/cpp/qps/timer.cc: $(OPENSSL_DEP) test/cpp/util/benchmark_config.cc: $(OPENSSL_DEP) test/cpp/util/cli_call.cc: $(OPENSSL_DEP) test/cpp/util/create_test_channel.cc: $(OPENSSL_DEP) -test/cpp/util/fake_credentials.cc: $(OPENSSL_DEP) test/cpp/util/subprocess.cc: $(OPENSSL_DEP) test/cpp/util/test_config.cc: $(OPENSSL_DEP) endif diff --git a/build.json b/build.json index a65932701ed..93da5f1a8e6 100644 --- a/build.json +++ b/build.json @@ -24,6 +24,7 @@ "src": [ "src/core/census/context.c", "src/core/census/initialize.c", + "src/core/census/operation.c", "src/core/census/record_stat.c", "src/core/census/tracing.c" ] diff --git a/gRPC.podspec b/gRPC.podspec index 775fbfda5ea..d02704c88ee 100644 --- a/gRPC.podspec +++ b/gRPC.podspec @@ -395,6 +395,7 @@ Pod::Spec.new do |s| 'src/core/transport/transport_op_string.c', 'src/core/census/context.c', 'src/core/census/initialize.c', + 'src/core/census/operation.c', 'src/core/census/record_stat.c', 'src/core/census/tracing.c' diff --git a/include/grpc/census.h b/include/grpc/census.h index 9315a3ad8c5..379d567343d 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -69,12 +69,14 @@ int census_supported(void); /** Return the census features currently enabled. */ int census_enabled(void); -/* Internally, Census relies on a context, which should be propagated across - * RPC's. From the RPC subsystems viewpoint, this is an opaque data structure. - * A context must be used as the first argument to all other census - * functions. Conceptually, contexts should be thought of as specific to - * single RPC/thread. The context can be serialized for passing across the - * wire. */ +/** + Context is a handle used by census to represent the current tracing and + tagging information. Contexts should be propagated across RPC's. Contexts + are created by any of the census_start_*_op() functions. A context is + typically used as argument to most census functions. Conceptually, contexts + should be thought of as specific to single RPC/thread. The context can be + serialized for passing across the wire, via census_context_serialize(). +*/ typedef struct census_context census_context; /* This function is called by the RPC subsystem whenever it needs to get a @@ -91,19 +93,6 @@ typedef struct census_context census_context; size_t census_context_serialize(const census_context *context, char *buffer, size_t buf_size); -/* Create a new census context, possibly from a serialized buffer. If 'buffer' - * is non-NULL, it is assumed that it is a buffer encoded by - * census_context_serialize(). If `buffer` is NULL, a new, empty context is - * created. The decoded/new contest is returned in 'context'. - * - * Returns 0 if no errors, non-zero if buffer is incorrectly formatted, in - * which case a new empty context will be returned. */ -int census_context_deserialize(const char *buffer, census_context **context); - -/* The given context is destroyed. Once destroyed, using the context in - * future census calls will result in undefined behavior. */ -void census_context_destroy(census_context *context); - /* Distributed traces can have a number of options. */ enum census_trace_mask_values { CENSUS_TRACE_MASK_NONE = 0, /* Default, empty flags */ @@ -114,13 +103,15 @@ enum census_trace_mask_values { will be the logical or of census_trace_mask_values values. */ int census_trace_mask(const census_context *context); -/* The concept of "operation" is a fundamental concept for Census. An - operation is a logical representation of a action in a RPC-using system. It - is most typically used to represent a single RPC, or a significant sub-part - thereof (e.g. a single logical "read" RPC to a distributed storage system - might do several other actions in parallel, from looking up metadata +/** Set the trace mask associated with a context. */ +void census_set_trace_mask(int trace_mask); + +/* The concept of "operation" is a fundamental concept for Census. In an RPC + system, and operation typcially represents a single RPC, or a significant + sub-part thereof (e.g. a single logical "read" RPC to a distributed storage + system might do several other actions in parallel, from looking up metadata indices to making requests of other services - each of these could be a - sub-operation with the larger RPC operation. Census uses operations for the + sub-operation with the larger RPC operation). Census uses operations for the following: CPU accounting: If enabled, census will measure the thread CPU time @@ -131,123 +122,152 @@ int census_trace_mask(const census_context *context); Distributed tracing: Each operation serves as a logical trace span. - Stats collection: Stats are broken down operation (e.g. latency - breakdown for each service/method combination). + Stats collection: Stats are broken down by operation (e.g. latency + breakdown for each unique RPC path). The following functions serve to delineate the start and stop points for each logical operation. */ + +/** + This structure (opaquely) represents a timestamp as used by census to + record the time at which an RPC operation begins. +*/ +typedef struct census_timestamp census_timestamp; + +/** + Mark the beginning of an RPC operation. The information required to call the + functions to record the start of RPC operations (both client and server) may + not be callable at the true start time of the operation, due to information + not being available (e.g. the census context data will not be available in a + server RPC until at least initial metadata has been processed). To ensure + correct CPU accounting and latency recording, RPC systems can call this + function to get the timestamp of operation beginning. This can later be used + as an argument to census_start_{client,server}_rpc_op(). NB: for correct + CPU accounting, the system must guarantee that the same thread is used + for all request processing after this function is called. + + @return A timestamp representing the operation start time. +*/ +census_timestamp *census_start_rpc_op_timestamp(void); + +/** + Represent functions to map RPC name ID to service/method names. Census + breaks down all RPC stats by service and method names. We leave the + definition and format of these to the RPC system. For efficiency purposes, + we encode these as a single 64 bit identifier, and allow the RPC system to + provide a structure for functions that can convert these to service and + method strings. + + TODO(aveitch): Instead of providing this as an argument to the rpc_start_op() + functions, maybe it should be set once at census initialization. +*/ +typedef struct { + const char *(*get_rpc_service_name)(gpr_int64 id); + const char *(*get_rpc_method_name)(gpr_int64 id); +} census_rpc_name_info; + /** - Start a client rpc operation. This function will create a new context. If + Start a client rpc operation. This function should be called as early in the + client RPC path as possible. This function will create a new context. If the context argument is non-null, then the new context will inherit all its properties, with the following changes: - create a new operation ID for the new context, marking it as a child of the previous operation. - - use the new RPC service/method/peer information for tracing and stats + - use the new RPC path and peer information for tracing and stats collection purposes, rather than those from the original context - - if trace_mask is non-zero, update the trace mask entries associated with - the original context. - If the context argument is NULL, then a new root context is created. This + If the context argument is NULL, then a new root context is created. This is particularly important for tracing purposes (the trace spans generated will be unassociated with any other trace spans, except those - downstream). Whatever it's value, the trace_mask will be used for tracing - operations associated with the new context. - - @param context The base context. Can be NULL. - @param service RPC service name. On some systems, may include other - parts of RPC identification (e.g. host on gRPC systems). - @param method RPC method name - @param peer RPC peer - @param trace_mask An or of census_trace_mask_values values - @param start_time If NULL, the time of function call is used as the - start time for the operation. If non-NULL, then the time should be in the - past, when the operation was deemed to have started. This is used when - the other information used as arguments is not yet available. + downstream). The trace_mask will be used for tracing operations associated + with the new context. + + In some RPC systems (e.g. where load balancing is used), peer information + may not be available at the time the operation starts. In this case, use a + NULL value for peer, and set it later using the + census_set_rpc_client_peer() function. + + @param context The parent context. Can be NULL. + @param rpc_name_id The rpc name identifier to be associated with this RPC. + @param rpc_name_info Used to decode rpc_name_id. + @param peer RPC peer. If not available at the time, NULL can be used, + and a later census_set_rpc_client_peer() call made. + @param trace_mask An OR of census_trace_mask_values values. Only used in + the creation of a new root context (context == NULL). + @param start_time A timestamp returned from census_start_rpc_op_timestamp(). + Can be NULL. Used to set the true time the operation + begins. @return A new census context. */ -census_context *census_start_client_rpc_op(census_context *context, - const char *service, - const char *method, const char *peer, - int trace_mask, - gpr_timespec *start_time); +census_context *census_start_client_rpc_op( + const census_context *context, gpr_int64 rpc_name_id, + const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, + const census_timestamp *start_time); /** - Indicate the start of a server rpc operation, updating the current - context (which should have been created from census_context_deserialize() - (as passed from the client side of the RPC operation) or census_start_op(). - - if trace_mask is non-zero, update the trace mask entries associated with - the original context. - - @param context The base context. Cannot be NULL. - @param service RPC service name. On some systems, may include other - parts of RPC identification (e.g. host on gRPC systems). - @param method RPC method name - @param peer RPC peer - @param trace_mask An or of census_trace_mask_values values - @param start_time If NULL, the time of function call is used as the - start time for the operation. If non-NULL, then the time should be in the - past, when the operation was deemed to have started. This is used when - the other information used as arguments is not yet available. + Add peer information to a context representing a client RPC operation. +*/ +void census_set_rpc_client_peer(census_context *context, const char *peer); + +/** + Start a server RPC operation. Returns a new context to be used in future + census calls. If buffer is non-NULL, then the buffer contents should + represent the client context, as generated by census_context_serialize(). + If buffer is NULL, a new root context is created. + + @param buffer Buffer containing bytes output from census_context_serialize(). + @param rpc_name_id The rpc name identifier to be associated with this RPC. + @param rpc_name_info Used to decode rpc_name_id. + @param peer RPC peer. + @param trace_mask An OR of census_trace_mask_values values. Only used in + the creation of a new root context (buffer == NULL). + @param start_time A timestamp returned from census_start_rpc_op_timestamp(). + Can be NULL. Used to set the true time the operation + begins. + + @return A new census context. */ -void census_start_server_rpc_op(census_context *context, const char *service, - const char *method, const char *peer, - int trace_mask, gpr_timespec *start_time); +census_context *census_start_server_rpc_op( + const char *buffer, gpr_int64 rpc_name_id, + const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, + census_timestamp *start_time); /** - Start a new, non-RPC census operation. In general, this function works very - similarly to census_start_client_rpc_op, with the primary differennce being - the abscence of peer information, and the replacement of service and method - names with the more general family/name. If the context argument is - non-null, then the new context will inherit all its properties, with the - following changes: + Start a new, non-RPC operation. In general, this function works very + similarly to census_start_client_rpc_op, with the primary difference being + the replacement of host/path information with the more generic family/name + tags. If the context argument is non-null, then the new context will + inherit all its properties, with the following changes: - create a new operation ID for the new context, marking it as a child of the previous operation. - use the family and name information for tracing and stats collection purposes, rather than those from the original context - - if trace_mask is non-zero, update the trace mask entries associated with - the original context. - If the context argument is NULL, then a new root context is created. This + If the context argument is NULL, then a new root context is created. This is particularly important for tracing purposes (the trace spans generated will be unassociated with any other trace spans, except those - downstream). Whatever it's value, the trace_mask will be used for tracing + downstream). The trace_mask will be used for tracing operations associated with the new context. @param context The base context. Can be NULL. @param family Family name to associate with the trace @param name Name within family to associated with traces/stats - @param trace_mask An or of census_trace_mask_values values - @param start_time If NULL, the time of function call is used as the - start time for the operation. If non-NULL, then the time should be in the - past, when the operation was deemed to have started. This is used when - the other information used as arguments is not yet available. + @param trace_mask An OR of census_trace_mask_values values. Only used if + context is NULL. @return A new census context. */ census_context *census_start_op(census_context *context, const char *family, - const char *name, int trace_mask, - gpr_timespec *start_time); + const char *name, int trace_mask); -/** End a tracing operation. Must be matched with an earlier - * census_start_*_op*() call. */ -void census_trace_end_op(census_context *context, int status); +/** End an operation started by any of the census_start_*_op*() calls. */ +void census_end_op(census_context *context, int status); /** Insert a trace record into the trace stream. The record consists of an * arbitrary size buffer, the size of which is provided in 'n'. */ void census_trace_print(census_context *context, const char *buffer, size_t n); -/** Retrieve active ops as a proto. Note that since we don't have proto - manipulation available in the grpc core yet, arguments etc. are left - unspecified for now. */ -void census_get_active_ops_as_proto(/* pointer to proto */); - -/** Retrieve all active trace records as a proto. Note that since we don't - have proto manipulation available in the grpc core yet, arguments etc. are - left unspecified for now. This function will clear existing trace - records. */ -void census_get_trace_as_proto(/* pointer to proto */); - /* A census statistic to be recorded comprises two parts: an ID for the * particular statistic and the value to be recorded against it. */ typedef struct { diff --git a/src/core/census/context.c b/src/core/census/context.c index df238ec98ca..cab58b653cb 100644 --- a/src/core/census/context.c +++ b/src/core/census/context.c @@ -44,16 +44,3 @@ size_t census_context_serialize(const census_context *context, char *buffer, /* TODO(aveitch): implement serialization */ return 0; } - -int census_context_deserialize(const char *buffer, census_context **context) { - int ret = 0; - if (buffer != NULL) { - /* TODO(aveitch): implement deserialization. */ - ret = 1; - } - *context = gpr_malloc(sizeof(census_context)); - memset(*context, 0, sizeof(census_context)); - return ret; -} - -void census_context_destroy(census_context *context) { gpr_free(context); } diff --git a/src/core/census/grpc_context.c b/src/core/census/grpc_context.c index 11f1eb3d5da..429f3ec9db0 100644 --- a/src/core/census/grpc_context.c +++ b/src/core/census/grpc_context.c @@ -35,24 +35,11 @@ #include #include "src/core/surface/call.h" -static void grpc_census_context_destroy(void *context) { - census_context_destroy((census_context *)context); -} - void grpc_census_call_set_context(grpc_call *call, census_context *context) { if (census_enabled() == CENSUS_FEATURE_NONE) { return; } - if (context == NULL) { - if (grpc_call_is_client(call)) { - census_context *context_ptr; - census_context_deserialize(NULL, &context_ptr); - grpc_call_context_set(call, GRPC_CONTEXT_TRACING, context_ptr, - grpc_census_context_destroy); - } else { - /* TODO(aveitch): server side context code to be implemented. */ - } - } else { + if (context != NULL) { grpc_call_context_set(call, GRPC_CONTEXT_TRACING, context, NULL); } } diff --git a/src/core/census/operation.c b/src/core/census/operation.c new file mode 100644 index 00000000000..a0196da6146 --- /dev/null +++ b/src/core/census/operation.c @@ -0,0 +1,57 @@ +/* + * Copyright 2015, Google Inc. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ + +#include + +/* TODO(aveitch): These are all placeholder implementations. */ + +census_timestamp *census_start_rpc_op_timestamp(void) { return NULL; } +census_context *census_start_client_rpc_op( + const census_context *context, gpr_int64 rpc_name_id, + const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, + const census_timestamp *start_time) { + return NULL; +} + +census_context *census_start_server_rpc_op( + const char *buffer, gpr_int64 rpc_name_id, + const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, + census_timestamp *start_time) { + return NULL; +} + +census_context *census_start_op(census_context *context, const char *family, + const char *name, int trace_mask) { + return NULL; +} + +void census_end_op(census_context *context, int status) {} diff --git a/src/core/census/tracing.c b/src/core/census/tracing.c index 83d46cc4075..44db95653c6 100644 --- a/src/core/census/tracing.c +++ b/src/core/census/tracing.c @@ -39,29 +39,7 @@ int census_trace_mask(const census_context *context) { return CENSUS_TRACE_MASK_NONE; } -census_context *census_start_client_rpc_op(census_context *context, - const char *service, - const char *method, const char *peer, - int trace_mask, - gpr_timespec *start_time) { - return NULL; -} - -void census_start_server_rpc_op(census_context *context, const char *service, - const char *method, const char *peer, - int trace_mask, gpr_timespec *start_time) {} - -census_context *census_start_op(census_context *context, const char *family, - const char *name, int trace_mask, - gpr_timespec *start_time) { - return NULL; -} - -void census_trace_end_op(census_context *context, int status) {} +void census_set_trace_mask(int trace_mask) {} void census_trace_print(census_context *context, const char *buffer, size_t n) { } - -void census_get_active_ops_as_proto(/* pointer to proto */) {} - -void census_get_trace_as_proto(/* pointer to proto */) {} diff --git a/tools/doxygen/Doxyfile.core.internal b/tools/doxygen/Doxyfile.core.internal index e5bf7fa220d..8f937303a90 100644 --- a/tools/doxygen/Doxyfile.core.internal +++ b/tools/doxygen/Doxyfile.core.internal @@ -1021,6 +1021,7 @@ src/core/transport/transport.c \ src/core/transport/transport_op_string.c \ src/core/census/context.c \ src/core/census/initialize.c \ +src/core/census/operation.c \ src/core/census/record_stat.c \ src/core/census/tracing.c \ include/grpc/support/alloc.h \ diff --git a/tools/run_tests/sources_and_headers.json b/tools/run_tests/sources_and_headers.json index 24dca9cc7f1..68787057704 100644 --- a/tools/run_tests/sources_and_headers.json +++ b/tools/run_tests/sources_and_headers.json @@ -11056,6 +11056,7 @@ "src/core/census/context.h", "src/core/census/grpc_context.c", "src/core/census/initialize.c", + "src/core/census/operation.c", "src/core/census/record_stat.c", "src/core/census/rpc_stat_id.h", "src/core/census/tracing.c", @@ -11509,6 +11510,7 @@ "src/core/census/context.h", "src/core/census/grpc_context.c", "src/core/census/initialize.c", + "src/core/census/operation.c", "src/core/census/record_stat.c", "src/core/census/rpc_stat_id.h", "src/core/census/tracing.c", diff --git a/vsprojects/grpc/grpc.vcxproj b/vsprojects/grpc/grpc.vcxproj index add4a8fa7c6..a0fca7aa893 100644 --- a/vsprojects/grpc/grpc.vcxproj +++ b/vsprojects/grpc/grpc.vcxproj @@ -623,6 +623,8 @@ + + diff --git a/vsprojects/grpc/grpc.vcxproj.filters b/vsprojects/grpc/grpc.vcxproj.filters index 41142651c22..e0c9519bb64 100644 --- a/vsprojects/grpc/grpc.vcxproj.filters +++ b/vsprojects/grpc/grpc.vcxproj.filters @@ -415,6 +415,9 @@ src\core\census + + src\core\census + src\core\census diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj index 395e3bc86fc..99d1e7ff6f6 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj @@ -556,6 +556,8 @@ + + diff --git a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters index 721bbd83102..049dbcf10d6 100644 --- a/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters +++ b/vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters @@ -346,6 +346,9 @@ src\core\census + + src\core\census + src\core\census From 0879df275530e0a990ad1e785137546eb43842e6 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Thu, 13 Aug 2015 14:32:05 -0700 Subject: [PATCH 5/9] add comment --- include/grpc/census.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/grpc/census.h b/include/grpc/census.h index 12b7508db4f..591d0dc52b7 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -261,7 +261,15 @@ census_context *census_start_server_rpc_op( census_context *census_start_op(census_context *context, const char *family, const char *name, int trace_mask); -/** End an operation started by any of the census_start_*_op*() calls. */ +/** + End an operation started by any of the census_start_*_op*() calls. The + context used in this call will no longer be valid once this function + completes. + + @param context Context associated with operation which is ending. + @param status status associated with the operation. Not interpreted by + census. +*/ void census_end_op(census_context *context, int status); /** Insert a trace record into the trace stream. The record consists of an From f886985d2c775d480079ea979323ae22efc0afc6 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Tue, 25 Aug 2015 15:24:49 -0700 Subject: [PATCH 6/9] refactor census_timestamp --- include/grpc/census.h | 12 ++++++++---- src/core/census/operation.c | 8 +++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/include/grpc/census.h b/include/grpc/census.h index 591d0dc52b7..ef6275fe58d 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -129,10 +129,14 @@ void census_set_trace_mask(int trace_mask); each logical operation. */ /** - This structure (opaquely) represents a timestamp as used by census to - record the time at which an RPC operation begins. + This structure represents a timestamp as used by census to record the time + at which an operation begins. */ -typedef struct census_timestamp census_timestamp; +typedef struct { + /* Use gpr_timespec for default implementation. High performance + * implementations should use a cycle-counter based timestamp. */ + gpr_timespec ts; +} census_timestamp; /** Mark the beginning of an RPC operation. The information required to call the @@ -148,7 +152,7 @@ typedef struct census_timestamp census_timestamp; @return A timestamp representing the operation start time. */ -census_timestamp *census_start_rpc_op_timestamp(void); +census_timestamp census_start_rpc_op_timestamp(void); /** Represent functions to map RPC name ID to service/method names. Census diff --git a/src/core/census/operation.c b/src/core/census/operation.c index a0196da6146..118eb0a47ad 100644 --- a/src/core/census/operation.c +++ b/src/core/census/operation.c @@ -34,7 +34,13 @@ /* TODO(aveitch): These are all placeholder implementations. */ -census_timestamp *census_start_rpc_op_timestamp(void) { return NULL; } +census_timestamp census_start_rpc_op_timestamp(void) { + census_timestamp ct; + /* TODO(aveitch): assumes gpr_timespec implementation of census_timestamp. */ + ct.ts = gpr_now(GPR_CLOCK_MONOTONIC); + return ct; +} + census_context *census_start_client_rpc_op( const census_context *context, gpr_int64 rpc_name_id, const census_rpc_name_info *rpc_name_info, const char *peer, int trace_mask, From 487a72b7262f0184c517093c2a8a6a7ef5fba046 Mon Sep 17 00:00:00 2001 From: Jan Tattermusch Date: Fri, 28 Aug 2015 13:33:38 -0700 Subject: [PATCH 7/9] Provide troubleshooting instructions for 'cannot load grpc_csharp_ext.dll' problem. --- src/csharp/README.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/csharp/README.md b/src/csharp/README.md index 30523b3bd28..3fbc1c5f052 100644 --- a/src/csharp/README.md +++ b/src/csharp/README.md @@ -158,3 +158,20 @@ Contents An example client that sends some requests to math server. - Grpc.IntegrationTesting: Cross-language gRPC implementation testing (interop testing). + +Troubleshooting +--------------- + +### Problem: Unable to load DLL 'grpc_csharp_ext.dll' + +Internally, gRPC C# uses a native library written in C (gRPC C core) and invokes its functionality via P/Invoke. `grpc_csharp_ext` library is a native extension library that facilitates this by wrapping some C core API into a form that's more digestible for P/Invoke. If you get the above error, it means that the native dependencies could not be located by the C# runtime (or they are incompatible with the current runtime, so they could not be loaded). The solution to this is environment specific. + +- If you are developing on Windows in Visual Studio, the `grpc_csharp_ext.dll` that is shipped by gRPC nuget packages should be automatically copied to your build destination folder once you build. By adjusting project properties in your VS project file, you can influence which exact configuration of `grpc_csharp_ext.dll` will be used (based on VS version, bitness, debug/release configuration). + +- If you are running your application that is using gRPC on Windows machine that doesn't have Visual Studio installed, you might need to install [Visual C++ 2013 redistributable](https://www.microsoft.com/en-us/download/details.aspx?id=40784) that contains some system .dll libraries that `grpc_csharp_ext.dll` depends on (see #905 for more details). + +- On Linux (or Docker), you need to first install gRPC C core and `libgrpc_csharp_ext.so` shared libraries. Currently, the libraries can be installed by `make install_grpc_csharp_ext` or using Linuxbrew (a Debian package is coming soon). Installation on a machine where your application is going to be deployed is no different. + +- On Mac, you need to first install gRPC C core and `libgrpc_csharp_ext.dylib` shared libraries using Homebrew. See above for installation instruction. Installation on a machine where your application is going to be deployed is no different. + +- Possible cause for the problem is that the `grpc_csharp_ext` library is installed, but it has different bitness (32/64bit) than your C# runtime (in case you are using mono) or C# application. From 6afe53f2360a20a4d3abda60cfdde576c29b9857 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Fri, 28 Aug 2015 14:05:15 -0700 Subject: [PATCH 8/9] add functions for getting trace records --- include/grpc/census.h | 48 +++++++++++++++++++++++++++++++++++++-- src/core/census/tracing.c | 4 ++-- 2 files changed, 48 insertions(+), 4 deletions(-) diff --git a/include/grpc/census.h b/include/grpc/census.h index ef6275fe58d..d1a2978bd22 100644 --- a/include/grpc/census.h +++ b/include/grpc/census.h @@ -276,9 +276,53 @@ census_context *census_start_op(census_context *context, const char *family, */ void census_end_op(census_context *context, int status); +#define CENSUS_TRACE_RECORD_START_OP ((gpr_uint32)0) +#define CENSUS_TRACE_RECORD_END_OP ((gpr_uint32)1) + /** Insert a trace record into the trace stream. The record consists of an - * arbitrary size buffer, the size of which is provided in 'n'. */ -void census_trace_print(census_context *context, const char *buffer, size_t n); + arbitrary size buffer, the size of which is provided in 'n'. + @param context Trace context + @param type User-defined type to associate with trace entry. + @param buffer Pointer to buffer to use + @param n Number of bytes in buffer +*/ +void census_trace_print(census_context *context, gpr_uint32 type, + const char *buffer, size_t n); + +/** Trace record. */ +typedef struct { + census_timestamp timestamp; /* Time of record creation */ + gpr_uint64 trace_id; /* Trace ID associated with record */ + gpr_uint64 op_id; /* Operation ID associated with record */ + gpr_uint32 type; /* Type (as used in census_trace_print() */ + const char *buffer; /* Buffer (from census_trace_print() */ + size_t buf_size; /* Number of bytes inside buffer */ +} census_trace_record; + +/** Start a scan of existing trace records. While a scan is ongoing, addition + of new trace records will be blocked if the underlying trace buffers + fill up, so trace processing systems should endeavor to complete + reading as soon as possible. + @param consume if non-zero, indicates that reading records also "consumes" + the previously read record - i.e. releases space in the trace log + while scanning is ongoing. + @returns 0 on success, non-zero on failure (e.g. if a scan is already ongoing) +*/ +int census_trace_scan_start(int consume); + +/** Get a trace record. The data pointed to by the trace buffer is guaranteed + stable until the next census_get_trace_record() call (if the consume + argument to census_trace_scan_start was non-zero) or census_trace_scan_end() + is called (otherwise). + @param trace_record structure that will be filled in with oldest trace record. + @returns -1 if an error occurred (e.g. no previous call to + census_trace_scan_start()), 0 if there is no more trace data (and + trace_record will not be modified) or 1 otherwise. +*/ +int census_get_trace_record(census_trace_record *trace_record); + +/** End a scan previously started by census_trace_scan_start() */ +void census_trace_scan_end(); /* Max number of characters in tag key */ #define CENSUS_MAX_TAG_KEY_LENGTH 20 diff --git a/src/core/census/tracing.c b/src/core/census/tracing.c index 44db95653c6..ae38773c0a1 100644 --- a/src/core/census/tracing.c +++ b/src/core/census/tracing.c @@ -41,5 +41,5 @@ int census_trace_mask(const census_context *context) { void census_set_trace_mask(int trace_mask) {} -void census_trace_print(census_context *context, const char *buffer, size_t n) { -} +void census_trace_print(census_context *context, gpr_uint32 type, + const char *buffer, size_t n) {} From 63b83f1cce5d9e257b8d110eefb5982de4127105 Mon Sep 17 00:00:00 2001 From: Alistair Veitch Date: Fri, 28 Aug 2015 15:50:13 -0700 Subject: [PATCH 9/9] fix openssl --- third_party/openssl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/openssl b/third_party/openssl index 3df69d3aefd..33dd0832064 160000 --- a/third_party/openssl +++ b/third_party/openssl @@ -1 +1 @@ -Subproject commit 3df69d3aefde7671053d4e3c242b228e5d79c83f +Subproject commit 33dd08320648ac71d7d9d732be774ed3818dccc5