view and aggregation API

pull/3107/head
Alistair Veitch 9 years ago
parent 072a6f8f65
commit 9a09982e2d
  1. 9
      BUILD
  2. 2
      Makefile
  3. 5
      build.json
  4. 7
      gRPC.podspec
  5. 236
      include/grpc/census.h
  6. 31
      src/core/census/grpc_filter.c
  7. 38
      src/core/census/record_stat.c
  8. 27
      src/core/census/rpc_metric_id.h
  9. 2
      third_party/openssl
  10. 3
      tools/doxygen/Doxyfile.core.internal
  11. 10
      tools/run_tests/sources_and_headers.json
  12. 4
      vsprojects/grpc/grpc.vcxproj
  13. 5
      vsprojects/grpc/grpc.vcxproj.filters
  14. 4
      vsprojects/grpc_unsecure/grpc_unsecure.vcxproj
  15. 5
      vsprojects/grpc_unsecure/grpc_unsecure.vcxproj.filters

@ -246,7 +246,7 @@ cc_library(
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/census/context.h",
"src/core/census/rpc_stat_id.h",
"src/core/census/rpc_metric_id.h",
"src/core/httpcli/httpcli_security_connector.c",
"src/core/security/base64.c",
"src/core/security/client_auth_filter.c",
@ -386,7 +386,6 @@ cc_library(
"src/core/transport/transport_op_string.c",
"src/core/census/context.c",
"src/core/census/initialize.c",
"src/core/census/record_stat.c",
],
hdrs = [
"include/grpc/grpc_security.h",
@ -515,7 +514,7 @@ cc_library(
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/census/context.h",
"src/core/census/rpc_stat_id.h",
"src/core/census/rpc_metric_id.h",
"src/core/surface/init_unsecure.c",
"src/core/census/grpc_context.c",
"src/core/census/grpc_filter.c",
@ -635,7 +634,6 @@ cc_library(
"src/core/transport/transport_op_string.c",
"src/core/census/context.c",
"src/core/census/initialize.c",
"src/core/census/record_stat.c",
],
hdrs = [
"include/grpc/byte_buffer.h",
@ -1144,7 +1142,6 @@ objc_library(
"src/core/transport/transport_op_string.c",
"src/core/census/context.c",
"src/core/census/initialize.c",
"src/core/census/record_stat.c",
],
hdrs = [
"include/grpc/grpc_security.h",
@ -1270,7 +1267,7 @@ objc_library(
"src/core/transport/transport.h",
"src/core/transport/transport_impl.h",
"src/core/census/context.h",
"src/core/census/rpc_stat_id.h",
"src/core/census/rpc_metric_id.h",
],
includes = [
"include",

@ -4196,7 +4196,6 @@ LIBGRPC_SRC = \
src/core/transport/transport_op_string.c \
src/core/census/context.c \
src/core/census/initialize.c \
src/core/census/record_stat.c \
PUBLIC_HEADERS_C += \
include/grpc/grpc_security.h \
@ -4470,7 +4469,6 @@ LIBGRPC_UNSECURE_SRC = \
src/core/transport/transport_op_string.c \
src/core/census/context.c \
src/core/census/initialize.c \
src/core/census/record_stat.c \
PUBLIC_HEADERS_C += \
include/grpc/byte_buffer.h \

@ -19,12 +19,11 @@
],
"headers": [
"src/core/census/context.h",
"src/core/census/rpc_stat_id.h"
"src/core/census/rpc_metric_id.h"
],
"src": [
"src/core/census/context.c",
"src/core/census/initialize.c",
"src/core/census/record_stat.c"
"src/core/census/initialize.c"
]
},
{

@ -248,7 +248,7 @@ Pod::Spec.new do |s|
'src/core/transport/transport.h',
'src/core/transport/transport_impl.h',
'src/core/census/context.h',
'src/core/census/rpc_stat_id.h',
'src/core/census/rpc_metric_id.h',
'grpc/grpc_security.h',
'grpc/byte_buffer.h',
'grpc/byte_buffer_reader.h',
@ -394,8 +394,7 @@ Pod::Spec.new do |s|
'src/core/transport/transport.c',
'src/core/transport/transport_op_string.c',
'src/core/census/context.c',
'src/core/census/initialize.c',
'src/core/census/record_stat.c'
'src/core/census/initialize.c'
ss.private_header_files = 'src/core/support/env.h',
'src/core/support/file.h',
@ -520,7 +519,7 @@ Pod::Spec.new do |s|
'src/core/transport/transport.h',
'src/core/transport/transport_impl.h',
'src/core/census/context.h',
'src/core/census/rpc_stat_id.h'
'src/core/census/rpc_metric_id.h'
ss.header_mappings_dir = '.'

@ -159,114 +159,154 @@ int census_tag_set_next(census_tag_set_iterator *it, census_tag_const *tag);
invalidated, and should not be used once close is called. */
void census_tag_set_close(census_tag_set_iterator *it);
/* A census statistic to be recorded comprises two parts: an ID for the
* particular statistic and the value to be recorded against it. */
/* Core stats collection API's. There following concepts are used:
* Aggregation: A collection of values. Census supports the following
aggregation types:
Scalar - a single scalar value. Typically used for keeping (e.g.)
counts of events.
Distribution - statistical distribution information, used for
recording average, standard deviation etc.
Histogram - a histogram of measurements falling in defined bucket
boundaries.
Window - a count of events that happen in reolling time window.
New aggregation types can be added by the user, if desired (see
census_register_aggregation()).
* Metric: Each measurement is for a single metric. Examples include RPC
latency, CPU seconds consumed, and bytes transmitted.
* View: A view is a tag set, in which the tag values are regular expressions,
combined with an arbitrary number of aggregations and their initialization
parameters.
Each metric can have an arbitrary number of views by which it will be
broken down. For every measurement recorded, they are broken down by
unique tag combinations, and recorded in each matvhing view/aggregation.
*/
/* A single value to be recorded comprises two parts: an ID for the particular
* metric and the value to be recorded against it. */
typedef struct {
int id;
gpr_int32 metric_id;
double value;
} census_stat;
} census_value;
/* Record new usage values against the given context. */
void census_record_usage(census_context *context, census_value *values,
size_t nvalues);
/** Structure used to describe an aggregation type. */
typedef struct {
/* Create a new aggregation. The pointer returned can be used in future calls
to free(), record(), data() and reset(). */
void *(*create)(const void *create_arg);
/* Destroy an aggregation created by create() */
void (*free)(void *aggregation);
/* Record a new value against aggregation. */
void (*record)(void *aggregation, double value);
/* Return current aggregation data. The caller must cast this object into
the correct type for the aggregation result. The object returned can be
freed by using free_data(). */
const void *(*data)(const void *aggregation);
/* destroy an aggregation result eturned from get_aggregation(). */
void (*free_data)(const void *data);
/* Reset an aggregation to default (zero) values. */
void (*reset)(void *aggregation);
} census_aggregation_descriptor;
/** Register a new aggregation type.
@param descriptor Describes aggregation
@return An identifier that can be used to identify the aggregation in other
census functions. */
gpr_int32 census_register_aggregation(
const census_aggregation_descriptor *descriptor);
/* Aggregation Identifiers for built-in census aggregations. */
#define CENSUS_AGGREGATION_ID_SCALAR ((gpr_int32)0)
#define CENSUS_AGGREGATION_ID_DISTRIBUTION ((gpr_int32)1)
#define CENSUS_AGGREGATION_ID_HISTOGRAM ((gpr_int32)2)
#define CENSUS_AGGREGATION_ID_WINDOW ((gpr_int32)3)
/** Information needed to instantiate a new aggregation. Used in view
construction via census_define_view(). */
typedef struct {
gpr_int32 id; /* aggregation ID */
const void
*create_arg; /* Argument to be used for aggregation initialization. */
} census_aggregation;
/* Record new stats against the given context. */
void census_record_stat(census_context *context, census_stat *stats,
size_t nstats);
/** Type representing a single view. */
typedef struct census_view census_view;
/* Stats Configuration - Census clients can use these functions and structures
to extend and define what stats get recorded for what measurements. */
/** Create a new view.
@param tags tags that define the view
@param aggregations aggregations to associate with the view
@param naggregations number of aggregations
/** Stats types supported by census. */
typedef enum {
CENSUS_STAT_SCALAR = 0, /* Simple scalar */
CENSUS_STAT_DISTRIBUTION = 1, /* count, average, variance */
CENSUS_STAT_HISTOGRAM = 2, /* Histogram. */
CENSUS_STAT_WINDOW = 3, /* Count over a time window. */
CENSUS_STAT_NSTATS = 4 /* Total number of stats types. */
} census_stat_type;
@return A new census view
*/
const census_view *census_define_view(const census_tag_set *tags,
const census_aggregation *aggregations,
size_t naggregations);
/*
Each stats type differs in how it is initialized, how it is represented, and
the results it provides. The following structures allow us to use a generic
type for each of those.
Types referenced (one for each stat type in census_stat_type, by creation
arguments, output blob, and object representation. */
typedef struct census_stat_scalar_create_arg census_stat_scalar_create_arg;
typedef struct census_stat_distribution_create_arg
census_stat_distribution_create_arg;
typedef struct census_stat_histogram_create_arg
census_stat_histogram_create_arg;
typedef struct census_stat_window_create_arg census_stat_window_create_arg;
/**
Type for representing information to construct a new instance of a given
stats type (e.g. histogram bucket boundaries).
/** Number of aggregations associated with view. */
size_t census_view_naggregations(const census_view *view);
/** Get tags associated with view. */
const census_tag_set *census_view_tags(const census_view *view);
/** Get aggregations associated with a view. */
const census_aggregation *census_view_aggregrations(const census_view *view);
/** Associate a given view with a metric. Every metric can have many different
views.
@param metric_id Identifier of metric with which to attah the view
@param view View to attach to the metric
@return A view identifier: can be used to retrieve aggregation data from
the view using census_view_data().
*/
gpr_int64 census_attach_view(gpr_int32 metric_id, const census_view *view);
/** Holds aggregation data, as it applies to a particular view. This structure
is used as one component of the data returned from census_get_view_data(). */
typedef struct {
census_stat_type stat_type; /* The "real" type of the stat. */
union {
const census_stat_scalar_create_arg *scalar_arg;
const census_stat_distribution_create_arg *distribution_arg;
const census_stat_histogram_create_arg *histogram_arg;
const census_stat_window_create_arg *window_arg;
}
} census_stat_create_arg;
/**
Type for representing a single stats result. */
/** Aggregation index in original view. Use as (e.g.)
census_view_aggregations(view)[index] to get the original
census_aggregation structure. */
size_t index;
/** Data as returned from the data() function for the relevant
aggregation descriptor. It is the user responsibility to cast this to the
correct type for the aggregation. */
void *data;
} census_aggregation_data;
/** Holds all the aggregation data for a particular view instantiation. Forms
part of the data returned by census_get_view_data(). */
typedef struct {
const census_tag_set *view; /* Unique tags associated with this result. */
census_stat_type stat_type;
union {
const census_stat_scalar_result *scalar_result;
const census_stat_distribution_result *distribution_result;
const census_stat_histogram_result *histogram_result;
const census_stat_window_result *window_result;
}
} census_stat_result;
/**
Generic type for representing a stat "object".
*/
typdef struct {
census_stat_type stat_type;
union {
census_stat_scalar *scalar;
census_stat_distribution *distribution;
census_stat_histogram *histogram;
census_stat_window *window;
}
} census_stat;
/**
Structure holding function pointers and associated information needed to
manipulate a statstics "object". Every stats type must provide an instance
of this structure. */
const census_tag_set *tags; /* Tags for this set of aggregations */
size_t naggregations; /* Number of aggregations in data. */
const census_aggregation_data *data; /* Aggregation data */
} census_view_aggregation_data;
/** Census view data as returned by census_get_view_data(). */
typedef struct {
/* Create a new statistic. The pointer returned can be used in future calls
to clone_stat(), destroy_stat(), record_stat() and get_stats(). */
(census_stat *) (*create_stat)(const census_stat_create_arg *create_arg);
/* Create a new statistic, using an existing one as base. */
(census_stat *) (*clone_stat)(const census_stat *stat);
/* destroy a stats object created by {create,clone}_stat(). */
(void) (*destroy_stat)(census_stat *stat);
/* Record a new value against a given statistics object instance. */
(void) (*record_stat)(census_stat *stat, double value);
/* Return current state of a stat. The object returned can be freed by
using destroy_stats_result(). */
(const census_stat_result *) (*get_stat)(const census_stat *stat);
/* destroy a stats result object, as returned from get_stat(). */
(void) (*destroy_stats_result)(census_stat_result *result);
/* Reset a stats values. */
(void) (*reset_stat)(census_stat *stat);
} census_stat;
gpr_int32 census_define_view(const census_tag_set *view);
gpr_int32 census_define_stat(gpr_int32 metric_id, gpr_int32 view_id,
const census_stat *stat,
const census_stat_create_arg *create_arg);
census_stat_result *census_get_stat(gpr_int32 stat_id, gpr_int32 *nstats);
const census_view *view; /* Original view */
size_t n_tag_sets; /* Number of unique tag sets that matched view. */
const census_view_aggregation_data *data; /* n_tag_sets entries */
} census_view_data;
/** Get data from aggregations associated with a view.
@param view_id View identifier returned from census_attach_view
@param aggregation_indices Indexes of aggregations (relative to original view)
for which to return current data. This parameter is ignored if
nindices == 0.
@param nindices. Number of entries in aggregation_indices. If this is set to
0, then all aggregations for the current view are returned.
*/
const census_view_data *census_get_view_data(gpr_int64 view_id,
size_t *aggregation_indices,
size_t nindices);
/** Reset all view data to zero for the specified view id. */
void census_reset_view_data(gpr_int64 view_id);
#ifdef __cplusplus
}

