Merge pull request #5013 from a-veitch/tag_set_to_context

Change all instances of census_tag_set to census_context
pull/5075/head
Bogdan Drutu 9 years ago
commit e4fdcd9242
  1. 6
      BUILD
  2. 74
      Makefile
  3. 1
      binding.gyp
  4. 18
      build.yaml
  5. 3
      gRPC.podspec
  6. 18
      grpc.def
  7. 2
      grpc.gemspec
  8. 314
      include/grpc/census.h
  9. 2
      package.json
  10. 500
      src/core/census/context.c
  11. 47
      src/core/census/context.h
  12. 9
      src/core/census/placeholders.c
  13. 535
      src/core/census/tag_set.c
  14. 1
      src/python/grpcio/grpc_core_dependencies.py
  15. 36
      src/ruby/ext/grpc/rb_grpc_imports.generated.c
  16. 58
      src/ruby/ext/grpc/rb_grpc_imports.generated.h
  17. 280
      test/core/census/context_test.c
  18. 34
      test/cpp/qps/client_async.cc
  19. 2
      tools/doxygen/Doxyfile.core.internal
  20. 30
      tools/run_tests/sources_and_headers.json
  21. 40
      tools/run_tests/tests.json
  22. 50
      vsprojects/buildtests_c.sln
  23. 3
      vsprojects/vcxproj/grpc/grpc.vcxproj
  24. 6
      vsprojects/vcxproj/grpc/grpc.vcxproj.filters
  25. 3
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj
  26. 6
      vsprojects/vcxproj/grpc_unsecure/grpc_unsecure.vcxproj.filters
  27. 8
      vsprojects/vcxproj/test/census_context_test/census_context_test.vcxproj
  28. 8
      vsprojects/vcxproj/test/census_context_test/census_context_test.vcxproj.filters

