Search in sources :

Example 1 with UpstreamLocalityStats

use of io.grpc.xds.Stats.UpstreamLocalityStats in project grpc-java by grpc.

the class LoadStatsManager2Test method loadCounterDelayedDeletionAfterAllInProgressRequestsReported.

@Test
public void loadCounterDelayedDeletionAfterAllInProgressRequestsReported() {
    ClusterLocalityStats counter = loadStatsManager.getClusterLocalityStats(CLUSTER_NAME1, EDS_SERVICE_NAME1, LOCALITY1);
    counter.recordCallStarted();
    counter.recordCallStarted();
    ClusterStats stats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER_NAME1));
    UpstreamLocalityStats localityStats = Iterables.getOnlyElement(stats.upstreamLocalityStatsList());
    assertThat(localityStats.totalIssuedRequests()).isEqualTo(2L);
    assertThat(localityStats.totalSuccessfulRequests()).isEqualTo(0L);
    assertThat(localityStats.totalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.totalRequestsInProgress()).isEqualTo(2L);
    // release the counter, but requests still in-flight
    counter.release();
    stats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER_NAME1));
    localityStats = Iterables.getOnlyElement(stats.upstreamLocalityStatsList());
    assertThat(localityStats.totalIssuedRequests()).isEqualTo(0L);
    assertThat(localityStats.totalSuccessfulRequests()).isEqualTo(0L);
    assertThat(localityStats.totalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.totalRequestsInProgress()).isEqualTo(// retained by in-flight calls
    2L);
    counter.recordCallFinished(Status.OK);
    counter.recordCallFinished(Status.UNAVAILABLE);
    stats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER_NAME1));
    localityStats = Iterables.getOnlyElement(stats.upstreamLocalityStatsList());
    assertThat(localityStats.totalIssuedRequests()).isEqualTo(0L);
    assertThat(localityStats.totalSuccessfulRequests()).isEqualTo(1L);
    assertThat(localityStats.totalErrorRequests()).isEqualTo(1L);
    assertThat(localityStats.totalRequestsInProgress()).isEqualTo(0L);
    assertThat(loadStatsManager.getClusterStatsReports(CLUSTER_NAME1)).isEmpty();
}
Also used : UpstreamLocalityStats(io.grpc.xds.Stats.UpstreamLocalityStats) ClusterStats(io.grpc.xds.Stats.ClusterStats) ClusterLocalityStats(io.grpc.xds.LoadStatsManager2.ClusterLocalityStats) Test(org.junit.Test)

Example 2 with UpstreamLocalityStats

use of io.grpc.xds.Stats.UpstreamLocalityStats in project grpc-java by grpc.

the class LoadStatsManager2Test method sharedLoadCounterStatsAggregation.

@Test
public void sharedLoadCounterStatsAggregation() {
    ClusterLocalityStats ref1 = loadStatsManager.getClusterLocalityStats(CLUSTER_NAME1, EDS_SERVICE_NAME1, LOCALITY1);
    ClusterLocalityStats ref2 = loadStatsManager.getClusterLocalityStats(CLUSTER_NAME1, EDS_SERVICE_NAME1, LOCALITY1);
    ref1.recordCallStarted();
    ref1.recordCallFinished(Status.OK);
    ref2.recordCallStarted();
    ref2.recordCallStarted();
    ref2.recordCallFinished(Status.UNAVAILABLE);
    ClusterStats stats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER_NAME1));
    UpstreamLocalityStats localityStats = Iterables.getOnlyElement(stats.upstreamLocalityStatsList());
    assertThat(localityStats.totalIssuedRequests()).isEqualTo(1L + 2L);
    assertThat(localityStats.totalSuccessfulRequests()).isEqualTo(1L);
    assertThat(localityStats.totalErrorRequests()).isEqualTo(1L);
    assertThat(localityStats.totalRequestsInProgress()).isEqualTo(1L + 2L - 1L - 1L);
}
Also used : UpstreamLocalityStats(io.grpc.xds.Stats.UpstreamLocalityStats) ClusterStats(io.grpc.xds.Stats.ClusterStats) ClusterLocalityStats(io.grpc.xds.LoadStatsManager2.ClusterLocalityStats) Test(org.junit.Test)

Example 3 with UpstreamLocalityStats

use of io.grpc.xds.Stats.UpstreamLocalityStats in project grpc-java by grpc.

the class LoadStatsManager2Test method recordAndGetReport.