@ -37,7 +37,6 @@
#include <string.h>
#include "include/grpc/census.h"
#include "src/core/census/rpc_stat_id.h"
#include "src/core/channel/channel_stack.h"
#include "src/core/channel/noop_filter.h"
#include "src/core/statistics/census_interface.h"
@ -173,25 +172,15 @@ static void destroy_channel_elem(grpc_channel_element* elem) {
}
const grpc_channel_filter grpc_client_census_filter = {
client_start_transport_op,
grpc_channel_next_op,
sizeof(call_data),
client_init_call_elem,
client_destroy_call_elem,
sizeof(channel_data),
init_channel_elem,
destroy_channel_elem,
grpc_call_next_get_peer,
"census-client"};
client_start_transport_op, grpc_channel_next_op,
sizeof(call_data), client_init_call_elem,
client_destroy_call_elem, sizeof(channel_data),
init_channel_elem, destroy_channel_elem,
grpc_call_next_get_peer, "census-client"};
const grpc_channel_filter grpc_server_census_filter = {
server_start_transport_op,
grpc_channel_next_op,
sizeof(call_data),
server_init_call_elem,
server_destroy_call_elem,
sizeof(channel_data),
init_channel_elem,
destroy_channel_elem,
grpc_call_next_get_peer,
"census-server"};
server_start_transport_op, grpc_channel_next_op,
sizeof(call_data), server_init_call_elem,
server_destroy_call_elem, sizeof(channel_data),
init_channel_elem, destroy_channel_elem,
grpc_call_next_get_peer, "census-server"};

