/* * Copyright 2015 Netflix, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.netflix.spectator.aws; import com.amazonaws.DefaultRequest; import com.amazonaws.Request; import com.amazonaws.Response; import com.amazonaws.http.HttpResponse; import com.amazonaws.services.cloudwatch.model.ListMetricsRequest; import com.amazonaws.util.AWSRequestMetrics; import com.amazonaws.util.AWSRequestMetricsFullSupport; import com.amazonaws.util.TimingInfo; import com.netflix.spectator.api.*; import org.apache.http.client.methods.HttpPost; import org.junit.Before; import org.junit.Test; import java.net.URI; import java.util.ArrayList; import java.util.Arrays; import java.util.Collections; import java.util.HashSet; import java.util.List; import java.util.Optional; import java.util.Set; import java.util.stream.Collectors; import static org.junit.Assert.*; public class SpectatorRequestMetricCollectorTest { Registry registry; SpectatorRequestMetricCollector collector; @Before public void setUp() { registry = new DefaultRegistry(); collector = new SpectatorRequestMetricCollector(registry); } private void execRequest(String endpoint, int status) { AWSRequestMetrics metrics = new AWSRequestMetricsFullSupport(); metrics.addProperty(AWSRequestMetrics.Field.ServiceName, "AmazonCloudWatch"); metrics.addProperty(AWSRequestMetrics.Field.ServiceEndpoint, endpoint); metrics.addProperty(AWSRequestMetrics.Field.StatusCode, "" + status); if (status == 503) { metrics.addProperty(AWSRequestMetrics.Field.AWSErrorCode, "Throttled"); } String counterName = "BytesProcessed"; String timerName = "ClientExecuteTime"; metrics.setCounter(counterName, 12345); metrics.getTimingInfo().addSubMeasurement(timerName, TimingInfo.unmodifiableTimingInfo(100000L, 200000L)); Request<?> req = new DefaultRequest(new ListMetricsRequest(), "AmazonCloudWatch"); req.setAWSRequestMetrics(metrics); req.setEndpoint(URI.create(endpoint)); HttpResponse hr = new HttpResponse(req, new HttpPost(endpoint)); hr.setStatusCode(status); Response<?> resp = new Response<>(null, new HttpResponse(req, new HttpPost(endpoint))); collector.collectMetrics(req, resp); } /** Returns a set of all values for a given tag key. */ private Set<String> valueSet(String k) { return registry.stream() .map(m -> Utils.getTagValue(m.id(), k)) .filter(v -> v != null) .collect(Collectors.toSet()); } private Set<String> set(String... vs) { return new HashSet<>(Arrays.asList(vs)); } @Test public void extractServiceEndpoint() { execRequest("http://monitoring", 200); assertEquals(set("monitoring"), valueSet("serviceEndpoint")); execRequest("http://s3", 200); assertEquals(set("monitoring", "s3"), valueSet("serviceEndpoint")); } @Test public void extractServiceName() { execRequest("http://monitoring", 200); assertEquals(set("AmazonCloudWatch"), valueSet("serviceName")); } @Test public void extractRequestType() { execRequest("http://monitoring", 200); assertEquals(set("ListMetricsRequest"), valueSet("requestType")); } @Test public void extractStatusCode() { execRequest("http://monitoring", 200); execRequest("http://monitoring", 429); execRequest("http://monitoring", 503); assertEquals(set("200", "429", "503"), valueSet("statusCode")); } @Test public void extractErrorCode() { execRequest("http://monitoring", 200); assertEquals(set(), valueSet("AWSErrorCode")); execRequest("http://monitoring", 503); assertEquals(set("Throttled"), valueSet("AWSErrorCode")); } @Test public void testMetricCollection() { execRequest("http://foo", 200); //then List<Meter> allMetrics = new ArrayList<>(); registry.iterator().forEachRemaining(allMetrics::add); assertEquals(2, allMetrics.size()); Optional<Timer> expectedTimer = registry.timers().findFirst(); assertTrue(expectedTimer.isPresent()); Timer timer = expectedTimer.get(); assertEquals(1, timer.count()); assertEquals(100000, timer.totalTime()); Optional<Counter> expectedCounter = registry.counters().findFirst(); assertTrue(expectedCounter.isPresent()); assertEquals(12345L, expectedCounter.get().count()); } @Test public void testListFiltering() { assertEquals(Optional.empty(), SpectatorRequestMetricCollector.firstValue(null, Object::toString)); assertEquals(Optional.empty(), SpectatorRequestMetricCollector.firstValue(Collections.emptyList(), Object::toString)); assertEquals(Optional.of("1"), SpectatorRequestMetricCollector.firstValue(Collections.singletonList(1L), Object::toString)); assertEquals(Optional.empty(), SpectatorRequestMetricCollector.firstValue(Collections.singletonList(null), Object::toString)); } }