2424import com .google .common .base .MoreObjects ;
2525import com .google .common .base .MoreObjects .ToStringHelper ;
2626import com .google .common .base .Ticker ;
27+ import com .google .common .collect .Lists ;
2728import com .google .common .util .concurrent .Futures ;
2829import com .google .common .util .concurrent .ListenableFuture ;
2930import com .google .common .util .concurrent .MoreExecutors ;
3637import io .grpc .LoadBalancer .PickSubchannelArgs ;
3738import io .grpc .LoadBalancer .ResolvedAddresses ;
3839import io .grpc .LoadBalancer .SubchannelPicker ;
40+ import io .grpc .LongCounterMetricInstrument ;
3941import io .grpc .ManagedChannel ;
4042import io .grpc .ManagedChannelBuilder ;
4143import io .grpc .Metadata ;
44+ import io .grpc .MetricInstrumentRegistry ;
4245import io .grpc .Status ;
4346import io .grpc .internal .BackoffPolicy ;
4447import io .grpc .internal .ExponentialBackoffPolicy ;
@@ -87,6 +90,10 @@ final class CachingRlsLbClient {
8790 /** Minimum bytes for a Java Object. */
8891 public static final int OBJ_OVERHEAD_B = 16 ;
8992
93+ private static final LongCounterMetricInstrument DEFAULT_TARGET_PICKS_COUNTER ;
94+ private static final LongCounterMetricInstrument TARGET_PICKS_COUNTER ;
95+ private static final LongCounterMetricInstrument FAILED_PICKS_COUNTER ;
96+
9097 // All cache status changes (pending, backoff, success) must be under this lock
9198 private final Object lock = new Object ();
9299 // LRU cache based on access order (BACKOFF and actual data will be here)
@@ -115,6 +122,23 @@ final class CachingRlsLbClient {
115122 private final RefCountedChildPolicyWrapperFactory refCountedChildPolicyWrapperFactory ;
116123 private final ChannelLogger logger ;
117124
125+ static {
126+ MetricInstrumentRegistry metricInstrumentRegistry
127+ = MetricInstrumentRegistry .getDefaultRegistry ();
128+ DEFAULT_TARGET_PICKS_COUNTER = metricInstrumentRegistry .registerLongCounter (
129+ "grpc.lb.rls.default_target_picks" , "Number of LB picks sent to the default target" , "pick" ,
130+ Lists .newArrayList ("grpc.target" , "grpc.lb.rls.server_target" ,
131+ "grpc.lb.rls.data_plane_target" , "grpc.lb.pick_result" ), Lists .newArrayList (), true );
132+ TARGET_PICKS_COUNTER = metricInstrumentRegistry .registerLongCounter ("grpc.lb.rls.target_picks" ,
133+ "Number of LB picks sent to each RLS target" , "pick" ,
134+ Lists .newArrayList ("grpc.target" , "grpc.lb.rls.server_target" ,
135+ "grpc.lb.rls.data_plane_target" , "grpc.lb.pick_result" ), Lists .newArrayList (), true );
136+ FAILED_PICKS_COUNTER = metricInstrumentRegistry .registerLongCounter ("grpc.lb.rls.failed_picks" ,
137+ "Number of LB picks failed due to either a failed RLS request or the RLS channel being "
138+ + "throttled" , "pick" , Lists .newArrayList ("grpc.target" , "grpc.lb.rls.server_target" ),
139+ Lists .newArrayList (), true );
140+ }
141+
118142 private CachingRlsLbClient (Builder builder ) {
119143 helper = new RlsLbHelper (checkNotNull (builder .helper , "helper" ));
120144 scheduledExecutorService = helper .getScheduledExecutorService ();
@@ -147,7 +171,7 @@ private CachingRlsLbClient(Builder builder) {
147171 }
148172 RlsRequestFactory requestFactory = new RlsRequestFactory (
149173 lbPolicyConfig .getRouteLookupConfig (), serverHost );
150- rlsPicker = new RlsPicker (requestFactory );
174+ rlsPicker = new RlsPicker (requestFactory , rlsConfig . lookupService () );
151175 // It is safe to use helper.getUnsafeChannelCredentials() because the client authenticates the
152176 // RLS server using the same authority as the backends, even though the RLS server’s addresses
153177 // will be looked up differently than the backends; overrideAuthority(helper.getAuthority()) is
@@ -904,9 +928,11 @@ public void onStatusChanged(ConnectivityState newState) {
904928 final class RlsPicker extends SubchannelPicker {
905929
906930 private final RlsRequestFactory requestFactory ;
931+ private final String lookupService ;
907932
908- RlsPicker (RlsRequestFactory requestFactory ) {
933+ RlsPicker (RlsRequestFactory requestFactory , String lookupService ) {
909934 this .requestFactory = checkNotNull (requestFactory , "requestFactory" );
935+ this .lookupService = checkNotNull (lookupService , "rlsConfig" );
910936 }
911937
912938 @ Override
@@ -941,14 +967,24 @@ public PickResult pickSubchannel(PickSubchannelArgs args) {
941967 }
942968 // Happy path
943969 logger .log (ChannelLogLevel .DEBUG , "Returning PickResult" );
944- return picker .pickSubchannel (args );
970+ PickResult pickResult = picker .pickSubchannel (args );
971+ // TODO: include the "grpc.target" label once target is available here.
972+ if (pickResult .hasResult ()) {
973+ helper .getMetricRecorder ().addLongCounter (TARGET_PICKS_COUNTER , 1 ,
974+ Lists .newArrayList ("" , lookupService , childPolicyWrapper .getTarget (),
975+ determineMetricsPickResult (pickResult )), Lists .newArrayList ());
976+ }
977+ return pickResult ;
945978 } else if (response .hasError ()) {
946979 logger .log (ChannelLogLevel .DEBUG , "RLS response has errors" );
947980 if (hasFallback ) {
948981 logger .log (ChannelLogLevel .DEBUG , "Using RLS fallback" );
949982 return useFallback (args );
950983 }
951984 logger .log (ChannelLogLevel .DEBUG , "No RLS fallback, returning PickResult with an error" );
985+ // TODO: include the "grpc.target" label once target is available here.
986+ helper .getMetricRecorder ().addLongCounter (FAILED_PICKS_COUNTER , 1 ,
987+ Lists .newArrayList ("" , lookupService ), Lists .newArrayList ());
952988 return PickResult .withError (
953989 convertRlsServerStatus (response .getStatus (),
954990 lbPolicyConfig .getRouteLookupConfig ().lookupService ()));
@@ -969,7 +1005,24 @@ private PickResult useFallback(PickSubchannelArgs args) {
9691005 if (picker == null ) {
9701006 return PickResult .withNoResult ();
9711007 }
972- return picker .pickSubchannel (args );
1008+ PickResult pickResult = picker .pickSubchannel (args );
1009+ if (pickResult .hasResult ()) {
1010+ // TODO: include the grpc.target label once target is available here.
1011+ helper .getMetricRecorder ().addLongCounter (DEFAULT_TARGET_PICKS_COUNTER , 1 ,
1012+ Lists .newArrayList ("" , lookupService , fallbackChildPolicyWrapper .getTarget (),
1013+ determineMetricsPickResult (pickResult )), Lists .newArrayList ());
1014+ }
1015+ return pickResult ;
1016+ }
1017+
1018+ private String determineMetricsPickResult (PickResult pickResult ) {
1019+ if (pickResult .getStatus ().isOk ()) {
1020+ return "complete" ;
1021+ } else if (pickResult .isDrop ()) {
1022+ return "drop" ;
1023+ } else {
1024+ return "fail" ;
1025+ }
9731026 }
9741027
9751028 private void startFallbackChildPolicy () {
0 commit comments