@ -1,38 +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.
*
*/
#include <grpc/census.h>
#include "src/core/census/rpc_stat_id.h"
void census_record_stat(census_context *context, census_stat *stats,
size_t nstats) {}

@ -31,16 +31,21 @@
*
*/
#ifndef CENSUS_RPC_STAT_ID_H
#define CENSUS_RPC_STAT_ID_H
#ifndef CENSUS_RPC_METRIC_ID_H
#define CENSUS_RPC_METRIC_ID_H
/* Stats ID's used for RPC measurements. */
#define CENSUS_INVALID_STAT_ID 0 /* ID 0 is always invalid */
#define CENSUS_RPC_CLIENT_REQUESTS 1 /* Count of client requests sent. */
#define CENSUS_RPC_SERVER_REQUESTS 2 /* Count of server requests sent. */
#define CENSUS_RPC_CLIENT_ERRORS 3 /* Client error counts. */
#define CENSUS_RPC_SERVER_ERRORS 4 /* Server error counts. */
#define CENSUS_RPC_CLIENT_LATENCY 5 /* Client side request latency. */
#define CENSUS_RPC_SERVER_LATENCY 6 /* Server side request latency. */
/* Metric ID's used for RPC measurements. */
/* Count of client requests sent. */
#define CENSUS_METRIC_RPC_CLIENT_REQUESTS ((gpr_int32)0)
/* Count of server requests sent. */
#define CENSUS_METRIC_RPC_SERVER_REQUESTS ((gpr_int32)1)
/* Client error counts. */
#define CENSUS_METRIC_RPC_CLIENT_ERRORS ((gpr_int32)2)
/* Server error counts. */
#define CENSUS_METRIC_RPC_SERVER_ERRORS ((gpr_int32)3)
/* Client side request latency. */
#define CENSUS_METRIC_RPC_CLIENT_LATENCY ((gpr_int32)4)
/* Server side request latency. */
#define CENSUS_METRIC_RPC_SERVER_LATENCY ((gpr_int32)5)
#endif /* CENSUS_RPC_STAT_ID_H */
#endif /* CENSUS_RPC_METRIC_ID_H */