@Test
public void recordAndGetReport() {
    ClusterDropStats dropCounter1 = loadStatsManager.getClusterDropStats(CLUSTER_NAME1, EDS_SERVICE_NAME1);
    ClusterDropStats dropCounter2 = loadStatsManager.getClusterDropStats(CLUSTER_NAME1, EDS_SERVICE_NAME2);
    ClusterLocalityStats loadCounter1 = loadStatsManager.getClusterLocalityStats(CLUSTER_NAME1, EDS_SERVICE_NAME1, LOCALITY1);
    ClusterLocalityStats loadCounter2 = loadStatsManager.getClusterLocalityStats(CLUSTER_NAME1, EDS_SERVICE_NAME1, LOCALITY2);
    ClusterLocalityStats loadCounter3 = loadStatsManager.getClusterLocalityStats(CLUSTER_NAME2, null, LOCALITY3);
    dropCounter1.recordDroppedRequest("lb");
    dropCounter1.recordDroppedRequest("throttle");
    for (int i = 0; i < 19; i++) {
        loadCounter1.recordCallStarted();
    }
    fakeClock.forwardTime(5L, TimeUnit.SECONDS);
    dropCounter2.recordDroppedRequest();
    loadCounter1.recordCallFinished(Status.OK);
    for (int i = 0; i < 9; i++) {
        loadCounter2.recordCallStarted();
    }
    loadCounter2.recordCallFinished(Status.UNAVAILABLE);
    fakeClock.forwardTime(10L, TimeUnit.SECONDS);
    loadCounter3.recordCallStarted();
    List<ClusterStats> allStats = loadStatsManager.getAllClusterStatsReports();
    // three cluster:edsServiceName
    assertThat(allStats).hasSize(3);
    ClusterStats stats1 = findClusterStats(allStats, CLUSTER_NAME1, EDS_SERVICE_NAME1);
    assertThat(stats1.loadReportIntervalNano()).isEqualTo(TimeUnit.SECONDS.toNanos(5L + 10L));
    assertThat(stats1.droppedRequestsList()).hasSize(2);
    assertThat(findDroppedRequestCount(stats1.droppedRequestsList(), "lb")).isEqualTo(1L);
    assertThat(findDroppedRequestCount(stats1.droppedRequestsList(), "throttle")).isEqualTo(1L);
    assertThat(stats1.totalDroppedRequests()).isEqualTo(1L + 1L);
    // two localities
    assertThat(stats1.upstreamLocalityStatsList()).hasSize(2);
    UpstreamLocalityStats loadStats1 = findLocalityStats(stats1.upstreamLocalityStatsList(), LOCALITY1);
    assertThat(loadStats1.totalIssuedRequests()).isEqualTo(19L);
    assertThat(loadStats1.totalSuccessfulRequests()).isEqualTo(1L);
    assertThat(loadStats1.totalErrorRequests()).isEqualTo(0L);
    assertThat(loadStats1.totalRequestsInProgress()).isEqualTo(19L - 1L);
    UpstreamLocalityStats loadStats2 = findLocalityStats(stats1.upstreamLocalityStatsList(), LOCALITY2);
    assertThat(loadStats2.totalIssuedRequests()).isEqualTo(9L);
    assertThat(loadStats2.totalSuccessfulRequests()).isEqualTo(0L);
    assertThat(loadStats2.totalErrorRequests()).isEqualTo(1L);
    assertThat(loadStats2.totalRequestsInProgress()).isEqualTo(9L - 1L);
    ClusterStats stats2 = findClusterStats(allStats, CLUSTER_NAME1, EDS_SERVICE_NAME2);
    assertThat(stats2.loadReportIntervalNano()).isEqualTo(TimeUnit.SECONDS.toNanos(5L + 10L));
    // no categorized drops
    assertThat(stats2.droppedRequestsList()).isEmpty();
    assertThat(stats2.totalDroppedRequests()).isEqualTo(1L);
    // no per-locality stats
    assertThat(stats2.upstreamLocalityStatsList()).isEmpty();
    ClusterStats stats3 = findClusterStats(allStats, CLUSTER_NAME2, null);
    assertThat(stats3.loadReportIntervalNano()).isEqualTo(TimeUnit.SECONDS.toNanos(5L + 10L));
    assertThat(stats3.droppedRequestsList()).isEmpty();
    // no drops recorded
    assertThat(stats3.totalDroppedRequests()).isEqualTo(0L);
    // one localities
    assertThat(stats3.upstreamLocalityStatsList()).hasSize(1);
    UpstreamLocalityStats loadStats3 = Iterables.getOnlyElement(stats3.upstreamLocalityStatsList());
    assertThat(loadStats3.totalIssuedRequests()).isEqualTo(1L);
    assertThat(loadStats3.totalSuccessfulRequests()).isEqualTo(0L);
    assertThat(loadStats3.totalErrorRequests()).isEqualTo(0L);
    assertThat(loadStats3.totalRequestsInProgress()).isEqualTo(1L);
    fakeClock.forwardTime(3L, TimeUnit.SECONDS);
    List<ClusterStats> clusterStatsList = loadStatsManager.getClusterStatsReports(CLUSTER_NAME1);
    assertThat(clusterStatsList).hasSize(2);
    stats1 = findClusterStats(clusterStatsList, CLUSTER_NAME1, EDS_SERVICE_NAME1);
    assertThat(stats1.loadReportIntervalNano()).isEqualTo(TimeUnit.SECONDS.toNanos(3L));
    assertThat(stats1.droppedRequestsList()).isEmpty();
    // no new drops recorded
    assertThat(stats1.totalDroppedRequests()).isEqualTo(0L);
    // two localities
    assertThat(stats1.upstreamLocalityStatsList()).hasSize(2);
    loadStats1 = findLocalityStats(stats1.upstreamLocalityStatsList(), LOCALITY1);
    assertThat(loadStats1.totalIssuedRequests()).isEqualTo(0L);
    assertThat(loadStats1.totalSuccessfulRequests()).isEqualTo(0L);
    assertThat(loadStats1.totalErrorRequests()).isEqualTo(0L);
    // still in-progress
    assertThat(loadStats1.totalRequestsInProgress()).isEqualTo(18L);
    loadStats2 = findLocalityStats(stats1.upstreamLocalityStatsList(), LOCALITY2);
    assertThat(loadStats2.totalIssuedRequests()).isEqualTo(0L);
    assertThat(loadStats2.totalSuccessfulRequests()).isEqualTo(0L);
    assertThat(loadStats2.totalErrorRequests()).isEqualTo(0L);
    // still in-progress
    assertThat(loadStats2.totalRequestsInProgress()).isEqualTo(8L);
    stats2 = findClusterStats(clusterStatsList, CLUSTER_NAME1, EDS_SERVICE_NAME2);
    assertThat(stats2.loadReportIntervalNano()).isEqualTo(TimeUnit.SECONDS.toNanos(3L));
    assertThat(stats2.droppedRequestsList()).isEmpty();
    // no new drops recorded
    assertThat(stats2.totalDroppedRequests()).isEqualTo(0L);
    // no per-locality stats
    assertThat(stats2.upstreamLocalityStatsList()).isEmpty();
}
Also used : UpstreamLocalityStats(io.grpc.xds.Stats.UpstreamLocalityStats) ClusterStats(io.grpc.xds.Stats.ClusterStats) ClusterDropStats(io.grpc.xds.LoadStatsManager2.ClusterDropStats) ClusterLocalityStats(io.grpc.xds.LoadStatsManager2.ClusterLocalityStats) Test(org.junit.Test)

