MetricsFilter implements Filter { @Override public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException { if (exported.compareAndSet(false, true)) { this.protocolName = invoker.getUrl().getParameter(METRICS_PROTOCOL) == null ? DEFAULT_PROTOCOL : invoker.getUrl().getParameter(METRICS_PROTOCOL); Protocol protocol = ExtensionLoader.getExtensionLoader(Protocol.class).getExtension(protocolName); this.port = invoker.getUrl().getParameter(METRICS_PORT) == null ? protocol.getDefaultPort() : Integer.valueOf(invoker.getUrl().getParameter(METRICS_PORT)); Invoker<MetricsService> metricsInvoker = initMetricsInvoker(); try { protocol.export(metricsInvoker); } catch (RuntimeException e) { logger.error("Metrics Service need to be configured" + " when multiple processes are running on a host" + e.getMessage()); } } RpcContext context = RpcContext.getContext(); boolean isProvider = context.isProviderSide(); long start = System.currentTimeMillis(); try { Result result = invoker.invoke(invocation); long duration = System.currentTimeMillis() - start; reportMetrics(invoker, invocation, duration, "success", isProvider); return result; } catch (RpcException e) { long duration = System.currentTimeMillis() - start; String result = "error"; if (e.isTimeout()) { result = "timeoutError"; } if (e.isBiz()) { result = "bisError"; } if (e.isNetwork()) { result = "networkError"; } if (e.isSerialization()) { result = "serializationError"; } reportMetrics(invoker, invocation, duration, result, isProvider); throw e; } }  @Override Result invoke(Invoker<?> invoker, Invocation invocation);  }
@Test public void testConsumerSuccess() throws Exception { IMetricManager metricManager = MetricManager.getIMetricManager(); metricManager.clear(); MetricsFilter metricsFilter = new MetricsFilter(); Invocation invocation = new RpcInvocation("sayName", DemoService.class.getName(), "", new Class<?>[]{Integer.class}, new Object[0]); RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345); RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(SIDE_KEY, CONSUMER_SIDE)); AppResponse response = AppResponseBuilder.create() .build(); onInvokeReturns(response); for (int i = 0; i < 100; i++) { metricsFilter.invoke(serviceInvoker, invocation); } FastCompass dubboClient = metricManager.getFastCompass(DUBBO_GROUP, new MetricName(DUBBO_CONSUMER, MetricLevel.MAJOR)); FastCompass dubboMethod = metricManager.getFastCompass(DUBBO_GROUP, new MetricName(DUBBO_CONSUMER_METHOD, new HashMap<String, String>(4) { { put(SERVICE, "org.apache.dubbo.monitor.dubbo.service.DemoService"); put(METHOD, "void sayName(Integer)"); } }, MetricLevel.NORMAL)); long timestamp = System.currentTimeMillis() / 5000 * 5000; Assertions.assertEquals(100, dubboClient.getMethodCountPerCategory(0).get("success").get(timestamp)); timestamp = timestamp / 15000 * 15000; Assertions.assertEquals(100, dubboMethod.getMethodCountPerCategory(0).get("success").get(timestamp)); }
@Test public void testConsumerTimeout() { IMetricManager metricManager = MetricManager.getIMetricManager(); metricManager.clear(); MetricsFilter metricsFilter = new MetricsFilter(); Invocation invocation = new RpcInvocation("timeoutException", DemoService.class.getName(), "", null, null); RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345); RpcContext.getContext().setUrl(timeoutInvoker.getUrl().addParameter(SIDE_KEY, CONSUMER_SIDE) .addParameter(TIMEOUT_KEY, 300)); AppResponse response = AppResponseBuilder.create() .build(); onInvokeReturns(response); for (int i = 0; i < 10; i++) { try { metricsFilter.invoke(timeoutInvoker, invocation); } catch (RpcException e) { } } FastCompass dubboClient = metricManager.getFastCompass(DUBBO_GROUP, new MetricName(DUBBO_CONSUMER, MetricLevel.MAJOR)); FastCompass dubboMethod = metricManager.getFastCompass(DUBBO_GROUP, new MetricName(DUBBO_CONSUMER_METHOD, new HashMap<String, String>(4) { { put(SERVICE, "org.apache.dubbo.monitor.dubbo.service.DemoService"); put(METHOD, "void timeoutException()"); } }, MetricLevel.NORMAL)); long timestamp = System.currentTimeMillis() / 5000 * 5000; Assertions.assertEquals(10, dubboClient.getMethodCountPerCategory(0).get("timeoutError").get(timestamp)); timestamp = timestamp / 15000 * 15000; Assertions.assertEquals(10, dubboMethod.getMethodCountPerCategory(0).get("timeoutError").get(timestamp)); }
@Test public void testProviderSuccess() throws Exception { IMetricManager metricManager = MetricManager.getIMetricManager(); metricManager.clear(); MetricsFilter metricsFilter = new MetricsFilter(); Invocation invocation = new RpcInvocation("sayName", DemoService.class.getName(), "", new Class<?>[0], new Object[0]); RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345); RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(SIDE_KEY, PROVIDER)); AppResponse response = AppResponseBuilder.create() .build(); onInvokeReturns(response); for (int i = 0; i < 100; i++) { metricsFilter.invoke(serviceInvoker, invocation); } FastCompass dubboClient = metricManager.getFastCompass(DUBBO_GROUP, new MetricName(DUBBO_PROVIDER, MetricLevel.MAJOR)); FastCompass dubboMethod = metricManager.getFastCompass(DUBBO_GROUP, new MetricName(DUBBO_PROVIDER_METHOD, new HashMap<String, String>(4) { { put(SERVICE, "org.apache.dubbo.monitor.dubbo.service.DemoService"); put(METHOD, "void sayName()"); } }, MetricLevel.NORMAL)); long timestamp = System.currentTimeMillis() / 5000 * 5000; Assertions.assertEquals(100, dubboClient.getMethodCountPerCategory(0).get("success").get(timestamp)); timestamp = timestamp / 15000 * 15000; Assertions.assertEquals(100, dubboMethod.getMethodCountPerCategory(0).get("success").get(timestamp)); }
@Test public void testInvokeMetricsService() { IMetricManager metricManager = MetricManager.getIMetricManager(); metricManager.clear(); MetricsFilter metricsFilter = new MetricsFilter(); Invocation invocation = new RpcInvocation("sayName", DemoService.class.getName(), "", new Class<?>[0], new Object[0]); RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345); RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(SIDE_KEY, PROVIDER_SIDE) .addParameter(TIMEOUT_KEY, 300)); AppResponse response = AppResponseBuilder.create() .build(); onInvokeReturns(response); for (int i = 0; i < 50; i++) { try { metricsFilter.invoke(serviceInvoker, invocation); metricsFilter.invoke(timeoutInvoker, invocation); } catch (RpcException e) { } } Protocol protocol = new DubboProtocol(); URL url = URL.valueOf("dubbo: Invoker<MetricsService> invoker = protocol.refer(MetricsService.class, url); invocation = new RpcInvocation("getMetricsByGroup", DemoService.class.getName(), "", new Class<?>[]{String.class}, new Object[]{DUBBO_GROUP}); try { Thread.sleep(5000); } catch (Exception e) { } String resStr = invoker.invoke(invocation).getValue().toString(); List<MetricObject> metricObjectList = new Gson().fromJson(resStr, new TypeToken<List<MetricObject>>() { }.getType()); Map<String, Object> metricMap = new HashMap<>(); for (int i = 0; i < metricObjectList.size(); i++) { MetricObject object = metricObjectList.get(i); String metric = object.getMetric().substring(object.getMetric().lastIndexOf(".") + 1); if ((double) object.getValue() > 0.0 && object.getMetricLevel().equals(MetricLevel.MAJOR)) metricMap.put(metric, object.getValue()); } Assertions.assertEquals(50.0, metricMap.get("success_bucket_count")); Assertions.assertEquals(50.0, metricMap.get("timeoutError_bucket_count")); Assertions.assertEquals(100.0, metricMap.get("bucket_count")); Assertions.assertEquals(100.0 / 5, metricMap.get("qps")); Assertions.assertEquals(50.0 / 100.0, metricMap.get("success_rate")); }
@Test public void testInvokeMetricsMethodService() { IMetricManager metricManager = MetricManager.getIMetricManager(); metricManager.clear(); MetricsFilter metricsFilter = new MetricsFilter(); Invocation sayNameInvocation = new RpcInvocation("sayName", DemoService.class.getName(), "", new Class<?>[0], new Object[0]); Invocation echoInvocation = new RpcInvocation("echo", DemoService.class.getName(), "", new Class<?>[]{Integer.class}, new Integer[]{1}); RpcContext.getContext().setRemoteAddress(NetUtils.getLocalHost(), 20880).setLocalAddress(NetUtils.getLocalHost(), 2345); RpcContext.getContext().setUrl(serviceInvoker.getUrl().addParameter(SIDE_KEY, PROVIDER_SIDE) .addParameter(TIMEOUT_KEY, 300)); AppResponse response = AppResponseBuilder.create() .build(); onInvokeReturns(response); for (int i = 0; i < 50; i++) { metricsFilter.invoke(serviceInvoker, sayNameInvocation); metricsFilter.invoke(serviceInvoker, echoInvocation); try { metricsFilter.invoke(timeoutInvoker, sayNameInvocation); } catch (RpcException e) { } try { metricsFilter.invoke(timeoutInvoker, echoInvocation); } catch (RpcException e) { } } Protocol protocol = new DubboProtocol(); URL url = URL.valueOf("dubbo: Invoker<MetricsService> invoker = protocol.refer(MetricsService.class, url); Invocation invocation = new RpcInvocation("getMetricsByGroup", DemoService.class.getName(), "", new Class<?>[]{String.class}, new Object[]{DUBBO_GROUP}); try { Thread.sleep(15000); } catch (Exception e) { } String resStr = invoker.invoke(invocation).getValue().toString(); List<MetricObject> metricObjectList = new Gson().fromJson(resStr, new TypeToken<List<MetricObject>>() { }.getType()); Map<String, Map<String, Object>> methodMetricMap = new HashMap<>(); for (int i = 0; i < metricObjectList.size(); i++) { MetricObject object = metricObjectList.get(i); String service = object.getTags().get("service"); String method = service + "." + object.getTags().get("method"); String metric = object.getMetric().substring(object.getMetric().lastIndexOf(".") + 1); Map map = methodMetricMap.get(method); if (map == null) { map = new HashMap(); methodMetricMap.put(method, map); } map.put(metric, object.getValue()); } Assertions.assertEquals(50.0, methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("success_bucket_count")); Assertions.assertEquals(50.0, methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("success_bucket_count")); Assertions.assertEquals(50.0, methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("timeoutError_bucket_count")); Assertions.assertEquals(50.0, methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("timeoutError_bucket_count")); Assertions.assertEquals(100.0 / 15, methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("qps")); Assertions.assertEquals(100.0 / 15, methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("qps")); Assertions.assertEquals(50.0 / 100.0, methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void sayName()").get("success_rate")); Assertions.assertEquals(50.0 / 100.0, methodMetricMap.get("org.apache.dubbo.monitor.dubbo.service.DemoService.void echo(Integer)").get("success_rate")); }