@ -1 +1 @@
Subproject commit 33dd08320648ac71d7d9d732be774ed3818dccc5
Subproject commit 3df69d3aefde7671053d4e3c242b228e5d79c83f

@ -883,7 +883,7 @@ src/core/transport/stream_op.h \
src/core/transport/transport.h \
src/core/transport/transport_impl.h \
src/core/census/context.h \
src/core/census/rpc_stat_id.h \
src/core/census/rpc_metric_id.h \
src/core/httpcli/httpcli_security_connector.c \
src/core/security/base64.c \
src/core/security/client_auth_filter.c \
@ -1023,7 +1023,6 @@ src/core/transport/transport.c \
src/core/transport/transport_op_string.c \
src/core/census/context.c \
src/core/census/initialize.c \
src/core/census/record_stat.c \
include/grpc/support/alloc.h \
include/grpc/support/atm.h \
include/grpc/support/atm_gcc_atomic.h \

@ -12265,7 +12265,7 @@
"include/grpc/status.h",
"src/core/census/context.h",
"src/core/census/grpc_filter.h",
"src/core/census/rpc_stat_id.h",
"src/core/census/rpc_metric_id.h",
"src/core/channel/channel_args.h",
"src/core/channel/channel_stack.h",
"src/core/channel/client_channel.h",
@ -12397,8 +12397,7 @@
"src/core/census/grpc_filter.c",
"src/core/census/grpc_filter.h",
"src/core/census/initialize.c",
"src/core/census/record_stat.c",
"src/core/census/rpc_stat_id.h",
"src/core/census/rpc_metric_id.h",
"src/core/channel/channel_args.c",
"src/core/channel/channel_args.h",
"src/core/channel/channel_stack.c",
@ -12744,7 +12743,7 @@
"include/grpc/status.h",
"src/core/census/context.h",
"src/core/census/grpc_filter.h",
"src/core/census/rpc_stat_id.h",
"src/core/census/rpc_metric_id.h",
"src/core/channel/channel_args.h",
"src/core/channel/channel_stack.h",
"src/core/channel/client_channel.h",
@ -12862,8 +12861,7 @@
"src/core/census/grpc_filter.c",
"src/core/census/grpc_filter.h",
"src/core/census/initialize.c",
"src/core/census/record_stat.c",
"src/core/census/rpc_stat_id.h",
"src/core/census/rpc_metric_id.h",
"src/core/channel/channel_args.c",
"src/core/channel/channel_args.h",
"src/core/channel/channel_stack.c",