Example 4 with UpstreamLocalityStats

use of io.grpc.xds.Stats.UpstreamLocalityStats in project grpc-java by grpc.

the class ClusterImplLoadBalancerTest method recordLoadStats.

@Test
public void recordLoadStats() {
    LoadBalancerProvider weightedTargetProvider = new WeightedTargetLoadBalancerProvider();
    WeightedTargetConfig weightedTargetConfig = buildWeightedTargetConfig(ImmutableMap.of(locality, 10));
    ClusterImplConfig config = new ClusterImplConfig(CLUSTER, EDS_SERVICE_NAME, LRS_SERVER_INFO, null, Collections.<DropOverload>emptyList(), new PolicySelection(weightedTargetProvider, weightedTargetConfig), null);
    EquivalentAddressGroup endpoint = makeAddress("endpoint-addr", locality);
    deliverAddressesAndConfig(Collections.singletonList(endpoint), config);
    FakeLoadBalancer leafBalancer = Iterables.getOnlyElement(downstreamBalancers);
    Subchannel subchannel = leafBalancer.helper.createSubchannel(CreateSubchannelArgs.newBuilder().setAddresses(leafBalancer.addresses).build());
    leafBalancer.deliverSubchannelState(subchannel, ConnectivityState.READY);
    assertThat(currentState).isEqualTo(ConnectivityState.READY);
    PickResult result = currentPicker.pickSubchannel(mock(PickSubchannelArgs.class));
    assertThat(result.getStatus().isOk()).isTrue();
    ClientStreamTracer streamTracer1 = result.getStreamTracerFactory().newClientStreamTracer(ClientStreamTracer.StreamInfo.newBuilder().build(), // first RPC call
    new Metadata());
    ClientStreamTracer streamTracer2 = result.getStreamTracerFactory().newClientStreamTracer(ClientStreamTracer.StreamInfo.newBuilder().build(), // second RPC call
    new Metadata());
    ClientStreamTracer streamTracer3 = result.getStreamTracerFactory().newClientStreamTracer(ClientStreamTracer.StreamInfo.newBuilder().build(), // third RPC call
    new Metadata());
    streamTracer1.streamClosed(Status.OK);
    streamTracer2.streamClosed(Status.UNAVAILABLE);
    ClusterStats clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    UpstreamLocalityStats localityStats = Iterables.getOnlyElement(clusterStats.upstreamLocalityStatsList());
    assertThat(localityStats.locality()).isEqualTo(locality);
    assertThat(localityStats.totalIssuedRequests()).isEqualTo(3L);
    assertThat(localityStats.totalSuccessfulRequests()).isEqualTo(1L);
    assertThat(localityStats.totalErrorRequests()).isEqualTo(1L);
    assertThat(localityStats.totalRequestsInProgress()).isEqualTo(1L);
    streamTracer3.streamClosed(Status.OK);
    // stats recorder released
    subchannel.shutdown();
    clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    // Locality load is reported for one last time in case of loads occurred since the previous
    // load report.
    localityStats = Iterables.getOnlyElement(clusterStats.upstreamLocalityStatsList());
    assertThat(localityStats.locality()).isEqualTo(locality);
    assertThat(localityStats.totalIssuedRequests()).isEqualTo(0L);
    assertThat(localityStats.totalSuccessfulRequests()).isEqualTo(1L);
    assertThat(localityStats.totalErrorRequests()).isEqualTo(0L);
    assertThat(localityStats.totalRequestsInProgress()).isEqualTo(0L);
    clusterStats = Iterables.getOnlyElement(loadStatsManager.getClusterStatsReports(CLUSTER));
    // no longer reported
    assertThat(clusterStats.upstreamLocalityStatsList()).isEmpty();
}
Also used : UpstreamLocalityStats(io.grpc.xds.Stats.UpstreamLocalityStats) ClientStreamTracer(io.grpc.ClientStreamTracer) Metadata(io.grpc.Metadata) WeightedTargetConfig(io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig) WeightedPolicySelection(io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection) PolicySelection(io.grpc.internal.ServiceConfigUtil.PolicySelection) ClusterImplConfig(io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig) ClusterStats(io.grpc.xds.Stats.ClusterStats) EquivalentAddressGroup(io.grpc.EquivalentAddressGroup) Subchannel(io.grpc.LoadBalancer.Subchannel) LoadBalancerProvider(io.grpc.LoadBalancerProvider) PickResult(io.grpc.LoadBalancer.PickResult) PickSubchannelArgs(io.grpc.LoadBalancer.PickSubchannelArgs) Test(org.junit.Test)

