MeterBuilder { public void buildAndSend(MeterProcessor processor, GroovyShell shell) { final MeterEntity entity = buildEntity(processor, config.getScope()); final String metricsName = formatMeterName(config.getName()); EvalMultipleData values; try { values = (EvalMultipleData) shell.evaluate(config.getMeter().getValue()); } catch (Exception e) { log.warn("Building {} meter value failure", config.getName(), e); return; } switch (config.getMeter().getOperation()) { case "avg": final EvalData combinedSingleAvgData = values.combineAsSingleData(); if (combinedSingleAvgData instanceof EvalSingleData) { AcceptableValue<Long> avgValue = meterSystem.buildMetrics(metricsName, Long.class); avgValue.accept(entity, (long) ((EvalSingleData) combinedSingleAvgData).getValue()); avgValue.setTimeBucket(TimeBucket.getMinuteTimeBucket(processor.timestamp())); meterSystem.doStreamingCalculation(avgValue); } else { log.warn("avg function not support histogram value, please check meter:{}", combinedSingleAvgData.getName()); } break; case "avgHistogram": case "avgHistogramPercentile": final EvalData combinedHistogramData = values.combineAsSingleData(); if (combinedHistogramData instanceof EvalHistogramData) { final EvalHistogramData histogram = (EvalHistogramData) combinedHistogramData; long[] buckets = new long[histogram.getBuckets().size()]; long[] bucketValues = new long[histogram.getBuckets().size()]; int i = 0; for (Map.Entry<Double, Long> entry : histogram.getBuckets().entrySet()) { buckets[i] = entry.getKey().intValue(); bucketValues[i] = entry.getValue(); i++; } if (config.getMeter().getOperation().equals("avgHistogram")) { AcceptableValue<BucketedValues> avgHistogramValue = meterSystem.buildMetrics(metricsName, BucketedValues.class); avgHistogramValue.accept(entity, new BucketedValues(buckets, bucketValues)); avgHistogramValue.setTimeBucket(TimeBucket.getMinuteTimeBucket(processor.timestamp())); meterSystem.doStreamingCalculation(avgHistogramValue); } else { final AcceptableValue<AvgHistogramPercentileFunction.AvgPercentileArgument> percentileValue = meterSystem.buildMetrics(metricsName, AvgHistogramPercentileFunction.AvgPercentileArgument.class); percentileValue.accept(entity, new AvgHistogramPercentileFunction.AvgPercentileArgument(new BucketedValues(buckets, bucketValues), config.getMeter().getPercentile().stream().mapToInt(Integer::intValue).toArray())); percentileValue.setTimeBucket(TimeBucket.getMinuteTimeBucket(processor.timestamp())); meterSystem.doStreamingCalculation(percentileValue); } } else { log.warn(config.getMeter().getOperation() + " function not support single value, please check meter:{}", combinedHistogramData.getName()); } break; default: log.warn("Cannot support function:{}", config.getMeter().getOperation()); } } MeterBuilder(MeterConfig config, MeterSystem meterSystem); void initMeter(); boolean hasInit(); void buildAndSend(MeterProcessor processor, GroovyShell shell); MeterEntity buildEntity(MeterProcessor processor, Scope scope);  }
@Test public void testBuildAndSend() throws ModuleStartException { List<AcceptableValue> values = new ArrayList<>(); doAnswer(invocationOnMock -> { values.add(invocationOnMock.getArgument(0, AcceptableValue.class)); return null; }).when(meterSystem).doStreamingCalculation(any()); final MeterProcessService context = (MeterProcessService) Whitebox.getInternalState( processor, "processService"); context.enabledBuilders().stream().peek(b -> doCallRealMethod().when(b).buildAndSend(any(), any())); context.initMeters(); processor.process(); Assert.assertEquals(3, values.size()); final AvgFunction avg = (AvgFunction) values.get(0); Assert.assertEquals(100, avg.getSummation()); Assert.assertEquals(1, avg.getCount()); Assert.assertEquals(IDManager.ServiceID.buildId("service", true), avg.getServiceId()); Assert.assertEquals(IDManager.ServiceID.buildId("service", true), avg.getEntityId()); Assert.assertEquals(TimeBucket.getMinuteTimeBucket(timestamp), avg.getTimeBucket()); final AvgHistogramFunction avgHistogram = (AvgHistogramFunction) values.get(1); verifyDataTable(avgHistogram.getSummation(), 1, 10, 5, 15, 10, 3); verifyDataTable(avgHistogram.getCount(), 1, 1, 5, 1, 10, 1); Assert.assertEquals(IDManager.ServiceInstanceID.buildId( IDManager.ServiceID.buildId("service", true), "instance"), avgHistogram.getEntityId()); Assert.assertEquals(TimeBucket.getMinuteTimeBucket(timestamp), avgHistogram.getTimeBucket()); final AvgHistogramPercentileFunction avgPercentile = (AvgHistogramPercentileFunction) values.get(2); Assert.assertEquals(3, avgPercentile.getRanks().size()); Assert.assertEquals(50, avgPercentile.getRanks().get(0)); Assert.assertEquals(90, avgPercentile.getRanks().get(1)); Assert.assertEquals(99, avgPercentile.getRanks().get(2)); Assert.assertEquals(IDManager.EndpointID.buildId( IDManager.ServiceID.buildId("service", true), "test_endpoint"), avgPercentile.getEntityId()); verifyDataTable(avgPercentile.getSummation(), 1, 10, 5, 15, 10, 3); verifyDataTable(avgPercentile.getCount(), 1, 1, 5, 1, 10, 1); }