@ -345,7 +345,7 @@
<ClInclude Include="..\..\src\core\transport\transport.h" />
<ClInclude Include="..\..\src\core\transport\transport_impl.h" />
<ClInclude Include="..\..\src\core\census\context.h" />
<ClInclude Include="..\..\src\core\census\rpc_stat_id.h" />
<ClInclude Include="..\..\src\core\census\rpc_metric_id.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\core\httpcli\httpcli_security_connector.c">
@ -626,8 +626,6 @@
</ClCompile>
<ClCompile Include="..\..\src\core\census\initialize.c">
</ClCompile>
<ClCompile Include="..\..\src\core\census\record_stat.c">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\gpr\gpr.vcxproj">

@ -418,9 +418,6 @@
<ClCompile Include="..\..\src\core\census\initialize.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\census\record_stat.c">
<Filter>src\core\census</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\grpc\grpc_security.h">
@ -794,7 +791,7 @@
<ClInclude Include="..\..\src\core\census\context.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\census\rpc_stat_id.h">
<ClInclude Include="..\..\src\core\census\rpc_metric_id.h">
<Filter>src\core\census</Filter>
</ClInclude>
</ItemGroup>

@ -328,7 +328,7 @@
<ClInclude Include="..\..\src\core\transport\transport.h" />
<ClInclude Include="..\..\src\core\transport\transport_impl.h" />
<ClInclude Include="..\..\src\core\census\context.h" />
<ClInclude Include="..\..\src\core\census\rpc_stat_id.h" />
<ClInclude Include="..\..\src\core\census\rpc_metric_id.h" />
</ItemGroup>
<ItemGroup>
<ClCompile Include="..\..\src\core\surface\init_unsecure.c">
@ -569,8 +569,6 @@
</ClCompile>
<ClCompile Include="..\..\src\core\census\initialize.c">
</ClCompile>
<ClCompile Include="..\..\src\core\census\record_stat.c">
</ClCompile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\gpr\gpr.vcxproj">

@ -358,9 +358,6 @@
<ClCompile Include="..\..\src\core\census\initialize.c">
<Filter>src\core\census</Filter>
</ClCompile>
<ClCompile Include="..\..\src\core\census\record_stat.c">
<Filter>src\core\census</Filter>
</ClCompile>
</ItemGroup>
<ItemGroup>
<ClInclude Include="..\..\include\grpc\byte_buffer.h">
@ -692,7 +689,7 @@
<ClInclude Include="..\..\src\core\census\context.h">
<Filter>src\core\census</Filter>
</ClInclude>
<ClInclude Include="..\..\src\core\census\rpc_stat_id.h">
<ClInclude Include="..\..\src\core\census\rpc_metric_id.h">
<Filter>src\core\census</Filter>
</ClInclude>
</ItemGroup>

Loading…
Cancel
Save