@ -182,7 +182,6 @@ cc_library(
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
"src/core/httpcli/httpcli_security_connector.c",
"src/core/security/base64.c",
@ -379,7 +378,6 @@ cc_library(
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
],
hdrs = [
@ -580,7 +578,6 @@ cc_library(
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
"src/core/surface/init_unsecure.c",
"src/core/profiling/basic_timers.c",
@ -757,7 +754,6 @@ cc_library(
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
],
hdrs = [
@ -1405,7 +1401,6 @@ objc_library(
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
],
hdrs = [
@ -1602,7 +1597,6 @@ objc_library(
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
],
includes = [

@ -831,6 +831,7 @@ algorithm_test: $(BINDIR)/$(CONFIG)/algorithm_test
alloc_test: $(BINDIR)/$(CONFIG)/alloc_test
alpn_test: $(BINDIR)/$(CONFIG)/alpn_test
bin_encoder_test: $(BINDIR)/$(CONFIG)/bin_encoder_test
census_context_test: $(BINDIR)/$(CONFIG)/census_context_test
channel_create_test: $(BINDIR)/$(CONFIG)/channel_create_test
chttp2_hpack_encoder_test: $(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test
chttp2_status_conversion_test: $(BINDIR)/$(CONFIG)/chttp2_status_conversion_test
@ -908,7 +909,6 @@ set_initial_connect_string_test: $(BINDIR)/$(CONFIG)/set_initial_connect_string_
sockaddr_resolver_test: $(BINDIR)/$(CONFIG)/sockaddr_resolver_test
sockaddr_utils_test: $(BINDIR)/$(CONFIG)/sockaddr_utils_test
socket_utils_test: $(BINDIR)/$(CONFIG)/socket_utils_test
tag_set_test: $(BINDIR)/$(CONFIG)/tag_set_test
tcp_client_posix_test: $(BINDIR)/$(CONFIG)/tcp_client_posix_test
tcp_posix_test: $(BINDIR)/$(CONFIG)/tcp_posix_test
tcp_server_posix_test: $(BINDIR)/$(CONFIG)/tcp_server_posix_test
@ -1138,6 +1138,7 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/alloc_test \
$(BINDIR)/$(CONFIG)/alpn_test \
$(BINDIR)/$(CONFIG)/bin_encoder_test \
$(BINDIR)/$(CONFIG)/census_context_test \
$(BINDIR)/$(CONFIG)/channel_create_test \
$(BINDIR)/$(CONFIG)/chttp2_hpack_encoder_test \
$(BINDIR)/$(CONFIG)/chttp2_status_conversion_test \
@ -1208,7 +1209,6 @@ buildtests_c: privatelibs_c \
$(BINDIR)/$(CONFIG)/sockaddr_resolver_test \
$(BINDIR)/$(CONFIG)/sockaddr_utils_test \
$(BINDIR)/$(CONFIG)/socket_utils_test \
$(BINDIR)/$(CONFIG)/tag_set_test \
$(BINDIR)/$(CONFIG)/tcp_client_posix_test \
$(BINDIR)/$(CONFIG)/tcp_posix_test \
$(BINDIR)/$(CONFIG)/tcp_server_posix_test \
@ -1371,6 +1371,8 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/alpn_test || ( echo test alpn_test failed ; exit 1 )
$(E) "[RUN] Testing bin_encoder_test"
$(Q) $(BINDIR)/$(CONFIG)/bin_encoder_test || ( echo test bin_encoder_test failed ; exit 1 )
$(E) "[RUN] Testing census_context_test"
$(Q) $(BINDIR)/$(CONFIG)/census_context_test || ( echo test census_context_test failed ; exit 1 )
$(E) "[RUN] Testing channel_create_test"
$(Q) $(BINDIR)/$(CONFIG)/channel_create_test || ( echo test channel_create_test failed ; exit 1 )
$(E) "[RUN] Testing chttp2_hpack_encoder_test"
@ -1505,8 +1507,6 @@ test_c: buildtests_c
$(Q) $(BINDIR)/$(CONFIG)/sockaddr_utils_test || ( echo test sockaddr_utils_test failed ; exit 1 )
$(E) "[RUN] Testing socket_utils_test"
$(Q) $(BINDIR)/$(CONFIG)/socket_utils_test || ( echo test socket_utils_test failed ; exit 1 )
$(E) "[RUN] Testing tag_set_test"
$(Q) $(BINDIR)/$(CONFIG)/tag_set_test || ( echo test tag_set_test failed ; exit 1 )
$(E) "[RUN] Testing tcp_client_posix_test"
$(Q) $(BINDIR)/$(CONFIG)/tcp_client_posix_test || ( echo test tcp_client_posix_test failed ; exit 1 )
$(E) "[RUN] Testing tcp_posix_test"
@ -2343,7 +2343,6 @@ LIBGRPC_SRC = \
src/core/census/initialize.c \
src/core/census/operation.c \
src/core/census/placeholders.c \
src/core/census/tag_set.c \
src/core/census/tracing.c \
PUBLIC_HEADERS_C += \
@ -2715,7 +2714,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/census/initialize.c \
src/core/census/operation.c \
src/core/census/placeholders.c \
src/core/census/tag_set.c \
src/core/census/tracing.c \
PUBLIC_HEADERS_C += \
@ -5803,6 +5801,38 @@ endif
endif
CENSUS_CONTEXT_TEST_SRC = \
test/core/census/context_test.c \
CENSUS_CONTEXT_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(CENSUS_CONTEXT_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/census_context_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/census_context_test: $(CENSUS_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(CENSUS_CONTEXT_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/census_context_test
endif
$(OBJDIR)/$(CONFIG)/test/core/census/context_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a
deps_census_context_test: $(CENSUS_CONTEXT_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(CENSUS_CONTEXT_TEST_OBJS:.o=.dep)
endif
endif
CHANNEL_CREATE_TEST_SRC = \
test/core/surface/channel_create_test.c \
@ -8267,38 +8297,6 @@ endif
endif
TAG_SET_TEST_SRC = \
test/core/census/tag_set_test.c \
TAG_SET_TEST_OBJS = $(addprefix $(OBJDIR)/$(CONFIG)/, $(addsuffix .o, $(basename $(TAG_SET_TEST_SRC))))
ifeq ($(NO_SECURE),true)
# You can't build secure targets if you don't have OpenSSL.
$(BINDIR)/$(CONFIG)/tag_set_test: openssl_dep_error
else
$(BINDIR)/$(CONFIG)/tag_set_test: $(TAG_SET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a
$(E) "[LD] Linking $@"
$(Q) mkdir -p `dirname $@`
$(Q) $(LD) $(LDFLAGS) $(TAG_SET_TEST_OBJS) $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a $(LDLIBS) $(LDLIBS_SECURE) -o $(BINDIR)/$(CONFIG)/tag_set_test
endif
$(OBJDIR)/$(CONFIG)/test/core/census/tag_set_test.o: $(LIBDIR)/$(CONFIG)/libgrpc_test_util.a $(LIBDIR)/$(CONFIG)/libgrpc.a
deps_tag_set_test: $(TAG_SET_TEST_OBJS:.o=.dep)
ifneq ($(NO_SECURE),true)
ifneq ($(NO_DEPS),true)
-include $(TAG_SET_TEST_OBJS:.o=.dep)
endif
endif
TCP_CLIENT_POSIX_TEST_SRC = \
test/core/iomgr/tcp_client_posix_test.c \

@ -685,7 +685,6 @@
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/placeholders.c',
'src/core/census/tag_set.c',
'src/core/census/tracing.c',
],
"conditions": [

@ -14,14 +14,12 @@ filegroups:
- include/grpc/census.h
headers:
- src/core/census/aggregation.h
- src/core/census/context.h
- src/core/census/rpc_metric_id.h
src:
- src/core/census/context.c
- src/core/census/initialize.c
- src/core/census/operation.c
- src/core/census/placeholders.c
- src/core/census/tag_set.c
- src/core/census/tracing.c
- name: gpr
public_headers:
@ -896,6 +894,14 @@ targets:
deps:
- grpc_test_util
- grpc
- name: census_context_test
build: test
language: c
src:
- test/core/census/context_test.c
deps:
- grpc_test_util
- grpc
- name: channel_create_test
build: test
language: c
@ -1561,14 +1567,6 @@ targets:
- mac
- linux
- posix
- name: tag_set_test
build: test
language: c
src:
- test/core/census/tag_set_test.c
deps:
- grpc_test_util
- grpc
- name: tcp_client_posix_test
cpu_cost: 0.5
build: test

@ -201,7 +201,6 @@ Pod::Spec.new do |s|
'src/core/support/thd_internal.h',
'src/core/support/time_precise.h',
'src/core/census/aggregation.h',
'src/core/census/context.h',
'src/core/census/rpc_metric_id.h',
'include/grpc/grpc_security.h',
'include/grpc/byte_buffer.h',
@ -453,7 +452,6 @@ Pod::Spec.new do |s|
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/placeholders.c',
'src/core/census/tag_set.c',
'src/core/census/tracing.c'
ss.private_header_files = 'src/core/security/auth_filters.h',
@ -594,7 +592,6 @@ Pod::Spec.new do |s|
'src/core/support/thd_internal.h',
'src/core/support/time_precise.h',
'src/core/census/aggregation.h',
'src/core/census/context.h',
'src/core/census/rpc_metric_id.h'
ss.header_mappings_dir = '.'

@ -3,7 +3,14 @@ EXPORTS
census_shutdown
census_supported
census_enabled
census_context_serialize
census_context_create
census_context_destroy
census_context_get_status
census_context_initialize_iterator
census_context_next_tag
census_context_get_tag
census_context_encode
census_context_decode
census_trace_mask
census_set_trace_mask
census_start_rpc_op_timestamp
@ -16,15 +23,6 @@ EXPORTS
census_trace_scan_start
census_get_trace_record
census_trace_scan_end
census_tag_set_create
census_tag_set_destroy
census_tag_set_get_create_status
census_tag_set_initialize_iterator
census_tag_set_next_tag
census_tag_set_get_tag_by_key
census_tag_set_encode
census_tag_set_decode
census_context_tag_set
census_record_values
census_view_create
census_view_delete

@ -240,7 +240,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/support/thd_internal.h )
s.files += %w( src/core/support/time_precise.h )
s.files += %w( src/core/census/aggregation.h )
s.files += %w( src/core/census/context.h )
s.files += %w( src/core/census/rpc_metric_id.h )
s.files += %w( src/core/httpcli/httpcli_security_connector.c )
s.files += %w( src/core/security/base64.c )
@ -437,7 +436,6 @@ Gem::Specification.new do |s|
s.files += %w( src/core/census/initialize.c )
s.files += %w( src/core/census/operation.c )
s.files += %w( src/core/census/placeholders.c )
s.files += %w( src/core/census/tag_set.c )
s.files += %w( src/core/census/tracing.c )
s.files += %w( third_party/boringssl/crypto/aes/internal.h )
s.files += %w( third_party/boringssl/crypto/asn1/asn1_locl.h )

@ -70,28 +70,148 @@ CENSUS_API int census_supported(void);
CENSUS_API int census_enabled(void);
/**
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().
*/
A Census Context is a handle used by Census to represent the current tracing
and stats collection information. Contexts should be propagated across RPC's
(this is the responsibility of the local RPC system). A context is typically
used as the first argument to most census functions. Conceptually, they
should be thought of as specific to a single RPC/thread. The user visible
context representation is that of a collection of key:value string pairs,
each of which is termed a 'tag'; these form the basis against which Census
metrics will be recorded. Keys are unique within a context. */
typedef struct census_context census_context;
/* This function is called by the RPC subsystem whenever it needs to get a
* serialized form of the current census context (presumably to pass across
* the wire). Arguments:
* 'buffer': pointer to memory into which serialized context will be placed
* 'buf_size': size of 'buffer'
*
* Returns: the number of bytes used in buffer if successful, or 0 if the
* buffer is of insufficient size.
*
* TODO(aveitch): determine how best to communicate required/max buffer size
* so caller doesn't have to guess. */
CENSUS_API size_t census_context_serialize(const census_context *context,
char *buffer, size_t buf_size);
/* A tag is a key:value pair. The key is a non-empty, printable (UTF-8
encoded), nil-terminated string. The value is a binary string, that may be
printable. There are limits on the sizes of both keys and values (see
CENSUS_MAX_TAG_KB_LEN definition below), and the number of tags that can be
propagated (CENSUS_MAX_PROPAGATED_TAGS). Users should also remember that
some systems may have limits on, e.g., the number of bytes that can be
transmitted as metadata, and that larger tags means more memory consumed
and time in processing. */
typedef struct {
const char *key;
const char *value;
size_t value_len;
uint8_t flags;
} census_tag;
/* Maximum length of a tag's key or value. */
#define CENSUS_MAX_TAG_KV_LEN 255
/* Maximum number of propagatable tags. */
#define CENSUS_MAX_PROPAGATED_TAGS 255
/* Tag flags. */
#define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */
#define CENSUS_TAG_STATS 2 /* Tag will be used for statistics aggregation */
#define CENSUS_TAG_BINARY 4 /* Tag value is not printable */
#define CENSUS_TAG_RESERVED 8 /* Reserved for internal use. */
/* Flag values 8,16,32,64,128 are reserved for future/internal use. Clients
should not use or rely on their values. */
#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
#define CENSUS_TAG_IS_BINARY(flags) (flags & CENSUS_TAG_BINARY)
/* An instance of this structure is kept by every context, and records the
basic information associated with the creation of that context. */
typedef struct {
int n_propagated_tags; /* number of propagated printable tags */
int n_propagated_binary_tags; /* number of propagated binary tags */
int n_local_tags; /* number of non-propagated (local) tags */
int n_deleted_tags; /* number of tags that were deleted */
int n_added_tags; /* number of tags that were added */
int n_modified_tags; /* number of tags that were modified */
int n_invalid_tags; /* number of tags with bad keys or values (e.g.
longer than CENSUS_MAX_TAG_KV_LEN) */
int n_ignored_tags; /* number of tags ignored because of
CENSUS_MAX_PROPAGATED_TAGS limit. */
} census_context_status;
/* Create a new context, adding and removing tags from an existing context.
This will copy all tags from the 'tags' input, so it is recommended
to add as many tags in a single operation as is practical for the client.
@param base Base context to build upon. Can be NULL.
@param tags A set of tags to be added/changed/deleted. Tags with keys that
are in 'tags', but not 'base', are added to the tag set. Keys that are in
both 'tags' and 'base' will have their value/flags modified. Tags with keys
in both, but with NULL or zero-length values, will be deleted from the tag
set. Tags with invalid (too long or short) keys or values will be ignored.
If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
binary or non-binary tags, they will be ignored, as will deletions of
tags that don't exist.
@param ntags number of tags in 'tags'
@param status If not NULL, will return a pointer to a census_context_status
structure containing information about the new context and status of the
tags used in its creation.
@return A new, valid census_context.
*/
CENSUS_API census_context *census_context_create(
const census_context *base, const census_tag *tags, int ntags,
census_context_status const **status);
/* Destroy a context. Once this function has been called, the context cannot
be reused. */
CENSUS_API void census_context_destroy(census_context *context);
/* Get a pointer to the original status from the context creation. */
CENSUS_API const census_context_status *census_context_get_status(
const census_context *context);
/* Structure used for iterating over the tegs in a context. API clients should
not use or reference internal fields - neither their contents or
presence/absence are guaranteed. */
typedef struct {
const census_context *context;
int base;
int index;
char *kvm;
} census_context_iterator;
/* Initialize a census_tag_iterator. Must be called before first use. */
CENSUS_API void census_context_initialize_iterator(
const census_context *context, census_context_iterator *iterator);
/* Get the contents of the "next" tag in the context. If there are no more
tags, returns 0 (and 'tag' contents will be unchanged), otherwise returns 1.
*/
CENSUS_API int census_context_next_tag(census_context_iterator *iterator,
census_tag *tag);
/* Get a context tag by key. Returns 0 if the key is not present. */
CENSUS_API int census_context_get_tag(const census_context *context,
const char *key, census_tag *tag);
/* Tag set encode/decode functionality. These functionas are intended
for use by RPC systems only, for purposes of transmitting/receiving contexts.
*/
/* Encode a context into a buffer. The propagated tags are encoded into the
buffer in two regions: one for printable tags, and one for binary tags.
@param context context to be encoded
@param buffer pointer to buffer. This address will be used to encode the
printable tags.
@param buf_size number of available bytes in buffer.
@param print_buf_size Will be set to the number of bytes consumed by
printable tags.
@param bin_buf_size Will be set to the number of bytes used to encode the
binary tags.
@return A pointer to the binary tag's encoded, or NULL if the buffer was
insufficiently large to hold the encoded tags. Thus, if successful,
printable tags are encoded into
[buffer, buffer + *print_buf_size) and binary tags into
[returned-ptr, returned-ptr + *bin_buf_size) (and the returned
pointer should be buffer + *print_buf_size) */
CENSUS_API char *census_context_encode(const census_context *context,
char *buffer, size_t buf_size,
size_t *print_buf_size,
size_t *bin_buf_size);
/* Decode context buffers encoded with census_context_encode(). Returns NULL
if there is an error in parsing either buffer. */
CENSUS_API census_context *census_context_decode(const char *buffer,
size_t size,
const char *bin_buffer,
size_t bin_size);
/* Distributed traces can have a number of options. */
enum census_trace_mask_values {
@ -326,146 +446,6 @@ CENSUS_API int census_get_trace_record(census_trace_record *trace_record);
/** End a scan previously started by census_trace_scan_start() */
CENSUS_API void census_trace_scan_end();
/* A Census tag set is a collection of key:value string pairs; these form the
basis against which Census metrics will be recorded. Keys are unique within
a tag set. All contexts have an associated tag set. */
typedef struct census_tag_set census_tag_set;
/* A tag is a key:value pair. The key is a non-empty, printable (UTF-8
encoded), nil-terminated string. The value is a binary string, that may be
printable. There are limits on the sizes of both keys and values (see
CENSUS_MAX_TAG_KB_LEN definition below), and the number of tags that can be
propagated (CENSUS_MAX_PROPAGATED_TAGS). Users should also remember that
some systems may have limits on, e.g., the number of bytes that can be
transmitted as metadata, and that larger tags means more memory consumed
and time in processing. */
typedef struct {
const char *key;
const char *value;
size_t value_len;
uint8_t flags;
} census_tag;
/* Maximum length of a tag's key or value. */
#define CENSUS_MAX_TAG_KV_LEN 255
/* Maximum number of propagatable tags. */
#define CENSUS_MAX_PROPAGATED_TAGS 255
/* Tag flags. */
#define CENSUS_TAG_PROPAGATE 1 /* Tag should be propagated over RPC */
#define CENSUS_TAG_STATS 2 /* Tag will be used for statistics aggregation */
#define CENSUS_TAG_BINARY 4 /* Tag value is not printable */
#define CENSUS_TAG_RESERVED 8 /* Reserved for internal use. */
/* Flag values 8,16,32,64,128 are reserved for future/internal use. Clients
should not use or rely on their values. */
#define CENSUS_TAG_IS_PROPAGATED(flags) (flags & CENSUS_TAG_PROPAGATE)
#define CENSUS_TAG_IS_STATS(flags) (flags & CENSUS_TAG_STATS)
#define CENSUS_TAG_IS_BINARY(flags) (flags & CENSUS_TAG_BINARY)
typedef struct {
int n_propagated_tags; /* number of propagated printable tags */
int n_propagated_binary_tags; /* number of propagated binary tags */
int n_local_tags; /* number of non-propagated (local) tags */
int n_deleted_tags; /* number of tags that were deleted */
int n_added_tags; /* number of tags that were added */
int n_modified_tags; /* number of tags that were modified */
int n_invalid_tags; /* number of tags with bad keys or values (e.g.
longer than CENSUS_MAX_TAG_KV_LEN) */
int n_ignored_tags; /* number of tags ignored because of
CENSUS_MAX_PROPAGATED_TAGS limit. */
} census_tag_set_create_status;
/* Create a new tag set, adding and removing tags from an existing tag set.
This will copy all tags from it's input parameters, so it is recommended
to add as many tags in a single operation as is practical for the client.
@param base Base tag set to build upon. Can be NULL.
@param tags A set of tags to be added/changed/deleted. Tags with keys that
are in 'tags', but not 'base', are added to the tag set. Keys that are in
both 'tags' and 'base' will have their value/flags modified. Tags with keys
in both, but with NULL or zero-length values, will be deleted from the tag
set. Tags with invalid (too long or short) keys or values will be ignored.
If adding a tag will result in more than CENSUS_MAX_PROPAGATED_TAGS in either
binary or non-binary tags, they will be ignored, as will deletions of
tags that don't exist.
@param ntags number of tags in 'tags'
@param status If not NULL, will return a pointer to a
census_tag_set_create_status structure containing information about the new
tag set and status of the tags used in its creation.
@return A new, valid census_tag_set.
*/
CENSUS_API census_tag_set *census_tag_set_create(
const census_tag_set *base, const census_tag *tags, int ntags,
census_tag_set_create_status const **status);
/* Destroy a tag set created by census_tag_set_create(). Once this function
has been called, the tag set cannot be reused. */
CENSUS_API void census_tag_set_destroy(census_tag_set *tags);
/* Get a pointer to the original status from the creation of this tag set. */
CENSUS_API const census_tag_set_create_status *census_tag_set_get_create_status(
const census_tag_set *tags);
/* Structure used for tag set iteration. API clients should not use or
reference internal fields - neither their contents or presence/absence are
guaranteed. */
typedef struct {
const census_tag_set *tags;
int base;
int index;
char *kvm;
} census_tag_set_iterator;
/* Initialize a tag set iterator. Must be called before first use of the
iterator. */
CENSUS_API void census_tag_set_initialize_iterator(
const census_tag_set *tags, census_tag_set_iterator *iterator);
/* Get the contents of the "next" tag in the tag set. If there are no more
tags in the tag set, returns 0 (and 'tag' contents will be unchanged),
otherwise returns 1. */
CENSUS_API int census_tag_set_next_tag(census_tag_set_iterator *iterator,
census_tag *tag);
/* Get a tag by its key. Returns 0 if the key is not present in the tag
set. */
CENSUS_API int census_tag_set_get_tag_by_key(const census_tag_set *tags,
const char *key, census_tag *tag);
/* Tag set encode/decode functionality. These functionas are intended
for use by RPC systems only, for purposes of transmitting/receiving tag
sets. */
/* Encode a tag set into a buffer. The propagated tags are encoded into the
buffer in two regions: one for printable tags, and one for binary tags.
@param tags tag set to be encoded
@param buffer pointer to buffer. This address will be used to encode the
printable tags.
@param buf_size number of available bytes in buffer.
@param print_buf_size Will be set to the number of bytes consumed by
printable tags.
@param bin_buf_size Will be set to the number of bytes used to encode the
binary tags.
@return A pointer to the binary tag's encoded, or NULL if the buffer was
insufficiently large to hold the encoded tags. Thus, if successful,
printable tags are encoded into
[buffer, buffer + *print_buf_size) and binary tags into
[returned-ptr, returned-ptr + *bin_buf_size) (and the return value
should be buffer + *print_buf_size) */
CENSUS_API char *census_tag_set_encode(const census_tag_set *tags, char *buffer,
size_t buf_size, size_t *print_buf_size,
size_t *bin_buf_size);
/* Decode tag set buffers encoded with census_tag_set_encode_*(). Returns NULL
if there is an error in parsing either buffer. */
CENSUS_API census_tag_set *census_tag_set_decode(const char *buffer,
size_t size,
const char *bin_buffer,
size_t bin_size);
/* Get a contexts tag set. */
CENSUS_API census_tag_set *census_context_tag_set(census_context *context);
/* Core stats collection API's. The following concepts are used:
* Aggregation: A collection of values. Census supports the following
aggregation types:
@ -511,8 +491,7 @@ extern census_aggregation_ops census_agg_window;
construction via census_define_view(). */
typedef struct {
const census_aggregation_ops *ops;
const void *
create_arg; /* Argument to be used for aggregation initialization. */
const void *create_arg; /* Aaggregation initialization argument. */
} census_aggregation;
/** A census view type. Opaque. */
@ -520,14 +499,17 @@ typedef struct census_view census_view;
/** Create a new view.
@param metric_id Metric with which this view is associated.
@param tags tags that define the view
@param tags tags that define the view.
@param aggregations aggregations to associate with the view
@param naggregations number of aggregations
@return A new census view
*/
/* TODO(aveitch): consider if context is the right argument type to pass in
tags. */
CENSUS_API census_view *census_view_create(
uint32_t metric_id, const census_tag_set *tags,
uint32_t metric_id, const census_context *tags,
const census_aggregation *aggregations, size_t naggregations);
/** Destroy a previously created view. */
@ -540,7 +522,7 @@ CENSUS_API size_t census_view_metric(const census_view *view);
CENSUS_API size_t census_view_naggregations(const census_view *view);
/** Get tags associated with view. */
CENSUS_API const census_tag_set *census_view_tags(const census_view *view);
CENSUS_API const census_context *census_view_tags(const census_view *view);
/** Get aggregation descriptors associated with a view. */
CENSUS_API const census_aggregation *census_view_aggregrations(
@ -549,7 +531,7 @@ CENSUS_API const census_aggregation *census_view_aggregrations(
/** Holds all the aggregation data for a particular view instantiation. Forms
part of the data returned by census_view_data(). */
typedef struct {
const census_tag_set *tags; /* Tags for this set of aggregations. */
const census_context *tags; /* Tags for this set of aggregations. */
const void **data; /* One data set for every aggregation in the view. */
} census_view_aggregation_data;

@ -280,7 +280,6 @@
"src/core/support/thd_internal.h",
"src/core/support/time_precise.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/rpc_metric_id.h",
"src/core/httpcli/httpcli_security_connector.c",
"src/core/security/base64.c",
@ -477,7 +476,6 @@
"src/core/census/initialize.c",
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
"third_party/zlib/crc32.h",
"third_party/zlib/deflate.h",

@ -1,6 +1,6 @@
/*
*
* Copyright 2015, Google Inc.
* Copyright 2015-2016, Google Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@ -31,16 +31,500 @@
*
*/
#include "src/core/census/context.h"
#include <string.h>
#include <grpc/census.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/useful.h>
#include <stdbool.h>
#include <string.h>
#include "src/core/support/string.h"
// Functions in this file support the public context API, including
// encoding/decoding as part of context propagation across RPC's. The overall
// requirements (in approximate priority order) for the
// context representation:
// 1. Efficient conversion to/from wire format
// 2. Minimal bytes used on-wire
// 3. Efficient context creation
// 4. Efficient lookup of tag value for a key
// 5. Efficient iteration over tags
// 6. Minimal memory footprint
//
// Notes on tradeoffs/decisions:
// * tag includes 1 byte length of key, as well as nil-terminating byte. These
// are to aid in efficient parsing and the ability to directly return key
// strings. This is more important than saving a single byte/tag on the wire.
// * The wire encoding uses only single byte values. This eliminates the need
// to handle endian-ness conversions. It also means there is a hard upper
// limit of 255 for both CENSUS_MAX_TAG_KV_LEN and CENSUS_MAX_PROPAGATED_TAGS.
// * Keep all tag information (keys/values/flags) in a single memory buffer,
// that can be directly copied to the wire.
// * Binary tags share the same structure as, but are encoded separately from,
// non-binary tags. This is primarily because non-binary tags are far more
// likely to be repeated across multiple RPC calls, so are more efficiently
// cached and compressed in any metadata schemes.
// Structure representing a set of tags. Essentially a count of number of tags
// present, and pointer to a chunk of memory that contains the per-tag details.
struct tag_set {
int ntags; // number of tags.
int ntags_alloc; // ntags + number of deleted tags (total number of tags
// in all of kvm). This will always be == ntags, except during the process
// of building a new tag set.
size_t kvm_size; // number of bytes allocated for key/value storage.
size_t kvm_used; // number of bytes of used key/value memory
char *kvm; // key/value memory. Consists of repeated entries of:
// Offset Size Description
// 0 1 Key length, including trailing 0. (K)
// 1 1 Value length. (V)
// 2 1 Flags
// 3 K Key bytes
// 3 + K V Value bytes
//
// We refer to the first 3 entries as the 'tag header'. If extra values are
// introduced in the header, you will need to modify the TAG_HEADER_SIZE
// constant, the raw_tag structure (and everything that uses it) and the
// encode/decode functions appropriately.
};
// Number of bytes in tag header.
#define TAG_HEADER_SIZE 3 // key length (1) + value length (1) + flags (1)
// Offsets to tag header entries.
#define KEY_LEN_OFFSET 0
#define VALUE_LEN_OFFSET 1
#define FLAG_OFFSET 2
// raw_tag represents the raw-storage form of a tag in the kvm of a tag_set.
struct raw_tag {
uint8_t key_len;
uint8_t value_len;
uint8_t flags;
char *key;
char *value;
};
// Use a reserved flag bit for indication of deleted tag.
#define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED
#define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED)
// Primary (external) representation of a context. Composed of 3 underlying
// tag_set structs, one for each of the binary/printable propagated tags, and
// one for everything else. This is to efficiently support tag
// encoding/decoding.
struct census_context {
struct tag_set tags[3];
census_context_status status;
};
// Indices into the tags member of census_context
#define PROPAGATED_TAGS 0
#define PROPAGATED_BINARY_TAGS 1
#define LOCAL_TAGS 2
// Extract a raw tag given a pointer (raw) to the tag header. Allow for some
// extra bytes in the tag header (see encode/decode functions for usage: this
// allows for future expansion of the tag header).
static char *decode_tag(struct raw_tag *tag, char *header, int offset) {
tag->key_len = (uint8_t)(*header++);
tag->value_len = (uint8_t)(*header++);
tag->flags = (uint8_t)(*header++);
header += offset;
tag->key = header;
header += tag->key_len;
tag->value = header;
return header + tag->value_len;
}
/* Placeholder implementation only. */
// Make a copy (in 'to') of an existing tag_set.
static void tag_set_copy(struct tag_set *to, const struct tag_set *from) {
memcpy(to, from, sizeof(struct tag_set));
to->kvm = gpr_malloc(to->kvm_size);
memcpy(to->kvm, from->kvm, from->kvm_used);
}
// Delete a tag from a tag_set, if it exists (returns true if it did).
static bool tag_set_delete_tag(struct tag_set *tags, const char *key,
size_t key_len) {
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags_alloc; i++) {
uint8_t *flags = (uint8_t *)(kvp + FLAG_OFFSET);
struct raw_tag tag;
kvp = decode_tag(&tag, kvp, 0);
if (CENSUS_TAG_IS_DELETED(tag.flags)) continue;
if ((key_len == tag.key_len) && (memcmp(key, tag.key, key_len) == 0)) {
*flags |= CENSUS_TAG_DELETED;
tags->ntags--;
return true;
}
}
return false;
}
// Delete a tag from a context, return true if it existed.
static bool context_delete_tag(census_context *context, const census_tag *tag,
size_t key_len) {
return (
tag_set_delete_tag(&context->tags[LOCAL_TAGS], tag->key, key_len) ||
tag_set_delete_tag(&context->tags[PROPAGATED_TAGS], tag->key, key_len) ||
tag_set_delete_tag(&context->tags[PROPAGATED_BINARY_TAGS], tag->key,
key_len));
}
// Add a tag to a tag_set. Return true on success, false if the tag could
// not be added because of constraints on tag set size. This function should
// not be called if the tag may already exist (in a non-deleted state) in
// the tag_set, as that would result in two tags with the same key.
static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
size_t key_len) {
if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) {
return false;
}
const size_t tag_size = key_len + tag->value_len + TAG_HEADER_SIZE;
if (tags->kvm_used + tag_size > tags->kvm_size) {
// allocate new memory if needed
tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
char *new_kvm = gpr_malloc(tags->kvm_size);
memcpy(new_kvm, tags->kvm, tags->kvm_used);
gpr_free(tags->kvm);
tags->kvm = new_kvm;
}
char *kvp = tags->kvm + tags->kvm_used;
*kvp++ = (char)key_len;
*kvp++ = (char)tag->value_len;
// ensure reserved flags are not used.
*kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS |
CENSUS_TAG_BINARY));
memcpy(kvp, tag->key, key_len);
kvp += key_len;
memcpy(kvp, tag->value, tag->value_len);
tags->kvm_used += tag_size;
tags->ntags++;
tags->ntags_alloc++;
return true;
}
// Add/modify/delete a tag to/in a context. Caller must validate that tag key
// etc. are valid.
static void context_modify_tag(census_context *context, const census_tag *tag,
size_t key_len) {
// First delete the tag if it is already present.
bool deleted = context_delete_tag(context, tag, key_len);
// Determine if we need to add it back.
bool call_add = tag->value != NULL && tag->value_len != 0;
bool added = false;
if (call_add) {
if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) {
if (CENSUS_TAG_IS_BINARY(tag->flags)) {
added = tag_set_add_tag(&context->tags[PROPAGATED_BINARY_TAGS], tag,
key_len);
} else {
added = tag_set_add_tag(&context->tags[PROPAGATED_TAGS], tag, key_len);
}
} else {
added = tag_set_add_tag(&context->tags[LOCAL_TAGS], tag, key_len);
}
}
if (deleted) {
if (call_add) {
context->status.n_modified_tags++;
} else {
context->status.n_deleted_tags++;
}
} else {
if (added) {
context->status.n_added_tags++;
} else {
context->status.n_ignored_tags++;
}
}
}
// Remove memory used for deleted tags from a tag set. Basic algorithm:
// 1) Walk through tag set to find first deleted tag. Record where it is.
// 2) Find the next not-deleted tag. Copy all of kvm from there to the end
// "over" the deleted tags
// 3) repeat #1 and #2 until we have seen all tags
// 4) if we are still looking for a not-deleted tag, then all the end portion
// of the kvm is deleted. Just reduce the used amount of memory by the
// appropriate amount.
static void tag_set_flatten(struct tag_set *tags) {
if (tags->ntags == tags->ntags_alloc) return;
bool found_deleted = false; // found a deleted tag.
char *kvp = tags->kvm;
char *dbase = NULL; // record location of deleted tag
for (int i = 0; i < tags->ntags_alloc; i++) {
struct raw_tag tag;
char *next_kvp = decode_tag(&tag, kvp, 0);
if (found_deleted) {
if (!CENSUS_TAG_IS_DELETED(tag.flags)) {
ptrdiff_t reduce = kvp - dbase; // #bytes in deleted tags
GPR_ASSERT(reduce > 0);
ptrdiff_t copy_size = tags->kvm + tags->kvm_used - kvp;
GPR_ASSERT(copy_size > 0);
memmove(dbase, kvp, (size_t)copy_size);
tags->kvm_used -= (size_t)reduce;
next_kvp -= reduce;
found_deleted = false;
}
} else {
if (CENSUS_TAG_IS_DELETED(tag.flags)) {
dbase = kvp;
found_deleted = true;
}
}
kvp = next_kvp;
}
if (found_deleted) {
GPR_ASSERT(dbase > tags->kvm);
tags->kvm_used = (size_t)(dbase - tags->kvm);
}
tags->ntags_alloc = tags->ntags;
}
size_t census_context_serialize(const census_context *context, char *buffer,
size_t buf_size) {
/* TODO(aveitch): implement serialization */
census_context *census_context_create(const census_context *base,
const census_tag *tags, int ntags,
census_context_status const **status) {
census_context *context = gpr_malloc(sizeof(census_context));
// If we are given a base, copy it into our new tag set. Otherwise set it
// to zero/NULL everything.
if (base == NULL) {
memset(context, 0, sizeof(census_context));
} else {
tag_set_copy(&context->tags[PROPAGATED_TAGS], &base->tags[PROPAGATED_TAGS]);
tag_set_copy(&context->tags[PROPAGATED_BINARY_TAGS],
&base->tags[PROPAGATED_BINARY_TAGS]);
tag_set_copy(&context->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]);
memset(&context->status, 0, sizeof(context->status));
}
// Walk over the additional tags and, for those that aren't invalid, modify
// the context to add/replace/delete as required.
for (int i = 0; i < ntags; i++) {
const census_tag *tag = &tags[i];
size_t key_len = strlen(tag->key) + 1;
// ignore the tag if it is too long/short.
if (key_len != 1 && key_len <= CENSUS_MAX_TAG_KV_LEN &&
tag->value_len <= CENSUS_MAX_TAG_KV_LEN) {
context_modify_tag(context, tag, key_len);
} else {
context->status.n_invalid_tags++;
}
}
// Remove any deleted tags, update status if needed, and return.
tag_set_flatten(&context->tags[PROPAGATED_TAGS]);
tag_set_flatten(&context->tags[PROPAGATED_BINARY_TAGS]);
tag_set_flatten(&context->tags[LOCAL_TAGS]);
context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
context->status.n_propagated_binary_tags =
context->tags[PROPAGATED_BINARY_TAGS].ntags;
context->status.n_local_tags = context->tags[LOCAL_TAGS].ntags;
if (status) {
*status = &context->status;
}
return context;
}
const census_context_status *census_context_get_status(
const census_context *context) {
return &context->status;
}
void census_context_destroy(census_context *context) {
gpr_free(context->tags[PROPAGATED_TAGS].kvm);
gpr_free(context->tags[PROPAGATED_BINARY_TAGS].kvm);
gpr_free(context->tags[LOCAL_TAGS].kvm);
gpr_free(context);
}
void census_context_initialize_iterator(const census_context *context,
census_context_iterator *iterator) {
iterator->context = context;
iterator->index = 0;
if (context->tags[PROPAGATED_TAGS].ntags != 0) {
iterator->base = PROPAGATED_TAGS;
iterator->kvm = context->tags[PROPAGATED_TAGS].kvm;
} else if (context->tags[PROPAGATED_BINARY_TAGS].ntags != 0) {
iterator->base = PROPAGATED_BINARY_TAGS;
iterator->kvm = context->tags[PROPAGATED_BINARY_TAGS].kvm;
} else if (context->tags[LOCAL_TAGS].ntags != 0) {
iterator->base = LOCAL_TAGS;
iterator->kvm = context->tags[LOCAL_TAGS].kvm;
} else {
iterator->base = -1;
}
}
int census_context_next_tag(census_context_iterator *iterator,
census_tag *tag) {
if (iterator->base < 0) {
return 0;
}
struct raw_tag raw;
iterator->kvm = decode_tag(&raw, iterator->kvm, 0);
tag->key = raw.key;
tag->value = raw.value;
tag->value_len = raw.value_len;
tag->flags = raw.flags;
if (++iterator->index == iterator->context->tags[iterator->base].ntags) {
do {
if (iterator->base == LOCAL_TAGS) {
iterator->base = -1;
return 1;
}
} while (iterator->context->tags[++iterator->base].ntags == 0);
iterator->index = 0;
iterator->kvm = iterator->context->tags[iterator->base].kvm;
}
return 1;
}
// Find a tag in a tag_set by key. Return true if found, false otherwise.
static bool tag_set_get_tag(const struct tag_set *tags, const char *key,
size_t key_len, census_tag *tag) {
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags; i++) {
struct raw_tag raw;
kvp = decode_tag(&raw, kvp, 0);
if (key_len == raw.key_len && memcmp(raw.key, key, key_len) == 0) {
tag->key = raw.key;
tag->value = raw.value;
tag->value_len = raw.value_len;
tag->flags = raw.flags;
return true;
}
}
return false;
}
int census_context_get_tag(const census_context *context, const char *key,
census_tag *tag) {
size_t key_len = strlen(key) + 1;
if (key_len == 1) {
return 0;
}
if (tag_set_get_tag(&context->tags[PROPAGATED_TAGS], key, key_len, tag) ||
tag_set_get_tag(&context->tags[PROPAGATED_BINARY_TAGS], key, key_len,
tag) ||
tag_set_get_tag(&context->tags[LOCAL_TAGS], key, key_len, tag)) {
return 1;
}
return 0;
}
// Context encoding and decoding functions.
//
// Wire format for tag_set's on the wire:
//
// First, a tag set header:
//
// offset bytes description
// 0 1 version number
// 1 1 number of bytes in this header. This allows for future
// expansion.
// 2 1 number of bytes in each tag header.
// 3 1 ntags value from tag set.
//
// This is followed by the key/value memory from struct tag_set.
#define ENCODED_VERSION 0 // Version number
#define ENCODED_HEADER_SIZE 4 // size of tag set header
// Encode a tag set. Returns 0 if buffer is too small.
static size_t tag_set_encode(const struct tag_set *tags, char *buffer,
size_t buf_size) {
if (buf_size < ENCODED_HEADER_SIZE + tags->kvm_used) {
return 0;
}
buf_size -= ENCODED_HEADER_SIZE;
*buffer++ = (char)ENCODED_VERSION;
*buffer++ = (char)ENCODED_HEADER_SIZE;
*buffer++ = (char)TAG_HEADER_SIZE;
*buffer++ = (char)tags->ntags;
if (tags->ntags == 0) {
return ENCODED_HEADER_SIZE;
}
memcpy(buffer, tags->kvm, tags->kvm_used);
return ENCODED_HEADER_SIZE + tags->kvm_used;
}
char *census_context_encode(const census_context *context, char *buffer,
size_t buf_size, size_t *print_buf_size,
size_t *bin_buf_size) {
*print_buf_size =
tag_set_encode(&context->tags[PROPAGATED_TAGS], buffer, buf_size);
if (*print_buf_size == 0) {
return NULL;
}
char *b_buffer = buffer + *print_buf_size;
*bin_buf_size = tag_set_encode(&context->tags[PROPAGATED_BINARY_TAGS],
b_buffer, buf_size - *print_buf_size);
if (*bin_buf_size == 0) {
return NULL;
}
return b_buffer;
}
// Decode a tag set.
static void tag_set_decode(struct tag_set *tags, const char *buffer,
size_t size) {
uint8_t version = (uint8_t)(*buffer++);
uint8_t header_size = (uint8_t)(*buffer++);
uint8_t tag_header_size = (uint8_t)(*buffer++);
tags->ntags = tags->ntags_alloc = (int)(*buffer++);
if (tags->ntags == 0) {
tags->ntags_alloc = 0;
tags->kvm_size = 0;
tags->kvm_used = 0;
tags->kvm = NULL;
return;
}
if (header_size != ENCODED_HEADER_SIZE) {
GPR_ASSERT(version != ENCODED_VERSION);
GPR_ASSERT(ENCODED_HEADER_SIZE < header_size);
buffer += (header_size - ENCODED_HEADER_SIZE);
}
tags->kvm_used = size - header_size;
tags->kvm_size = tags->kvm_used + CENSUS_MAX_TAG_KV_LEN;
tags->kvm = gpr_malloc(tags->kvm_size);
if (tag_header_size != TAG_HEADER_SIZE) {
// something new in the tag information. I don't understand it, so
// don't copy it over.
GPR_ASSERT(version != ENCODED_VERSION);
GPR_ASSERT(tag_header_size > TAG_HEADER_SIZE);
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags; i++) {
memcpy(kvp, buffer, TAG_HEADER_SIZE);
kvp += header_size;
struct raw_tag raw;
buffer =
decode_tag(&raw, (char *)buffer, tag_header_size - TAG_HEADER_SIZE);
memcpy(kvp, raw.key, (size_t)raw.key_len + raw.value_len);
kvp += raw.key_len + raw.value_len;
}
} else {
memcpy(tags->kvm, buffer, tags->kvm_used);
}
}
census_context *census_context_decode(const char *buffer, size_t size,
const char *bin_buffer, size_t bin_size) {
census_context *context = gpr_malloc(sizeof(census_context));
memset(&context->tags[LOCAL_TAGS], 0, sizeof(struct tag_set));
if (buffer == NULL) {
memset(&context->tags[PROPAGATED_TAGS], 0, sizeof(struct tag_set));
} else {
tag_set_decode(&context->tags[PROPAGATED_TAGS], buffer, size);
}
if (bin_buffer == NULL) {
memset(&context->tags[PROPAGATED_BINARY_TAGS], 0, sizeof(struct tag_set));
} else {
tag_set_decode(&context->tags[PROPAGATED_BINARY_TAGS], bin_buffer,
bin_size);
}
memset(&context->status, 0, sizeof(context->status));
context->status.n_propagated_tags = context->tags[PROPAGATED_TAGS].ntags;
context->status.n_propagated_binary_tags =
context->tags[PROPAGATED_BINARY_TAGS].ntags;
// TODO(aveitch): check that BINARY flag is correct for each type.
return context;
}

@ -1,47 +0,0 @@
/*
*
* 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.
*
*/
#ifndef GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H
#define GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H
#include <grpc/census.h>
#define GRPC_CENSUS_MAX_ON_THE_WIRE_TAG_BYTES 2048
/* census_context is the in-memory representation of information needed to
* maintain tracing, RPC statistics and resource usage information. */
struct census_context {
census_tag_set *tags; /* Opaque data structure for census tags. */
};
#endif /* GRPC_INTERNAL_CORE_CENSUS_CONTEXT_H */

@ -37,11 +37,6 @@
/* Placeholders for the pending APIs */
census_tag_set *census_context_tag_set(census_context *context) {
(void)context;
abort();
}
int census_get_trace_record(census_trace_record *trace_record) {
(void)trace_record;
abort();
@ -73,7 +68,7 @@ const census_aggregation *census_view_aggregrations(const census_view *view) {
abort();
}
census_view *census_view_create(uint32_t metric_id, const census_tag_set *tags,
census_view *census_view_create(uint32_t metric_id, const census_context *tags,
const census_aggregation *aggregations,
size_t naggregations) {
(void)metric_id;
@ -83,7 +78,7 @@ census_view *census_view_create(uint32_t metric_id, const census_tag_set *tags,
abort();
}
const census_tag_set *census_view_tags(const census_view *view) {
const census_context *census_view_tags(const census_view *view) {
(void)view;
abort();
}

@ -1,535 +0,0 @@
/*
*
* Copyright 2015-2016, 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 <grpc/census.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/port_platform.h>
#include <grpc/support/useful.h>
#include <stdbool.h>
#include <string.h>
#include "src/core/support/string.h"
// Functions in this file support the public tag_set API, as well as
// encoding/decoding tag_sets as part of context propagation across
// RPC's. The overall requirements (in approximate priority order) for the
// tag_set representations:
// 1. Efficient conversion to/from wire format
// 2. Minimal bytes used on-wire
// 3. Efficient tag set creation
// 4. Efficient lookup of value for a key
// 5. Efficient lookup of value for an index (to support iteration)
// 6. Minimal memory footprint
//
// Notes on tradeoffs/decisions:
// * tag includes 1 byte length of key, as well as nil-terminating byte. These
// are to aid in efficient parsing and the ability to directly return key
// strings. This is more important than saving a single byte/tag on the wire.
// * The wire encoding uses only single byte values. This eliminates the need
// to handle endian-ness conversions. It also means there is a hard upper
// limit of 255 for both CENSUS_MAX_TAG_KV_LEN and CENSUS_MAX_PROPAGATED_TAGS.
// * Keep all tag information (keys/values/flags) in a single memory buffer,
// that can be directly copied to the wire.14
// * Binary tags share the same structure as, but are encoded separately from,
// non-binary tags. This is primarily because non-binary tags are far more
// likely to be repeated across multiple RPC calls, so are more efficiently
// cached and compressed in any metadata schemes.
// * all lengths etc. are restricted to one byte. This eliminates endian
// issues.
// Structure representing a set of tags. Essentially a count of number of tags
// present, and pointer to a chunk of memory that contains the per-tag details.
struct tag_set {
int ntags; // number of tags.
int ntags_alloc; // ntags + number of deleted tags (total number of tags
// in all of kvm). This will always be == ntags, except during the process
// of building a new tag set.
size_t kvm_size; // number of bytes allocated for key/value storage.
size_t kvm_used; // number of bytes of used key/value memory
char *kvm; // key/value memory. Consists of repeated entries of:
// Offset Size Description
// 0 1 Key length, including trailing 0. (K)
// 1 1 Value length. (V)
// 2 1 Flags
// 3 K Key bytes
// 3 + K V Value bytes
//
// We refer to the first 3 entries as the 'tag header'. If extra values are
// introduced in the header, you will need to modify the TAG_HEADER_SIZE
// constant, the raw_tag structure (and everything that uses it) and the
// encode/decode functions appropriately.
};
// Number of bytes in tag header.
#define TAG_HEADER_SIZE 3 // key length (1) + value length (1) + flags (1)
// Offsets to tag header entries.
#define KEY_LEN_OFFSET 0
#define VALUE_LEN_OFFSET 1
#define FLAG_OFFSET 2
// raw_tag represents the raw-storage form of a tag in the kvm of a tag_set.
struct raw_tag {
uint8_t key_len;
uint8_t value_len;
uint8_t flags;
char *key;
char *value;
};
// Use a reserved flag bit for indication of deleted tag.
#define CENSUS_TAG_DELETED CENSUS_TAG_RESERVED
#define CENSUS_TAG_IS_DELETED(flags) (flags & CENSUS_TAG_DELETED)
// Primary (external) representation of a tag set. Composed of 3 underlying
// tag_set structs, one for each of the binary/printable propagated tags, and
// one for everything else. This is to efficiently support tag
// encoding/decoding.
struct census_tag_set {
struct tag_set tags[3];
census_tag_set_create_status status;
};
// Indices into the tags member of census_tag_set
#define PROPAGATED_TAGS 0
#define PROPAGATED_BINARY_TAGS 1
#define LOCAL_TAGS 2
// Extract a raw tag given a pointer (raw) to the tag header. Allow for some
// extra bytes in the tag header (see encode/decode functions for usage: this
// allows for future expansion of the tag header).
static char *decode_tag(struct raw_tag *tag, char *header, int offset) {
tag->key_len = (uint8_t)(*header++);
tag->value_len = (uint8_t)(*header++);
tag->flags = (uint8_t)(*header++);
header += offset;
tag->key = header;
header += tag->key_len;
tag->value = header;
return header + tag->value_len;
}
// Make a copy (in 'to') of an existing tag_set.
static void tag_set_copy(struct tag_set *to, const struct tag_set *from) {
memcpy(to, from, sizeof(struct tag_set));
to->kvm = gpr_malloc(to->kvm_size);
memcpy(to->kvm, from->kvm, from->kvm_used);
}
// Delete a tag from a tag_set, if it exists (returns true if it did).
static bool tag_set_delete_tag(struct tag_set *tags, const char *key,
size_t key_len) {
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags_alloc; i++) {
uint8_t *flags = (uint8_t *)(kvp + FLAG_OFFSET);
struct raw_tag tag;
kvp = decode_tag(&tag, kvp, 0);
if (CENSUS_TAG_IS_DELETED(tag.flags)) continue;
if ((key_len == tag.key_len) && (memcmp(key, tag.key, key_len) == 0)) {
*flags |= CENSUS_TAG_DELETED;
tags->ntags--;
return true;
}
}
return false;
}
// Delete a tag from a census_tag_set, return true if it existed.
static bool cts_delete_tag(census_tag_set *tags, const census_tag *tag,
size_t key_len) {
return (tag_set_delete_tag(&tags->tags[LOCAL_TAGS], tag->key, key_len) ||
tag_set_delete_tag(&tags->tags[PROPAGATED_TAGS], tag->key, key_len) ||
tag_set_delete_tag(&tags->tags[PROPAGATED_BINARY_TAGS], tag->key,
key_len));
}
// Add a tag to a tag_set. Return true on sucess, false if the tag could
// not be added because of constraints on tag set size. This function should
// not be called if the tag may already exist (in a non-deleted state) in
// the tag_set, as that would result in two tags with the same key.
static bool tag_set_add_tag(struct tag_set *tags, const census_tag *tag,
size_t key_len) {
if (tags->ntags == CENSUS_MAX_PROPAGATED_TAGS) {
return false;
}
const size_t tag_size = key_len + tag->value_len + TAG_HEADER_SIZE;
if (tags->kvm_used + tag_size > tags->kvm_size) {
// allocate new memory if needed
tags->kvm_size += 2 * CENSUS_MAX_TAG_KV_LEN + TAG_HEADER_SIZE;
char *new_kvm = gpr_malloc(tags->kvm_size);
memcpy(new_kvm, tags->kvm, tags->kvm_used);
gpr_free(tags->kvm);
tags->kvm = new_kvm;
}
char *kvp = tags->kvm + tags->kvm_used;
*kvp++ = (char)key_len;
*kvp++ = (char)tag->value_len;
// ensure reserved flags are not used.
*kvp++ = (char)(tag->flags & (CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS |
CENSUS_TAG_BINARY));
memcpy(kvp, tag->key, key_len);
kvp += key_len;
memcpy(kvp, tag->value, tag->value_len);
tags->kvm_used += tag_size;
tags->ntags++;
tags->ntags_alloc++;
return true;
}
// Add/modify/delete a tag to/in a census_tag_set. Caller must validate that
// tag key etc. are valid.
static void cts_modify_tag(census_tag_set *tags, const census_tag *tag,
size_t key_len) {
// First delete the tag if it is already present.
bool deleted = cts_delete_tag(tags, tag, key_len);
// Determine if we need to add it back.
bool call_add = tag->value != NULL && tag->value_len != 0;
bool added = false;
if (call_add) {
if (CENSUS_TAG_IS_PROPAGATED(tag->flags)) {
if (CENSUS_TAG_IS_BINARY(tag->flags)) {
added =
tag_set_add_tag(&tags->tags[PROPAGATED_BINARY_TAGS], tag, key_len);
} else {
added = tag_set_add_tag(&tags->tags[PROPAGATED_TAGS], tag, key_len);
}
} else {
added = tag_set_add_tag(&tags->tags[LOCAL_TAGS], tag, key_len);
}
}
if (deleted) {
if (call_add) {
tags->status.n_modified_tags++;
} else {
tags->status.n_deleted_tags++;
}
} else {
if (added) {
tags->status.n_added_tags++;
} else {
tags->status.n_ignored_tags++;
}
}
}
// Remove memory used for deleted tags from the tag set. Basic algorithm:
// 1) Walk through tag set to find first deleted tag. Record where it is.
// 2) Find the next not-deleted tag. Copy all of kvm from there to the end
// "over" the deleted tags
// 3) repeat #1 and #2 until we have seen all tags
// 4) if we are still looking for a not-deleted tag, then all the end portion
// of the kvm is deleted. Just reduce the used amount of memory by the
// appropriate amount.
static void tag_set_flatten(struct tag_set *tags) {
if (tags->ntags == tags->ntags_alloc) return;
bool found_deleted = false; // found a deleted tag.
char *kvp = tags->kvm;
char *dbase = NULL; // record location of deleted tag
for (int i = 0; i < tags->ntags_alloc; i++) {
struct raw_tag tag;
char *next_kvp = decode_tag(&tag, kvp, 0);
if (found_deleted) {
if (!CENSUS_TAG_IS_DELETED(tag.flags)) {
ptrdiff_t reduce = kvp - dbase; // #bytes in deleted tags
GPR_ASSERT(reduce > 0);
ptrdiff_t copy_size = tags->kvm + tags->kvm_used - kvp;
GPR_ASSERT(copy_size > 0);
memmove(dbase, kvp, (size_t)copy_size);
tags->kvm_used -= (size_t)reduce;
next_kvp -= reduce;
found_deleted = false;
}
} else {
if (CENSUS_TAG_IS_DELETED(tag.flags)) {
dbase = kvp;
found_deleted = true;
}
}
kvp = next_kvp;
}
if (found_deleted) {
GPR_ASSERT(dbase > tags->kvm);
tags->kvm_used = (size_t)(dbase - tags->kvm);
}
tags->ntags_alloc = tags->ntags;
}
census_tag_set *census_tag_set_create(
const census_tag_set *base, const census_tag *tags, int ntags,
census_tag_set_create_status const **status) {
census_tag_set *new_ts = gpr_malloc(sizeof(census_tag_set));
// If we are given a base, copy it into our new tag set. Otherwise set it
// to zero/NULL everything.
if (base == NULL) {
memset(new_ts, 0, sizeof(census_tag_set));
} else {
tag_set_copy(&new_ts->tags[PROPAGATED_TAGS], &base->tags[PROPAGATED_TAGS]);
tag_set_copy(&new_ts->tags[PROPAGATED_BINARY_TAGS],
&base->tags[PROPAGATED_BINARY_TAGS]);
tag_set_copy(&new_ts->tags[LOCAL_TAGS], &base->tags[LOCAL_TAGS]);
memset(&new_ts->status, 0, sizeof(new_ts->status));
}
// Walk over the additional tags and, for those that aren't invalid, modify
// the tag set to add/replace/delete as required.
for (int i = 0; i < ntags; i++) {
const census_tag *tag = &tags[i];
size_t key_len = strlen(tag->key) + 1;
// ignore the tag if it is too long/short.
if (key_len != 1 && key_len <= CENSUS_MAX_TAG_KV_LEN &&
tag->value_len <= CENSUS_MAX_TAG_KV_LEN) {
cts_modify_tag(new_ts, tag, key_len);
} else {
new_ts->status.n_invalid_tags++;
}
}
// Remove any deleted tags, update status if needed, and return.
tag_set_flatten(&new_ts->tags[PROPAGATED_TAGS]);
tag_set_flatten(&new_ts->tags[PROPAGATED_BINARY_TAGS]);
tag_set_flatten(&new_ts->tags[LOCAL_TAGS]);
new_ts->status.n_propagated_tags = new_ts->tags[PROPAGATED_TAGS].ntags;
new_ts->status.n_propagated_binary_tags =
new_ts->tags[PROPAGATED_BINARY_TAGS].ntags;
new_ts->status.n_local_tags = new_ts->tags[LOCAL_TAGS].ntags;
if (status) {
*status = &new_ts->status;
}
return new_ts;
}
const census_tag_set_create_status *census_tag_set_get_create_status(
const census_tag_set *tags) {
return &tags->status;
}
void census_tag_set_destroy(census_tag_set *tags) {
gpr_free(tags->tags[PROPAGATED_TAGS].kvm);
gpr_free(tags->tags[PROPAGATED_BINARY_TAGS].kvm);
gpr_free(tags->tags[LOCAL_TAGS].kvm);
gpr_free(tags);
}
// Initialize a tag set iterator. Must be called before first use of the
// iterator.
void census_tag_set_initialize_iterator(const census_tag_set *tags,
census_tag_set_iterator *iterator) {
iterator->tags = tags;
iterator->index = 0;
if (tags->tags[PROPAGATED_TAGS].ntags != 0) {
iterator->base = PROPAGATED_TAGS;
iterator->kvm = tags->tags[PROPAGATED_TAGS].kvm;
} else if (tags->tags[PROPAGATED_BINARY_TAGS].ntags != 0) {
iterator->base = PROPAGATED_BINARY_TAGS;
iterator->kvm = tags->tags[PROPAGATED_BINARY_TAGS].kvm;
} else if (tags->tags[LOCAL_TAGS].ntags != 0) {
iterator->base = LOCAL_TAGS;
iterator->kvm = tags->tags[LOCAL_TAGS].kvm;
} else {
iterator->base = -1;
}
}
// Get the contents of the "next" tag in the tag set. If there are no more
// tags in the tag set, returns 0 (and 'tag' contents will be unchanged),
// otherwise returns 1. */
int census_tag_set_next_tag(census_tag_set_iterator *iterator,
census_tag *tag) {
if (iterator->base < 0) {
return 0;
}
struct raw_tag raw;
iterator->kvm = decode_tag(&raw, iterator->kvm, 0);
tag->key = raw.key;
tag->value = raw.value;
tag->value_len = raw.value_len;
tag->flags = raw.flags;
if (++iterator->index == iterator->tags->tags[iterator->base].ntags) {
do {
if (iterator->base == LOCAL_TAGS) {
iterator->base = -1;
return 1;
}
} while (iterator->tags->tags[++iterator->base].ntags == 0);
iterator->index = 0;
iterator->kvm = iterator->tags->tags[iterator->base].kvm;
}
return 1;
}
// Find a tag in a tag_set by key. Return true if found, false otherwise.
static bool tag_set_get_tag_by_key(const struct tag_set *tags, const char *key,
size_t key_len, census_tag *tag) {
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags; i++) {
struct raw_tag raw;
kvp = decode_tag(&raw, kvp, 0);
if (key_len == raw.key_len && memcmp(raw.key, key, key_len) == 0) {
tag->key = raw.key;
tag->value = raw.value;
tag->value_len = raw.value_len;
tag->flags = raw.flags;
return true;
}
}
return false;
}
int census_tag_set_get_tag_by_key(const census_tag_set *tags, const char *key,
census_tag *tag) {
size_t key_len = strlen(key) + 1;
if (key_len == 1) {
return 0;
}
if (tag_set_get_tag_by_key(&tags->tags[PROPAGATED_TAGS], key, key_len, tag) ||
tag_set_get_tag_by_key(&tags->tags[PROPAGATED_BINARY_TAGS], key, key_len,
tag) ||
tag_set_get_tag_by_key(&tags->tags[LOCAL_TAGS], key, key_len, tag)) {
return 1;
}
return 0;
}
// tag_set encoding and decoding functions.
//
// Wire format for tag sets on the wire:
//
// First, a tag set header:
//
// offset bytes description
// 0 1 version number
// 1 1 number of bytes in this header. This allows for future
// expansion.
// 2 1 number of bytes in each tag header.
// 3 1 ntags value from tag set.
//
// This is followed by the key/value memory from struct tag_set.
#define ENCODED_VERSION 0 // Version number
#define ENCODED_HEADER_SIZE 4 // size of tag set header
// Encode a tag set. Returns 0 if buffer is too small.
static size_t tag_set_encode(const struct tag_set *tags, char *buffer,
size_t buf_size) {
if (buf_size < ENCODED_HEADER_SIZE + tags->kvm_used) {
return 0;
}
buf_size -= ENCODED_HEADER_SIZE;
*buffer++ = (char)ENCODED_VERSION;
*buffer++ = (char)ENCODED_HEADER_SIZE;
*buffer++ = (char)TAG_HEADER_SIZE;
*buffer++ = (char)tags->ntags;
if (tags->ntags == 0) {
return ENCODED_HEADER_SIZE;
}
memcpy(buffer, tags->kvm, tags->kvm_used);
return ENCODED_HEADER_SIZE + tags->kvm_used;
}
char *census_tag_set_encode(const census_tag_set *tags, char *buffer,
size_t buf_size, size_t *print_buf_size,
size_t *bin_buf_size) {
*print_buf_size =
tag_set_encode(&tags->tags[PROPAGATED_TAGS], buffer, buf_size);
if (*print_buf_size == 0) {
return NULL;
}
char *b_buffer = buffer + *print_buf_size;
*bin_buf_size = tag_set_encode(&tags->tags[PROPAGATED_BINARY_TAGS], b_buffer,
buf_size - *print_buf_size);
if (*bin_buf_size == 0) {
return NULL;
}
return b_buffer;
}
// Decode a tag set.
static void tag_set_decode(struct tag_set *tags, const char *buffer,
size_t size) {
uint8_t version = (uint8_t)(*buffer++);
uint8_t header_size = (uint8_t)(*buffer++);
uint8_t tag_header_size = (uint8_t)(*buffer++);
tags->ntags = tags->ntags_alloc = (int)(*buffer++);
if (tags->ntags == 0) {
tags->ntags_alloc = 0;
tags->kvm_size = 0;
tags->kvm_used = 0;
tags->kvm = NULL;
return;
}
if (header_size != ENCODED_HEADER_SIZE) {
GPR_ASSERT(version != ENCODED_VERSION);
GPR_ASSERT(ENCODED_HEADER_SIZE < header_size);
buffer += (header_size - ENCODED_HEADER_SIZE);
}
tags->kvm_used = size - header_size;
tags->kvm_size = tags->kvm_used + CENSUS_MAX_TAG_KV_LEN;
tags->kvm = gpr_malloc(tags->kvm_size);
if (tag_header_size != TAG_HEADER_SIZE) {
// something new in the tag information. I don't understand it, so
// don't copy it over.
GPR_ASSERT(version != ENCODED_VERSION);
GPR_ASSERT(tag_header_size > TAG_HEADER_SIZE);
char *kvp = tags->kvm;
for (int i = 0; i < tags->ntags; i++) {
memcpy(kvp, buffer, TAG_HEADER_SIZE);
kvp += header_size;
struct raw_tag raw;
buffer =
decode_tag(&raw, (char *)buffer, tag_header_size - TAG_HEADER_SIZE);
memcpy(kvp, raw.key, (size_t)raw.key_len + raw.value_len);
kvp += raw.key_len + raw.value_len;
}
} else {
memcpy(tags->kvm, buffer, tags->kvm_used);
}
}
census_tag_set *census_tag_set_decode(const char *buffer, size_t size,
const char *bin_buffer, size_t bin_size) {
census_tag_set *new_ts = gpr_malloc(sizeof(census_tag_set));
memset(&new_ts->tags[LOCAL_TAGS], 0, sizeof(struct tag_set));
if (buffer == NULL) {
memset(&new_ts->tags[PROPAGATED_TAGS], 0, sizeof(struct tag_set));
} else {
tag_set_decode(&new_ts->tags[PROPAGATED_TAGS], buffer, size);
}
if (bin_buffer == NULL) {
memset(&new_ts->tags[PROPAGATED_BINARY_TAGS], 0, sizeof(struct tag_set));
} else {
tag_set_decode(&new_ts->tags[PROPAGATED_BINARY_TAGS], bin_buffer, bin_size);
}
memset(&new_ts->status, 0, sizeof(new_ts->status));
new_ts->status.n_propagated_tags = new_ts->tags[PROPAGATED_TAGS].ntags;
new_ts->status.n_propagated_binary_tags =
new_ts->tags[PROPAGATED_BINARY_TAGS].ntags;
// TODO(aveitch): check that BINARY flag is correct for each type.
return new_ts;
}

@ -225,7 +225,6 @@ CORE_SOURCE_FILES = [
'src/core/census/initialize.c',
'src/core/census/operation.c',
'src/core/census/placeholders.c',
'src/core/census/tag_set.c',
'src/core/census/tracing.c',
'src/boringssl/err_data.c',
'third_party/boringssl/crypto/aes/aes.c',

@ -41,7 +41,14 @@ census_initialize_type census_initialize_import;
census_shutdown_type census_shutdown_import;
census_supported_type census_supported_import;
census_enabled_type census_enabled_import;
census_context_serialize_type census_context_serialize_import;
census_context_create_type census_context_create_import;
census_context_destroy_type census_context_destroy_import;
census_context_get_status_type census_context_get_status_import;
census_context_initialize_iterator_type census_context_initialize_iterator_import;
census_context_next_tag_type census_context_next_tag_import;
census_context_get_tag_type census_context_get_tag_import;
census_context_encode_type census_context_encode_import;
census_context_decode_type census_context_decode_import;
census_trace_mask_type census_trace_mask_import;
census_set_trace_mask_type census_set_trace_mask_import;
census_start_rpc_op_timestamp_type census_start_rpc_op_timestamp_import;
@ -54,15 +61,6 @@ census_trace_print_type census_trace_print_import;
census_trace_scan_start_type census_trace_scan_start_import;
census_get_trace_record_type census_get_trace_record_import;
census_trace_scan_end_type census_trace_scan_end_import;
census_tag_set_create_type census_tag_set_create_import;
census_tag_set_destroy_type census_tag_set_destroy_import;
census_tag_set_get_create_status_type census_tag_set_get_create_status_import;
census_tag_set_initialize_iterator_type census_tag_set_initialize_iterator_import;
census_tag_set_next_tag_type census_tag_set_next_tag_import;
census_tag_set_get_tag_by_key_type census_tag_set_get_tag_by_key_import;
census_tag_set_encode_type census_tag_set_encode_import;
census_tag_set_decode_type census_tag_set_decode_import;
census_context_tag_set_type census_context_tag_set_import;
census_record_values_type census_record_values_import;
census_view_create_type census_view_create_import;
census_view_delete_type census_view_delete_import;
@ -303,7 +301,14 @@ void grpc_rb_load_imports(HMODULE library) {
census_shutdown_import = (census_shutdown_type) GetProcAddress(library, "census_shutdown");
census_supported_import = (census_supported_type) GetProcAddress(library, "census_supported");
census_enabled_import = (census_enabled_type) GetProcAddress(library, "census_enabled");
census_context_serialize_import = (census_context_serialize_type) GetProcAddress(library, "census_context_serialize");
census_context_create_import = (census_context_create_type) GetProcAddress(library, "census_context_create");
census_context_destroy_import = (census_context_destroy_type) GetProcAddress(library, "census_context_destroy");
census_context_get_status_import = (census_context_get_status_type) GetProcAddress(library, "census_context_get_status");
census_context_initialize_iterator_import = (census_context_initialize_iterator_type) GetProcAddress(library, "census_context_initialize_iterator");
census_context_next_tag_import = (census_context_next_tag_type) GetProcAddress(library, "census_context_next_tag");
census_context_get_tag_import = (census_context_get_tag_type) GetProcAddress(library, "census_context_get_tag");
census_context_encode_import = (census_context_encode_type) GetProcAddress(library, "census_context_encode");
census_context_decode_import = (census_context_decode_type) GetProcAddress(library, "census_context_decode");
census_trace_mask_import = (census_trace_mask_type) GetProcAddress(library, "census_trace_mask");
census_set_trace_mask_import = (census_set_trace_mask_type) GetProcAddress(library, "census_set_trace_mask");
census_start_rpc_op_timestamp_import = (census_start_rpc_op_timestamp_type) GetProcAddress(library, "census_start_rpc_op_timestamp");
@ -316,15 +321,6 @@ void grpc_rb_load_imports(HMODULE library) {
census_trace_scan_start_import = (census_trace_scan_start_type) GetProcAddress(library, "census_trace_scan_start");
census_get_trace_record_import = (census_get_trace_record_type) GetProcAddress(library, "census_get_trace_record");
census_trace_scan_end_import = (census_trace_scan_end_type) GetProcAddress(library, "census_trace_scan_end");
census_tag_set_create_import = (census_tag_set_create_type) GetProcAddress(library, "census_tag_set_create");
census_tag_set_destroy_import = (census_tag_set_destroy_type) GetProcAddress(library, "census_tag_set_destroy");
census_tag_set_get_create_status_import = (census_tag_set_get_create_status_type) GetProcAddress(library, "census_tag_set_get_create_status");
census_tag_set_initialize_iterator_import = (census_tag_set_initialize_iterator_type) GetProcAddress(library, "census_tag_set_initialize_iterator");
census_tag_set_next_tag_import = (census_tag_set_next_tag_type) GetProcAddress(library, "census_tag_set_next_tag");
census_tag_set_get_tag_by_key_import = (census_tag_set_get_tag_by_key_type) GetProcAddress(library, "census_tag_set_get_tag_by_key");
census_tag_set_encode_import = (census_tag_set_encode_type) GetProcAddress(library, "census_tag_set_encode");
census_tag_set_decode_import = (census_tag_set_decode_type) GetProcAddress(library, "census_tag_set_decode");
census_context_tag_set_import = (census_context_tag_set_type) GetProcAddress(library, "census_context_tag_set");
census_record_values_import = (census_record_values_type) GetProcAddress(library, "census_record_values");
census_view_create_import = (census_view_create_type) GetProcAddress(library, "census_view_create");
census_view_delete_import = (census_view_delete_type) GetProcAddress(library, "census_view_delete");

@ -73,9 +73,30 @@ extern census_supported_type census_supported_import;
typedef int(*census_enabled_type)(void);
extern census_enabled_type census_enabled_import;
#define census_enabled census_enabled_import
typedef size_t(*census_context_serialize_type)(const census_context *context, char *buffer, size_t buf_size);
extern census_context_serialize_type census_context_serialize_import;
#define census_context_serialize census_context_serialize_import
typedef census_context *(*census_context_create_type)(const census_context *base, const census_tag *tags, int ntags, census_context_status const **status);
extern census_context_create_type census_context_create_import;
#define census_context_create census_context_create_import
typedef void(*census_context_destroy_type)(census_context *context);
extern census_context_destroy_type census_context_destroy_import;
#define census_context_destroy census_context_destroy_import
typedef const census_context_status *(*census_context_get_status_type)(const census_context *context);
extern census_context_get_status_type census_context_get_status_import;
#define census_context_get_status census_context_get_status_import
typedef void(*census_context_initialize_iterator_type)(const census_context *context, census_context_iterator *iterator);
extern census_context_initialize_iterator_type census_context_initialize_iterator_import;
#define census_context_initialize_iterator census_context_initialize_iterator_import
typedef int(*census_context_next_tag_type)(census_context_iterator *iterator, census_tag *tag);
extern census_context_next_tag_type census_context_next_tag_import;
#define census_context_next_tag census_context_next_tag_import
typedef int(*census_context_get_tag_type)(const census_context *context, const char *key, census_tag *tag);
extern census_context_get_tag_type census_context_get_tag_import;
#define census_context_get_tag census_context_get_tag_import
typedef char *(*census_context_encode_type)(const census_context *context, char *buffer, size_t buf_size, size_t *print_buf_size, size_t *bin_buf_size);
extern census_context_encode_type census_context_encode_import;
#define census_context_encode census_context_encode_import
typedef census_context *(*census_context_decode_type)(const char *buffer, size_t size, const char *bin_buffer, size_t bin_size);
extern census_context_decode_type census_context_decode_import;
#define census_context_decode census_context_decode_import
typedef int(*census_trace_mask_type)(const census_context *context);
extern census_trace_mask_type census_trace_mask_import;
#define census_trace_mask census_trace_mask_import
@ -112,37 +133,10 @@ extern census_get_trace_record_type census_get_trace_record_import;
typedef void(*census_trace_scan_end_type)();
extern census_trace_scan_end_type census_trace_scan_end_import;
#define census_trace_scan_end census_trace_scan_end_import
typedef census_tag_set *(*census_tag_set_create_type)(const census_tag_set *base, const census_tag *tags, int ntags, census_tag_set_create_status const **status);
extern census_tag_set_create_type census_tag_set_create_import;
#define census_tag_set_create census_tag_set_create_import
typedef void(*census_tag_set_destroy_type)(census_tag_set *tags);
extern census_tag_set_destroy_type census_tag_set_destroy_import;
#define census_tag_set_destroy census_tag_set_destroy_import
typedef const census_tag_set_create_status *(*census_tag_set_get_create_status_type)(const census_tag_set *tags);
extern census_tag_set_get_create_status_type census_tag_set_get_create_status_import;
#define census_tag_set_get_create_status census_tag_set_get_create_status_import
typedef void(*census_tag_set_initialize_iterator_type)(const census_tag_set *tags, census_tag_set_iterator *iterator);
extern census_tag_set_initialize_iterator_type census_tag_set_initialize_iterator_import;
#define census_tag_set_initialize_iterator census_tag_set_initialize_iterator_import
typedef int(*census_tag_set_next_tag_type)(census_tag_set_iterator *iterator, census_tag *tag);
extern census_tag_set_next_tag_type census_tag_set_next_tag_import;
#define census_tag_set_next_tag census_tag_set_next_tag_import
typedef int(*census_tag_set_get_tag_by_key_type)(const census_tag_set *tags, const char *key, census_tag *tag);
extern census_tag_set_get_tag_by_key_type census_tag_set_get_tag_by_key_import;
#define census_tag_set_get_tag_by_key census_tag_set_get_tag_by_key_import
typedef char *(*census_tag_set_encode_type)(const census_tag_set *tags, char *buffer, size_t buf_size, size_t *print_buf_size, size_t *bin_buf_size);
extern census_tag_set_encode_type census_tag_set_encode_import;
#define census_tag_set_encode census_tag_set_encode_import
typedef census_tag_set *(*census_tag_set_decode_type)(const char *buffer, size_t size, const char *bin_buffer, size_t bin_size);
extern census_tag_set_decode_type census_tag_set_decode_import;
#define census_tag_set_decode census_tag_set_decode_import
typedef census_tag_set *(*census_context_tag_set_type)(census_context *context);
extern census_context_tag_set_type census_context_tag_set_import;
#define census_context_tag_set census_context_tag_set_import
typedef void(*census_record_values_type)(census_context *context, census_value *values, size_t nvalues);
extern census_record_values_type census_record_values_import;
#define census_record_values census_record_values_import
typedef census_view *(*census_view_create_type)(uint32_t metric_id, const census_tag_set *tags, const census_aggregation *aggregations, size_t naggregations);
typedef census_view *(*census_view_create_type)(uint32_t metric_id, const census_context *tags, const census_aggregation *aggregations, size_t naggregations);
extern census_view_create_type census_view_create_import;
#define census_view_create census_view_create_import
typedef void(*census_view_delete_type)(census_view *view);
@ -154,7 +148,7 @@ extern census_view_metric_type census_view_metric_import;
typedef size_t(*census_view_naggregations_type)(const census_view *view);
extern census_view_naggregations_type census_view_naggregations_import;
#define census_view_naggregations census_view_naggregations_import
typedef const census_tag_set *(*census_view_tags_type)(const census_view *view);
typedef const census_context *(*census_view_tags_type)(const census_view *view);
extern census_view_tags_type census_view_tags_import;
#define census_view_tags census_view_tags_import
typedef const census_aggregation *(*census_view_aggregrations_type)(const census_view *view);

@ -31,7 +31,7 @@
*
*/
// Test census_tag_set functions, including encoding/decoding
// Test census_context functions, including encoding/decoding
#include <grpc/census.h>
#include <grpc/support/log.h>
@ -46,7 +46,7 @@ static uint8_t one_byte_val = 7;
static uint32_t four_byte_val = 0x12345678;
static uint64_t eight_byte_val = 0x1234567890abcdef;
// A set of tags Used to create a basic tag_set for testing. Each tag has a
// A set of tags Used to create a basic context for testing. Each tag has a
// unique set of flags. Note that replace_add_delete_test() relies on specific
// offsets into this array - if you add or delete entries, you will also need
// to change the test.
@ -65,7 +65,7 @@ static census_tag basic_tags[BASIC_TAG_COUNT] = {
/* 7 */ {"k7", (char *)&four_byte_val, 4,
CENSUS_TAG_PROPAGATE | CENSUS_TAG_STATS | CENSUS_TAG_BINARY}};
// Set of tags used to modify the basic tag_set. Note that
// Set of tags used to modify the basic context. Note that
// replace_add_delete_test() relies on specific offsets into this array - if
// you add or delete entries, you will also need to change the test. Other
// tests that rely on specific instances have XXX_XXX_OFFSET definitions (also
@ -99,35 +99,34 @@ static bool compare_tag(const census_tag *t1, const census_tag *t2) {
t1->flags == t2->flags);
}
// Utility function to validate a tag exists in tag set.
static bool validate_tag(const census_tag_set *cts, const census_tag *tag) {
// Utility function to validate a tag exists in context.
static bool validate_tag(const census_context *context, const census_tag *tag) {
census_tag tag2;
if (census_tag_set_get_tag_by_key(cts, tag->key, &tag2) != 1) return false;
if (census_context_get_tag(context, tag->key, &tag2) != 1) return false;
return compare_tag(tag, &tag2);
}
// Create an empty tag_set.
// Create an empty context.
static void empty_test(void) {
struct census_tag_set *cts = census_tag_set_create(NULL, NULL, 0, NULL);
GPR_ASSERT(cts != NULL);
const census_tag_set_create_status *status =
census_tag_set_get_create_status(cts);
census_tag_set_create_status expected = {0, 0, 0, 0, 0, 0, 0, 0};
struct census_context *context = census_context_create(NULL, NULL, 0, NULL);
GPR_ASSERT(context != NULL);
const census_context_status *status = census_context_get_status(context);
census_context_status expected = {0, 0, 0, 0, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
}
// Test create and iteration over basic tag set.
// Test create and iteration over basic context.
static void basic_test(void) {
const census_tag_set_create_status *status;
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, &status);
census_tag_set_create_status expected = {2, 2, 4, 0, 8, 0, 0, 0};
const census_context_status *status;
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, &status);
census_context_status expected = {2, 2, 4, 0, 8, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_iterator it;
census_tag_set_initialize_iterator(cts, &it);
census_context_iterator it;
census_context_initialize_iterator(context, &it);
census_tag tag;
while (census_tag_set_next_tag(&it, &tag)) {
while (census_context_next_tag(&it, &tag)) {
// can't rely on tag return order: make sure it matches exactly one.
int matches = 0;
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
@ -135,29 +134,28 @@ static void basic_test(void) {
}
GPR_ASSERT(matches == 1);
}
census_tag_set_destroy(cts);
census_context_destroy(context);
}
// Test that census_tag_set_get_tag_by_key().
// Test census_context_get_tag().
static void lookup_by_key_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
census_tag tag;
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, basic_tags[i].key, &tag) ==
1);
GPR_ASSERT(census_context_get_tag(context, basic_tags[i].key, &tag) == 1);
GPR_ASSERT(compare_tag(&tag, &basic_tags[i]));
}
// non-existent keys
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "key", &tag) == 0);
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "key01", &tag) == 0);
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "k9", &tag) == 0);
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "random", &tag) == 0);
GPR_ASSERT(census_tag_set_get_tag_by_key(cts, "", &tag) == 0);
census_tag_set_destroy(cts);
GPR_ASSERT(census_context_get_tag(context, "key", &tag) == 0);
GPR_ASSERT(census_context_get_tag(context, "key01", &tag) == 0);
GPR_ASSERT(census_context_get_tag(context, "k9", &tag) == 0);
GPR_ASSERT(census_context_get_tag(context, "random", &tag) == 0);
GPR_ASSERT(census_context_get_tag(context, "", &tag) == 0);
census_context_destroy(context);
}
// Try creating tag set with invalid entries.
// Try creating context with invalid entries.
static void invalid_test(void) {
char key[300];
memset(key, 'k', 299);
@ -168,155 +166,156 @@ static void invalid_test(void) {
// long keys, short value. Key lengths (including terminator) should be
// <= 255 (CENSUS_MAX_TAG_KV_LEN)
GPR_ASSERT(strlen(key) == 299);
const census_tag_set_create_status *status;
struct census_tag_set *cts = census_tag_set_create(NULL, &tag, 1, &status);
census_tag_set_create_status expected = {0, 0, 0, 0, 0, 0, 1, 0};
const census_context_status *status;
struct census_context *context =
census_context_create(NULL, &tag, 1, &status);
census_context_status expected = {0, 0, 0, 0, 0, 0, 1, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
key[CENSUS_MAX_TAG_KV_LEN] = 0;
GPR_ASSERT(strlen(key) == CENSUS_MAX_TAG_KV_LEN);
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
key[CENSUS_MAX_TAG_KV_LEN - 1] = 0;
GPR_ASSERT(strlen(key) == CENSUS_MAX_TAG_KV_LEN - 1);
cts = census_tag_set_create(NULL, &tag, 1, &status);
census_tag_set_create_status expected2 = {0, 0, 1, 0, 1, 0, 0, 0};
context = census_context_create(NULL, &tag, 1, &status);
census_context_status expected2 = {0, 0, 1, 0, 1, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
// now try with long values
tag.value_len = 300;
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
tag.value_len = CENSUS_MAX_TAG_KV_LEN + 1;
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
tag.value_len = CENSUS_MAX_TAG_KV_LEN;
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected2, sizeof(expected2)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
// 0 length key.
key[0] = 0;
cts = census_tag_set_create(NULL, &tag, 1, &status);
context = census_context_create(NULL, &tag, 1, &status);
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag_set_destroy(cts);
census_context_destroy(context);
}
// Make a copy of a tag set
// Make a copy of a context
static void copy_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 = census_tag_set_create(cts, NULL, 0, &status);
census_tag_set_create_status expected = {2, 2, 4, 0, 0, 0, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 =
census_context_create(context, NULL, 0, &status);
census_context_status expected = {2, 2, 4, 0, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(cts2, basic_tags[i].key, &tag) ==
1);
GPR_ASSERT(census_context_get_tag(context2, basic_tags[i].key, &tag) == 1);
GPR_ASSERT(compare_tag(&tag, &basic_tags[i]));
}
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
census_context_destroy(context);
census_context_destroy(context2);
}
// replace a single tag value
static void replace_value_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 = census_tag_set_create(
cts, modify_tags + REPLACE_VALUE_OFFSET, 1, &status);
census_tag_set_create_status expected = {2, 2, 4, 0, 0, 1, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 = census_context_create(
context, modify_tags + REPLACE_VALUE_OFFSET, 1, &status);
census_context_status expected = {2, 2, 4, 0, 0, 1, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(
cts2, modify_tags[REPLACE_VALUE_OFFSET].key, &tag) == 1);
GPR_ASSERT(census_context_get_tag(
context2, modify_tags[REPLACE_VALUE_OFFSET].key, &tag) == 1);
GPR_ASSERT(compare_tag(&tag, &modify_tags[REPLACE_VALUE_OFFSET]));
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
census_context_destroy(context);
census_context_destroy(context2);
}
// replace a single tags flags
static void replace_flags_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 =
census_tag_set_create(cts, modify_tags + REPLACE_FLAG_OFFSET, 1, &status);
census_tag_set_create_status expected = {1, 2, 5, 0, 0, 1, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 = census_context_create(
context, modify_tags + REPLACE_FLAG_OFFSET, 1, &status);
census_context_status expected = {1, 2, 5, 0, 0, 1, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(
cts2, modify_tags[REPLACE_FLAG_OFFSET].key, &tag) == 1);
GPR_ASSERT(census_context_get_tag(
context2, modify_tags[REPLACE_FLAG_OFFSET].key, &tag) == 1);
GPR_ASSERT(compare_tag(&tag, &modify_tags[REPLACE_FLAG_OFFSET]));
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
census_context_destroy(context);
census_context_destroy(context2);
}
// delete a single tag.
static void delete_tag_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 =
census_tag_set_create(cts, modify_tags + DELETE_TAG_OFFSET, 1, &status);
census_tag_set_create_status expected = {2, 1, 4, 1, 0, 0, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 = census_context_create(
context, modify_tags + DELETE_TAG_OFFSET, 1, &status);
census_context_status expected = {2, 1, 4, 1, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(
cts2, modify_tags[DELETE_TAG_OFFSET].key, &tag) == 0);
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
GPR_ASSERT(census_context_get_tag(
context2, modify_tags[DELETE_TAG_OFFSET].key, &tag) == 0);
census_context_destroy(context);
census_context_destroy(context2);
}
// add a single new tag.
static void add_tag_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 =
census_tag_set_create(cts, modify_tags + ADD_TAG_OFFSET, 1, &status);
census_tag_set_create_status expected = {2, 2, 5, 0, 1, 0, 0, 0};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 =
census_context_create(context, modify_tags + ADD_TAG_OFFSET, 1, &status);
census_context_status expected = {2, 2, 5, 0, 1, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
census_tag tag;
GPR_ASSERT(census_tag_set_get_tag_by_key(
cts2, modify_tags[ADD_TAG_OFFSET].key, &tag) == 1);
GPR_ASSERT(census_context_get_tag(context2, modify_tags[ADD_TAG_OFFSET].key,
&tag) == 1);
GPR_ASSERT(compare_tag(&tag, &modify_tags[ADD_TAG_OFFSET]));
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
census_context_destroy(context);
census_context_destroy(context2);
}
// test many changes at once.
static void replace_add_delete_test(void) {
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_tag_set_create_status *status;
struct census_tag_set *cts2 =
census_tag_set_create(cts, modify_tags, MODIFY_TAG_COUNT, &status);
census_tag_set_create_status expected = {2, 1, 6, 2, 3, 4, 0, 2};
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
const census_context_status *status;
struct census_context *context2 =
census_context_create(context, modify_tags, MODIFY_TAG_COUNT, &status);
census_context_status expected = {2, 1, 6, 2, 3, 4, 0, 2};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
// validate tag set contents. Use specific indices into the two arrays
// validate context contents. Use specific indices into the two arrays
// holding tag values.
GPR_ASSERT(validate_tag(cts2, &basic_tags[3]));
GPR_ASSERT(validate_tag(cts2, &basic_tags[4]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[0]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[1]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[6]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[7]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[8]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[9]));
GPR_ASSERT(validate_tag(cts2, &modify_tags[10]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[0]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[1]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[2]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[5]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[6]));
GPR_ASSERT(!validate_tag(cts2, &basic_tags[7]));
census_tag_set_destroy(cts);
census_tag_set_destroy(cts2);
GPR_ASSERT(validate_tag(context2, &basic_tags[3]));
GPR_ASSERT(validate_tag(context2, &basic_tags[4]));
GPR_ASSERT(validate_tag(context2, &modify_tags[0]));
GPR_ASSERT(validate_tag(context2, &modify_tags[1]));
GPR_ASSERT(validate_tag(context2, &modify_tags[6]));
GPR_ASSERT(validate_tag(context2, &modify_tags[7]));
GPR_ASSERT(validate_tag(context2, &modify_tags[8]));
GPR_ASSERT(validate_tag(context2, &modify_tags[9]));
GPR_ASSERT(validate_tag(context2, &modify_tags[10]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[0]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[1]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[2]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[5]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[6]));
GPR_ASSERT(!validate_tag(context2, &basic_tags[7]));
census_context_destroy(context);
census_context_destroy(context2);
}
#define BUF_SIZE 200
@ -324,38 +323,37 @@ static void replace_add_delete_test(void) {
// test encode/decode.
static void encode_decode_test(void) {
char buffer[BUF_SIZE];
struct census_tag_set *cts =
census_tag_set_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
struct census_context *context =
census_context_create(NULL, basic_tags, BASIC_TAG_COUNT, NULL);
size_t print_bsize;
size_t bin_bsize;
// Test with too small a buffer
GPR_ASSERT(census_tag_set_encode(cts, buffer, 2, &print_bsize, &bin_bsize) ==
NULL);
char *b_buffer =
census_tag_set_encode(cts, buffer, BUF_SIZE, &print_bsize, &bin_bsize);
GPR_ASSERT(census_context_encode(context, buffer, 2, &print_bsize,
&bin_bsize) == NULL);
char *b_buffer = census_context_encode(context, buffer, BUF_SIZE,
&print_bsize, &bin_bsize);
GPR_ASSERT(b_buffer != NULL && print_bsize > 0 && bin_bsize > 0 &&
print_bsize + bin_bsize <= BUF_SIZE &&
b_buffer == buffer + print_bsize);
census_tag_set *cts2 =
census_tag_set_decode(buffer, print_bsize, b_buffer, bin_bsize);
GPR_ASSERT(cts2 != NULL);
const census_tag_set_create_status *status =
census_tag_set_get_create_status(cts2);
census_tag_set_create_status expected = {2, 2, 0, 0, 0, 0, 0, 0};
census_context *context2 =
census_context_decode(buffer, print_bsize, b_buffer, bin_bsize);
GPR_ASSERT(context2 != NULL);
const census_context_status *status = census_context_get_status(context2);
census_context_status expected = {2, 2, 0, 0, 0, 0, 0, 0};
GPR_ASSERT(memcmp(status, &expected, sizeof(expected)) == 0);
for (int i = 0; i < BASIC_TAG_COUNT; i++) {
census_tag tag;
if (CENSUS_TAG_IS_PROPAGATED(basic_tags[i].flags)) {
GPR_ASSERT(census_tag_set_get_tag_by_key(cts2, basic_tags[i].key, &tag) ==
GPR_ASSERT(census_context_get_tag(context2, basic_tags[i].key, &tag) ==
1);
GPR_ASSERT(compare_tag(&tag, &basic_tags[i]));
} else {
GPR_ASSERT(census_tag_set_get_tag_by_key(cts2, basic_tags[i].key, &tag) ==
GPR_ASSERT(census_context_get_tag(context2, basic_tags[i].key, &tag) ==
0);
}
}
census_tag_set_destroy(cts2);
census_tag_set_destroy(cts);
census_context_destroy(context2);
census_context_destroy(context);
}
int main(int argc, char *argv[]) {

@ -96,7 +96,8 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
std::function<
std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, const RequestType&,
CompletionQueue*)> start_req,
CompletionQueue*)>
start_req,
std::function<void(grpc::Status, ResponseType*)> on_done)
: ClientRpcContext(channel_id),
context_(),
@ -142,7 +143,8 @@ class ClientRpcContextUnaryImpl : public ClientRpcContext {
std::function<void(grpc::Status, ResponseType*)> callback_;
std::function<std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, const RequestType&,
CompletionQueue*)> start_req_;
CompletionQueue*)>
start_req_;
grpc::Status status_;
double start_;
std::unique_ptr<grpc::ClientAsyncResponseReader<ResponseType>>
@ -162,11 +164,12 @@ class AsyncClient : public ClientImpl<StubType, RequestType> {
using ClientImpl<StubType, RequestType>::cores_;
using ClientImpl<StubType, RequestType>::channels_;
using ClientImpl<StubType, RequestType>::request_;
AsyncClient(const ClientConfig& config,
std::function<ClientRpcContext*(int, StubType*,
const RequestType&)> setup_ctx,
std::function<std::unique_ptr<StubType>(std::shared_ptr<Channel>)>
create_stub)
AsyncClient(
const ClientConfig& config,
std::function<ClientRpcContext*(int, StubType*, const RequestType&)>
setup_ctx,
std::function<std::unique_ptr<StubType>(std::shared_ptr<Channel>)>
create_stub)
: ClientImpl<StubType, RequestType>(config, create_stub),
num_async_threads_(NumThreads(config)),
channel_lock_(new std::mutex[config.client_channels()]),
@ -408,7 +411,8 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
std::function<std::unique_ptr<
grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*,
void*)> start_req,
void*)>
start_req,
std::function<void(grpc::Status, ResponseType*)> on_done)
: ClientRpcContext(channel_id),
context_(),
@ -460,10 +464,10 @@ class ClientRpcContextStreamingImpl : public ClientRpcContext {
ResponseType response_;
bool (ClientRpcContextStreamingImpl::*next_state_)(bool, Histogram*);
std::function<void(grpc::Status, ResponseType*)> callback_;
std::function<
std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*,
void*)> start_req_;
std::function<std::unique_ptr<
grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>(
BenchmarkService::Stub*, grpc::ClientContext*, CompletionQueue*, void*)>
start_req_;
grpc::Status status_;
double start_;
std::unique_ptr<grpc::ClientAsyncReaderWriter<RequestType, ResponseType>>
@ -507,7 +511,8 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
int channel_id, grpc::GenericStub* stub, const ByteBuffer& req,
std::function<std::unique_ptr<grpc::GenericClientAsyncReaderWriter>(
grpc::GenericStub*, grpc::ClientContext*,
const grpc::string& method_name, CompletionQueue*, void*)> start_req,
const grpc::string& method_name, CompletionQueue*, void*)>
start_req,
std::function<void(grpc::Status, ByteBuffer*)> on_done)
: ClientRpcContext(channel_id),
context_(),
@ -564,7 +569,8 @@ class ClientRpcContextGenericStreamingImpl : public ClientRpcContext {
std::function<void(grpc::Status, ByteBuffer*)> callback_;
std::function<std::unique_ptr<grpc::GenericClientAsyncReaderWriter>(
grpc::GenericStub*, grpc::ClientContext*, const grpc::string&,
CompletionQueue*, void*)> start_req_;
CompletionQueue*, void*)>
start_req_;
grpc::Status status_;
double start_;
std::unique_ptr<grpc::GenericClientAsyncReaderWriter> stream_;