Example 5 with UpstreamLocalityStats

use of io.grpc.xds.Stats.UpstreamLocalityStats in project grpc-java by grpc.

the class LoadStatsManager2 method getClusterStatsReports.

/**
 * Gets the traffic stats (drops and loads) as a list of {@link ClusterStats} recorded for the
 * specified cluster since the previous call of this method or {@link
 * #getAllClusterStatsReports}. A {@link ClusterStats} includes stats for a specific cluster with
 * edsServiceName.
 */
synchronized List<ClusterStats> getClusterStatsReports(String cluster) {
    if (!allDropStats.containsKey(cluster) && !allLoadStats.containsKey(cluster)) {
        return Collections.emptyList();
    }
    Map<String, ReferenceCounted<ClusterDropStats>> clusterDropStats = allDropStats.get(cluster);
    Map<String, Map<Locality, ReferenceCounted<ClusterLocalityStats>>> clusterLoadStats = allLoadStats.get(cluster);
    Map<String, ClusterStats.Builder> statsReportBuilders = new HashMap<>();
    // Populate drop stats.
    if (clusterDropStats != null) {
        Set<String> toDiscard = new HashSet<>();
        for (String edsServiceName : clusterDropStats.keySet()) {
            ClusterStats.Builder builder = ClusterStats.newBuilder().clusterName(cluster);
            if (edsServiceName != null) {
                builder.clusterServiceName(edsServiceName);
            }
            ReferenceCounted<ClusterDropStats> ref = clusterDropStats.get(edsServiceName);
            if (ref.getReferenceCount() == 0) {
                // stats object no longer needed after snapshot
                toDiscard.add(edsServiceName);
            }
            ClusterDropStatsSnapshot dropStatsSnapshot = ref.get().snapshot();
            long totalCategorizedDrops = 0L;
            for (Map.Entry<String, Long> entry : dropStatsSnapshot.categorizedDrops.entrySet()) {
                builder.addDroppedRequests(DroppedRequests.create(entry.getKey(), entry.getValue()));
                totalCategorizedDrops += entry.getValue();
            }
            builder.totalDroppedRequests(totalCategorizedDrops + dropStatsSnapshot.uncategorizedDrops);
            builder.loadReportIntervalNano(dropStatsSnapshot.durationNano);
            statsReportBuilders.put(edsServiceName, builder);
        }
        clusterDropStats.keySet().removeAll(toDiscard);
    }
    // Populate load stats for all localities in the cluster.
    if (clusterLoadStats != null) {
        Set<String> toDiscard = new HashSet<>();
        for (String edsServiceName : clusterLoadStats.keySet()) {
            ClusterStats.Builder builder = statsReportBuilders.get(edsServiceName);
            if (builder == null) {
                builder = ClusterStats.newBuilder().clusterName(cluster);
                if (edsServiceName != null) {
                    builder.clusterServiceName(edsServiceName);
                }
                statsReportBuilders.put(edsServiceName, builder);
            }
            Map<Locality, ReferenceCounted<ClusterLocalityStats>> localityStats = clusterLoadStats.get(edsServiceName);
            Set<Locality> localitiesToDiscard = new HashSet<>();
            for (Locality locality : localityStats.keySet()) {
                ReferenceCounted<ClusterLocalityStats> ref = localityStats.get(locality);
                ClusterLocalityStatsSnapshot snapshot = ref.get().snapshot();
                // Only discard stats object after all in-flight calls under recording had finished.
                if (ref.getReferenceCount() == 0 && snapshot.callsInProgress == 0) {
                    localitiesToDiscard.add(locality);
                }
                UpstreamLocalityStats upstreamLocalityStats = UpstreamLocalityStats.create(locality, snapshot.callsIssued, snapshot.callsSucceeded, snapshot.callsFailed, snapshot.callsInProgress);
                builder.addUpstreamLocalityStats(upstreamLocalityStats);
                // Use the max (drops/loads) recording interval as the overall interval for the
                // cluster's stats. In general, they should be mostly identical.
                builder.loadReportIntervalNano(Math.max(builder.loadReportIntervalNano(), snapshot.durationNano));
            }
            localityStats.keySet().removeAll(localitiesToDiscard);
            if (localityStats.isEmpty()) {
                toDiscard.add(edsServiceName);
            }
        }
        clusterLoadStats.keySet().removeAll(toDiscard);
    }
    List<ClusterStats> res = new ArrayList<>();
    for (ClusterStats.Builder builder : statsReportBuilders.values()) {
        res.add(builder.build());
    }
    return Collections.unmodifiableList(res);
}
Also used : UpstreamLocalityStats(io.grpc.xds.Stats.UpstreamLocalityStats) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) ClusterStats(io.grpc.xds.Stats.ClusterStats) HashSet(java.util.HashSet) AtomicLong(java.util.concurrent.atomic.AtomicLong) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) Map(java.util.Map)