@ -953,7 +953,6 @@ src/core/support/string_win32.h \
src/core/support/thd_internal.h \
src/core/support/time_precise.h \
src/core/census/aggregation.h \
src/core/census/context.h \
src/core/census/rpc_metric_id.h \
src/core/httpcli/httpcli_security_connector.c \
src/core/security/base64.c \
@ -1150,7 +1149,6 @@ src/core/census/context.c \
src/core/census/initialize.c \
src/core/census/operation.c \
src/core/census/placeholders.c \
src/core/census/tag_set.c \
src/core/census/tracing.c
# This tag can be used to specify the character encoding of the source files

@ -61,6 +61,18 @@
"test/core/transport/chttp2/bin_encoder_test.c"
]
},
{
"deps": [
"grpc",
"grpc_test_util"
],
"headers": [],
"language": "c",
"name": "census_context_test",
"src": [
"test/core/census/context_test.c"
]
},
{
"deps": [
"grpc",
@ -981,18 +993,6 @@
"test/core/iomgr/socket_utils_test.c"
]
},
{
"deps": [
"grpc",
"grpc_test_util"
],
"headers": [],
"language": "c",
"name": "tag_set_test",
"src": [
"test/core/census/tag_set_test.c"
]
},
{
"deps": [
"grpc",
@ -2506,7 +2506,6 @@
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/grpc_filter.h",
"src/core/census/rpc_metric_id.h",
"src/core/channel/channel_args.h",
@ -2706,7 +2705,6 @@
"include/grpc/support/useful.h",
"src/core/census/aggregation.h",
"src/core/census/context.c",
"src/core/census/context.h",
"src/core/census/grpc_context.c",
"src/core/census/grpc_filter.c",
"src/core/census/grpc_filter.h",
@ -2714,7 +2712,6 @@
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/rpc_metric_id.h",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
"src/core/channel/channel_args.c",
"src/core/channel/channel_args.h",
@ -3181,7 +3178,6 @@
"include/grpc/support/tls_pthread.h",
"include/grpc/support/useful.h",
"src/core/census/aggregation.h",
"src/core/census/context.h",
"src/core/census/grpc_filter.h",
"src/core/census/rpc_metric_id.h",
"src/core/channel/channel_args.h",
@ -3366,7 +3362,6 @@
"include/grpc/support/useful.h",
"src/core/census/aggregation.h",
"src/core/census/context.c",
"src/core/census/context.h",
"src/core/census/grpc_context.c",
"src/core/census/grpc_filter.c",
"src/core/census/grpc_filter.h",
@ -3374,7 +3369,6 @@
"src/core/census/operation.c",
"src/core/census/placeholders.c",
"src/core/census/rpc_metric_id.h",
"src/core/census/tag_set.c",
"src/core/census/tracing.c",
"src/core/channel/channel_args.c",
"src/core/channel/channel_args.h",

@ -101,6 +101,26 @@
"windows"
]
},
{
"args": [],
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "census_context_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{
"args": [],
"ci_platforms": [
@ -1419,26 +1439,6 @@
"posix"
]
},
{
"args": [],
"ci_platforms": [
"linux",
"mac",
"posix",
"windows"
],
"cpu_cost": 1.0,
"exclude_configs": [],
"flaky": false,
"language": "c",
"name": "tag_set_test",
"platforms": [
"linux",
"mac",
"posix",
"windows"
]
},
{
"args": [],
"ci_platforms": [

@ -126,6 +126,15 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "bin_encoder_test", "vcxproj
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "census_context_test", "vcxproj\test\census_context_test\census_context_test.vcxproj", "{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}"
ProjectSection(myProperties) = preProject
lib = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "channel_create_test", "vcxproj\test\channel_create_test\channel_create_test.vcxproj", "{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}"
ProjectSection(myProperties) = preProject
lib = "False"
@ -724,15 +733,6 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "sockaddr_utils_test", "vcxp
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "tag_set_test", "vcxproj\test\tag_set_test\tag_set_test.vcxproj", "{430F8F07-6AAD-0150-B35B-DB9E2E21941A}"
ProjectSection(myProperties) = preProject
lib = "False"
EndProjectSection
ProjectSection(ProjectDependencies) = postProject
{17BCAFC0-5FDC-4C94-AEB9-95F3E220614B} = {17BCAFC0-5FDC-4C94-AEB9-95F3E220614B}
{29D16885-7228-4C31-81ED-5F9187C7F2A9} = {29D16885-7228-4C31-81ED-5F9187C7F2A9}
EndProjectSection
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "time_averaged_stats_test", "vcxproj\test\time_averaged_stats_test\time_averaged_stats_test.vcxproj", "{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}"
ProjectSection(myProperties) = preProject
lib = "False"
@ -1349,6 +1349,22 @@ Global
{D5C70922-D68E-0E9D-9988-995E0F9A79AE}.Release-DLL|Win32.Build.0 = Release|Win32
{D5C70922-D68E-0E9D-9988-995E0F9A79AE}.Release-DLL|x64.ActiveCfg = Release|x64
{D5C70922-D68E-0E9D-9988-995E0F9A79AE}.Release-DLL|x64.Build.0 = Release|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug|Win32.ActiveCfg = Debug|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug|x64.ActiveCfg = Debug|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release|Win32.ActiveCfg = Release|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release|x64.ActiveCfg = Release|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug|Win32.Build.0 = Debug|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug|x64.Build.0 = Debug|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release|Win32.Build.0 = Release|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release|x64.Build.0 = Release|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug-DLL|Win32.Build.0 = Debug|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug-DLL|x64.ActiveCfg = Debug|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Debug-DLL|x64.Build.0 = Debug|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|Win32.ActiveCfg = Release|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|Win32.Build.0 = Release|Win32
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|x64.ActiveCfg = Release|x64
{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}.Release-DLL|x64.Build.0 = Release|x64
{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Debug|Win32.ActiveCfg = Debug|Win32
{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Debug|x64.ActiveCfg = Debug|x64
{AFC88484-3A2E-32BC-25B2-23DF741D4F3D}.Release|Win32.ActiveCfg = Release|Win32
@ -2421,22 +2437,6 @@ Global
{529771F0-10B0-9B1A-1E7E-8A8E01870348}.Release-DLL|Win32.Build.0 = Release|Win32
{529771F0-10B0-9B1A-1E7E-8A8E01870348}.Release-DLL|x64.ActiveCfg = Release|x64
{529771F0-10B0-9B1A-1E7E-8A8E01870348}.Release-DLL|x64.Build.0 = Release|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug|Win32.ActiveCfg = Debug|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug|x64.ActiveCfg = Debug|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release|Win32.ActiveCfg = Release|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release|x64.ActiveCfg = Release|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug|Win32.Build.0 = Debug|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug|x64.Build.0 = Debug|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release|Win32.Build.0 = Release|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release|x64.Build.0 = Release|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug-DLL|Win32.ActiveCfg = Debug|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug-DLL|Win32.Build.0 = Debug|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug-DLL|x64.ActiveCfg = Debug|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Debug-DLL|x64.Build.0 = Debug|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release-DLL|Win32.ActiveCfg = Release|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release-DLL|Win32.Build.0 = Release|Win32
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release-DLL|x64.ActiveCfg = Release|x64
{430F8F07-6AAD-0150-B35B-DB9E2E21941A}.Release-DLL|x64.Build.0 = Release|x64
{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}.Debug|Win32.ActiveCfg = Debug|Win32
{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}.Debug|x64.ActiveCfg = Debug|x64
{D1EB2A9B-8508-62D7-8FC4-11A11B1CBFD3}.Release|Win32.ActiveCfg = Release|Win32

@ -462,7 +462,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\support\thd_internal.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\support\time_precise.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\context.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h" />
</ItemGroup>
<ItemGroup>
@ -856,8 +855,6 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\placeholders.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tag_set.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
</ClCompile>
</ItemGroup>

@ -586,9 +586,6 @@
<ClCompile Include="$(SolutionDir)\..\src\core\census\placeholders.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tag_set.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
<Filter>src\core\census</Filter>
</ClCompile>
@ -1175,9 +1172,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\census\context.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h">
<Filter>src\core\census</Filter>
</ClInclude>

@ -438,7 +438,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\transport\transport.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\transport\transport_impl.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\context.h" />
<ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h" />
</ItemGroup>
<ItemGroup>
@ -792,8 +791,6 @@
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\placeholders.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tag_set.c">
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
</ClCompile>
</ItemGroup>

@ -526,9 +526,6 @@
<ClCompile Include="$(SolutionDir)\..\src\core\census\placeholders.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tag_set.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="$(SolutionDir)\..\src\core\census\tracing.c">
<Filter>src\core\census</Filter>
</ClCompile>
@ -1070,9 +1067,6 @@
<ClInclude Include="$(SolutionDir)\..\src\core\census\aggregation.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\census\context.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="$(SolutionDir)\..\src\core\census\rpc_metric_id.h">
<Filter>src\core\census</Filter>
</ClInclude>

@ -20,7 +20,7 @@
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<ProjectGuid>{430F8F07-6AAD-0150-B35B-DB9E2E21941A}</ProjectGuid>
<ProjectGuid>{5C1CFC2D-AF3C-D7CB-BA74-D267E91CBC73}</ProjectGuid>
<IgnoreWarnIntDirInTempDetected>true</IgnoreWarnIntDirInTempDetected>
<IntDir>$(SolutionDir)IntDir\$(MSBuildProjectName)\</IntDir>
</PropertyGroup>
@ -60,14 +60,14 @@
</ImportGroup>
<PropertyGroup Label="UserMacros" />
<PropertyGroup Condition="'$(Configuration)'=='Debug'">
<TargetName>tag_set_test</TargetName>
<TargetName>census_context_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Debug</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
<Configuration-grpc_dependencies_openssl>Debug</Configuration-grpc_dependencies_openssl>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)'=='Release'">
<TargetName>tag_set_test</TargetName>
<TargetName>census_context_test</TargetName>
<Linkage-grpc_dependencies_zlib>static</Linkage-grpc_dependencies_zlib>
<Configuration-grpc_dependencies_zlib>Release</Configuration-grpc_dependencies_zlib>
<Linkage-grpc_dependencies_openssl>static</Linkage-grpc_dependencies_openssl>
@ -158,7 +158,7 @@
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\core\census\tag_set_test.c">
<ClCompile Include="$(SolutionDir)\..\test\core\census\context_test.c">
</ClCompile>
</ItemGroup>
<ItemGroup>

@ -1,20 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<ClCompile Include="$(SolutionDir)\..\test\core\census\tag_set_test.c">
<ClCompile Include="$(SolutionDir)\..\test\core\census\context_test.c">
<Filter>test\core\census</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<Filter Include="test">
<UniqueIdentifier>{500aa440-5924-8047-996a-4c5096d1ef96}</UniqueIdentifier>
<UniqueIdentifier>{bc15bb31-7dbe-17f2-fb1c-4bc140ce1707}</UniqueIdentifier>
</Filter>
<Filter Include="test\core">
<UniqueIdentifier>{a3bf80f0-5b13-f623-277b-05f0231dd933}</UniqueIdentifier>
<UniqueIdentifier>{806f9b58-6a48-ae09-3cc6-bb36e3126f27}</UniqueIdentifier>
</Filter>
<Filter Include="test\core\census">
<UniqueIdentifier>{b6ed1b86-7795-4da9-a169-9eccf836852c}</UniqueIdentifier>
<UniqueIdentifier>{85e37a47-e797-dcd1-b1e0-df553a454d8f}</UniqueIdentifier>
</Filter>
</ItemGroup>
</Project>
Loading…
Cancel
Save