Aggregations

ClusterStats (io.grpc.xds.Stats.ClusterStats)5 UpstreamLocalityStats (io.grpc.xds.Stats.UpstreamLocalityStats)5 Test (org.junit.Test)4 ClusterLocalityStats (io.grpc.xds.LoadStatsManager2.ClusterLocalityStats)3 ClientStreamTracer (io.grpc.ClientStreamTracer)1 EquivalentAddressGroup (io.grpc.EquivalentAddressGroup)1 PickResult (io.grpc.LoadBalancer.PickResult)1 PickSubchannelArgs (io.grpc.LoadBalancer.PickSubchannelArgs)1 Subchannel (io.grpc.LoadBalancer.Subchannel)1 LoadBalancerProvider (io.grpc.LoadBalancerProvider)1 Metadata (io.grpc.Metadata)1 PolicySelection (io.grpc.internal.ServiceConfigUtil.PolicySelection)1 ClusterImplConfig (io.grpc.xds.ClusterImplLoadBalancerProvider.ClusterImplConfig)1 ClusterDropStats (io.grpc.xds.LoadStatsManager2.ClusterDropStats)1 WeightedPolicySelection (io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedPolicySelection)1 WeightedTargetConfig (io.grpc.xds.WeightedTargetLoadBalancerProvider.WeightedTargetConfig)1 ArrayList (java.util.ArrayList)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Map (java.util.Map)1