com.amazonaws.services.cloudwatch.model.StandardUnit Java Examples

The following examples show how to use com.amazonaws.services.cloudwatch.model.StandardUnit. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: CloudWatchReporter.java    From metrics-cloudwatch with Apache License 2.0 6 votes vote down vote up
void reportCounter(Map.Entry<String, ? extends Counting> entry, String typeDimValue, List<MetricDatum> data) {
    Counting metric = entry.getValue();
    final long diff = diffLast(metric);
    if (diff == 0) {
        // Don't submit metrics that have not changed. No reason to keep these alive. Also saves on CloudWatch
        // costs.
        return;
    }

    DemuxedKey key = new DemuxedKey(appendGlobalDimensions(entry.getKey()));
    Iterables.addAll(data, key.newDatums(typeDimName, typeDimValue, new Function<MetricDatum, MetricDatum>() {
        @Override
        public MetricDatum apply(MetricDatum datum) {
            return datum.withValue((double) diff).withUnit(StandardUnit.Count);
        }
    }));
}
 
Example #2
Source File: DynamoDBReplicationEmitter.java    From dynamodb-cross-region-library with Apache License 2.0 6 votes vote down vote up
/**
 * {@inheritDoc}
 */
@Override
public void fail(final List<Record> records) {
    if (isShutdown) {
        if (records.isEmpty()) {
            // This is OK (but not expected)
            log.warn("Emitter fail method called after shutdown method was called. Continuing because list is empty");
            return;
        } else {
            throw new IllegalStateException("Emitter fail method called after shutdown method was called.");
        }
    }
    for (Record record : records) {
        log.error("Could not emit record: " + record);
    }
    final AmazonCloudWatchAsync cloudwatch = CLOUDWATCH.get();
    if (null != cloudwatch) {
        final double failed = records.size();
        final MetricDatum recordsProcessedFailedDatum = new MetricDatum().withMetricName(RECORDS_FAILED).withValue(failed).withUnit(StandardUnit.Count)
            .withTimestamp(new Date());
        final PutMetricDataRequest request = new PutMetricDataRequest().withNamespace(applicationName).withMetricData(recordsProcessedFailedDatum);
        cloudwatch.putMetricDataAsync(request);
    }
}
 
Example #3
Source File: CloudWatchRecorderTest.java    From swage with Apache License 2.0 6 votes vote down vote up
private MetricDatum makeDatum(
        final String id,
        final String name,
        final double sum,
        final double min,
        final double max,
        final int count,
        final StandardUnit unit)
{
    MetricDatum md = new MetricDatum().withMetricName(name).withUnit(unit);

    final StatisticSet statSet = new StatisticSet()
            .withSampleCount(Double.valueOf(count))
            .withSum(sum)
            .withMinimum(min)
            .withMaximum(max);
    md.setStatisticValues(statSet);

    List<Dimension> dimensions = new ArrayList<>(1);
    Dimension trace = new Dimension().withName(ContextData.ID.name).withValue(id);

    dimensions.add(trace);
    md.setDimensions(dimensions);

    return md;
}
 
Example #4
Source File: CloudWatchScanCountListener.java    From emodb with Apache License 2.0 6 votes vote down vote up
@Override
protected void runOneIteration() throws Exception {
    try {
        _cloudWatch.putMetricData(
                new PutMetricDataRequest()
                        .withNamespace(NAMESPACE)
                        .withMetricData(
                                new MetricDatum()
                                        .withTimestamp(new Date())
                                        .withMetricName(ACTIVE_AND_PENDING_SCANS)
                                        .withValue((double) (_activeScanCount + _pendingScanCount))
                                        .withUnit(StandardUnit.Count)
                                        .withDimensions(_dimensions)));
    } catch (AmazonClientException e) {
        _log.error("Failed to publish active and pending scans metric", e);
    }
}
 
Example #5
Source File: MetricDataAggregator.java    From swage with Apache License 2.0 6 votes vote down vote up
/**
 * Add a metric event to be aggregated.
 * Events with the same name, unit, and attributes will have their values
 * aggregated into {@link StatisticSet}s, with the aggregated data
 * available via {@link #flush}.
 *
 * @param context Metric context to use for dimension information
 * @param name Metric name
 * @param value Recorded value for the metric event
 * @param unit Unit for interpreting the value
 */
public void add(
        final MetricRecorder.RecorderContext context,
        final Metric name,
        final double value,
        final StandardUnit unit)
{
    //TODO: avoid doing this every time for a context - caching, or?
    List<Dimension> dimensions = dimensionMapper.getDimensions(name, context);

    DatumKey key = new DatumKey(name.toString(), unit, dimensions);
    statisticsMap.merge(
            key,
            new StatisticSet()
                    .withMaximum(value)
                    .withMinimum(value)
                    .withSampleCount(1D)
                    .withSum(value),
            MetricDataAggregator::sum);
}
 
Example #6
Source File: CloudWatchMeterRegistry.java    From micrometer with Apache License 2.0 5 votes vote down vote up
Stream<MetricDatum> functionTimerData(FunctionTimer timer) {
    // we can't know anything about max and percentiles originating from a function timer
    double sum = timer.totalTime(getBaseTimeUnit());
    if (!Double.isFinite(sum)) {
        return Stream.empty();
    }
    Stream.Builder<MetricDatum> metrics = Stream.builder();
    double count = timer.count();
    metrics.add(metricDatum(timer.getId(), "count", StandardUnit.Count, count));
    metrics.add(metricDatum(timer.getId(), "sum", sum));
    if (count > 0) {
        metrics.add(metricDatum(timer.getId(), "avg", timer.mean(getBaseTimeUnit())));
    }
    return metrics.build();
}
 
Example #7
Source File: CloudWatchAlertDispatcher.java    From s3mper with Apache License 2.0 5 votes vote down vote up
private void sendCloudWatchTimeoutAlert() {
    MetricDatum datum = new MetricDatum();
    datum.setMetricName(cloudWatchTimeoutMetric);
    datum.setUnit(StandardUnit.Count);
    datum.setValue(1.0);
    
    PutMetricDataRequest request = new PutMetricDataRequest();
    request.setNamespace(namespace);
    request.setMetricData(Collections.singleton(datum));
    
    cloudWatch.putMetricData(request);
}
 
Example #8
Source File: CloudWatchAlertDispatcher.java    From s3mper with Apache License 2.0 5 votes vote down vote up
private void sendCloudWatchConsistencyAlert() {
    MetricDatum datum = new MetricDatum();
    datum.setMetricName(cloudWatchConsistencyMetric);
    datum.setUnit(StandardUnit.Count);
    datum.setValue(1.0);
    
    PutMetricDataRequest request = new PutMetricDataRequest();
    request.setNamespace(namespace);
    request.setMetricData(Collections.singleton(datum));
    
    cloudWatch.putMetricData(request);
}
 
Example #9
Source File: MetricsCloudWatchReporter.java    From chassis with Apache License 2.0 5 votes vote down vote up
private void addDatum(String name, double value, LinkedList<PutMetricDataRequest> requests, Date timestamp) {
    if (logger.isDebugEnabled()) {
        logger.debug("Adding Datum {} with value {} at {}", name, value, timestamp);
    }
    if (requests.isEmpty() || requests.getLast().getMetricData().size() == MAX_CLOUDWATCH_DATUM_PER_REQUEST) {
        requests.add(createRequest());
    }
    PutMetricDataRequest request = requests.getLast();
    MetricDatum datum = new MetricDatum().withTimestamp(timestamp).withValue(value).withMetricName(name).withUnit(StandardUnit.None).withDimensions(createDimensions());
    request.withMetricData(datum);
}
 
Example #10
Source File: PutMetricData.java    From aws-doc-sdk-examples with Apache License 2.0 5 votes vote down vote up
public static void main(String[] args) {

        final String USAGE =
            "To run this example, supply a data point:\n" +
            "Ex: PutMetricData <data_point>\n";

        if (args.length != 1) {
            System.out.println(USAGE);
            System.exit(1);
        }

        Double data_point = Double.parseDouble(args[0]);

        final AmazonCloudWatch cw =
            AmazonCloudWatchClientBuilder.defaultClient();

        Dimension dimension = new Dimension()
            .withName("UNIQUE_PAGES")
            .withValue("URLS");

        MetricDatum datum = new MetricDatum()
            .withMetricName("PAGES_VISITED")
            .withUnit(StandardUnit.None)
            .withValue(data_point)
            .withDimensions(dimension);

        PutMetricDataRequest request = new PutMetricDataRequest()
            .withNamespace("SITE/TRAFFIC")
            .withMetricData(datum);

        PutMetricDataResult response = cw.putMetricData(request);

        System.out.printf("Successfully put data point %f", data_point);
    }
 
Example #11
Source File: CloudWatchMeterRegistry.java    From micrometer with Apache License 2.0 5 votes vote down vote up
private StandardUnit toStandardUnit(@Nullable String unit) {
    if (unit == null) {
        return StandardUnit.None;
    }
    StandardUnit standardUnit = STANDARD_UNIT_BY_LOWERCASE_VALUE.get(unit.toLowerCase());
    return standardUnit != null ? standardUnit : StandardUnit.None;
}
 
Example #12
Source File: CloudWatchMeterRegistry.java    From micrometer with Apache License 2.0 5 votes vote down vote up
@Nullable
private MetricDatum metricDatum(Meter.Id id, @Nullable String suffix, StandardUnit standardUnit, double value) {
    if (Double.isNaN(value)) {
        return null;
    }

    List<Tag> tags = id.getConventionTags(config().namingConvention());
    return new MetricDatum()
            .withMetricName(getMetricName(id, suffix))
            .withDimensions(toDimensions(tags))
            .withTimestamp(timestamp)
            .withValue(CloudWatchUtils.clampMetricValue(value))
            .withUnit(standardUnit);
}
 
Example #13
Source File: CloudWatchMeterRegistry.java    From micrometer with Apache License 2.0 5 votes vote down vote up
Stream<MetricDatum> functionCounterData(FunctionCounter counter) {
    MetricDatum metricDatum = metricDatum(counter.getId(), "count", StandardUnit.Count, counter.count());
    if (metricDatum == null) {
        return Stream.empty();
    }
    return Stream.of(metricDatum);
}
 
Example #14
Source File: CloudWatchMeterRegistry.java    From micrometer with Apache License 2.0 5 votes vote down vote up
Stream<MetricDatum> summaryData(DistributionSummary summary) {
    Stream.Builder<MetricDatum> metrics = Stream.builder();
    metrics.add(metricDatum(summary.getId(), "sum", summary.totalAmount()));
    long count = summary.count();
    metrics.add(metricDatum(summary.getId(), "count", StandardUnit.Count, count));
    if (count > 0) {
        metrics.add(metricDatum(summary.getId(), "avg", summary.mean()));
        metrics.add(metricDatum(summary.getId(), "max", summary.max()));
    }
    return metrics.build();

}
 
Example #15
Source File: CloudWatchMeterRegistry.java    From micrometer with Apache License 2.0 5 votes vote down vote up
Stream<MetricDatum> timerData(Timer timer) {
    Stream.Builder<MetricDatum> metrics = Stream.builder();
    metrics.add(metricDatum(timer.getId(), "sum", getBaseTimeUnit().name(), timer.totalTime(getBaseTimeUnit())));
    long count = timer.count();
    metrics.add(metricDatum(timer.getId(), "count", StandardUnit.Count, count));
    if (count > 0) {
        metrics.add(metricDatum(timer.getId(), "avg", getBaseTimeUnit().name(), timer.mean(getBaseTimeUnit())));
        metrics.add(metricDatum(timer.getId(), "max", getBaseTimeUnit().name(), timer.max(getBaseTimeUnit())));
    }
    return metrics.build();
}
 
Example #16
Source File: MetricDataAggregatorTest.java    From swage with Apache License 2.0 5 votes vote down vote up
@Test
public void single() throws Exception {
    final DimensionMapper mapper = new DimensionMapper.Builder()
            .addGlobalDimension(ContextData.ID)
            .build();

    final Metric name = Metric.define("SomeMetric");
    final double value = 3.14;
    final StandardUnit unit = StandardUnit.Terabits;

    final MetricRecorder.RecorderContext context = new MetricRecorder.RecorderContext(ContextData.withId(UUID.randomUUID().toString()).build());

    MetricDataAggregator aggregator = new MetricDataAggregator(mapper);
    aggregator.add(context, name, value, unit);

    List<MetricDatum> ags = aggregator.flush();

    assertEquals("One metric datum should aggregate to one entry", 1, ags.size());
    assertEquals("Metric datum has wrong name", name.toString(), ags.get(0).getMetricName());
    assertEquals("Metric datum has wrong unit", unit.toString(), ags.get(0).getUnit());

    StatisticSet stats = ags.get(0).getStatisticValues();
    assertEquals("Metric datum has wrong stats value", Double.valueOf(value), stats.getSum());
    assertEquals("Metric datum has wrong stats value", Double.valueOf(value), stats.getMinimum());
    assertEquals("Metric datum has wrong stats value", Double.valueOf(value), stats.getMaximum());
    assertEquals("Metric datum has wrong stats count", Double.valueOf(1), stats.getSampleCount());

    assertTrue("Flush with no attributes was non-empty", aggregator.flush().isEmpty());
}
 
Example #17
Source File: CloudWatchRecorderTest.java    From swage with Apache License 2.0 5 votes vote down vote up
@Test
public void record_and_shutdown() throws Exception {
    final DimensionMapper mapper = new DimensionMapper.Builder()
            .addGlobalDimension(ContextData.ID)
            .build();

    final String namespace = "spacename";

    final String id = UUID.randomUUID().toString();
    final TypedMap data = ContextData.withId(id).build();
    final double time = 123.45;

    final AmazonCloudWatch client = mock(AmazonCloudWatch.class);

    final CloudWatchRecorder recorder = new CloudWatchRecorder.Builder()
            .client(client)
            .namespace(namespace)
            .publishFrequency(120)
            .maxJitter(60)
            .dimensionMapper(mapper)
            .build();

    final MetricContext context = recorder.context(data);
    context.record(M_TIME, time, Unit.MILLISECOND, Instant.now());
    context.close();

    // shutdown right away, before first scheduled publish
    recorder.shutdown();

    final List<MetricDatum> expected = new ArrayList<>(1);
    expected.add(makeDatum(id, M_TIME.toString(), time, time, time, 1, StandardUnit.Milliseconds));

    verify(client).putMetricData(argThat(new RequestMatcher(namespace, expected)));
}
 
Example #18
Source File: CloudWatchRecorder.java    From swage with Apache License 2.0 5 votes vote down vote up
@Override
public void count(final Metric label, final long delta, final RecorderContext context)
{
    if (!running.get()) {
        log.debug("count called on shutdown recorder");
        //TODO: something besides silently ignore, perhaps IllegalStateException?
        return;
    }

    aggregator.add(context,
                   label,
                   Long.valueOf(delta).doubleValue(),
                   StandardUnit.Count);
}
 
Example #19
Source File: MetricDataAggregator.java    From swage with Apache License 2.0 5 votes vote down vote up
public DatumKey(
        final String name,
        final StandardUnit unit,
        final List<Dimension> dimensions)
{
    this.name = name;
    this.unit = unit;
    this.dimensions = dimensions;
}
 
Example #20
Source File: CloudwatchReporter.java    From bender with Apache License 2.0 4 votes vote down vote up
@Override
public void write(ArrayList<Stat> stats, long invokeTimeMs, Set<Tag> tags) {
  Date dt = new Date();
  dt.setTime(invokeTimeMs);

  Collection<Dimension> parentDims = tagsToDimensions(tags);
  List<MetricDatum> metrics = new ArrayList<MetricDatum>();

  /*
   * Create CW metric objects from bender internal Stat objects
   */
  for (Stat stat : stats) {
    /*
     * Dimension are CW's version of metric tags. A conversion must be done.
     */
    Collection<Dimension> metricDims = tagsToDimensions(stat.getTags());
    metricDims.addAll(parentDims);

    MetricDatum metric = new MetricDatum();
    metric.setMetricName(stat.getName());
    // TODO: add units to Stat object SYSTEMS-870
    metric.setUnit(StandardUnit.None);
    metric.setTimestamp(dt);
    metric.setDimensions(metricDims);
    metric.setValue((double) stat.getValue());

    metrics.add(metric);
  }

  /*
   * Not very well documented in java docs but CW only allows 20 metrics at a time.
   */
  List<List<MetricDatum>> chunks = ListUtils.partition(metrics, 20);
  for (List<MetricDatum> chunk : chunks) {
    PutMetricDataRequest req = new PutMetricDataRequest();
    req.withMetricData(chunk);
    req.setNamespace(namespace);

    this.client.putMetricData(req);
  }
}
 
Example #21
Source File: CloudWatchEmbeddedMetricsReporter.java    From bender with Apache License 2.0 4 votes vote down vote up
/**
 * Example of accepted format:
 * {
 *   "_aws": {
 *     "Timestamp": 1574109732004,
 *     "CloudWatchMetrics": [
 *       {
 *         "Namespace": "lambda-function-metrics",
 *         "Dimensions": [["functionVersion"]],
 *         "Metrics": [
 *           {
 *             "Name": "time",
 *             "Unit": "Milliseconds"
 *           }
 *         ]
 *       }
 *     ]
 *   },
 *   "functionVersion": "$LATEST",
 *   "time": 100,
 *   "requestId": "989ffbf8-9ace-4817-a57c-e4dd734019ee"
 * }
 *
 * Java code example: https://docs.aws.amazon.com/AmazonCloudWatch/latest/monitoring/CloudWatch_Embedded_Metric_Format_Generation_PutLogEvents.html
 */
public static String getCloudWatchEmbeddedMetricsJson(String namespace,
                                                      long timestamp,
                                                      Map<String, String> dimensions,
                                                      List<Stat> stats,
                                                      Gson gson) {
    Map<String, Object> embeddedMetricsObject = new HashMap<>();

    /* first add nodes for each dimension in the embedded object since it'll be shared by all stats/metrics */
    dimensions.forEach(embeddedMetricsObject::put);

    /* Each stat is essentially a metric so iterate through each stat (metric).
       We can be confident there are now duplicate stats since handler guarantees that
     */
    List<CloudWatchMetricObject> cwMetricObjects = new ArrayList<>();
    stats.forEach(s -> {
        /* each CloudWatchMetric object will have the overall dimensions at the operation level */
        List<String> allDimensions = new ArrayList<>(dimensions.keySet());
        List<Dimension> statDimensions = tagsToDimensions(s.getTags());
        allDimensions.addAll(statDimensions.stream()
                .map(Dimension::getName)
                .collect(Collectors.toList()));

        allDimensions = allDimensions.stream()
                .distinct()
                .collect(Collectors.toList());

        /* add dimension name/value to main embedded metrics object */
        statDimensions.forEach(d -> embeddedMetricsObject.put(d.getName(), d.getValue()));

        /* add stat metric info as overall field */
        embeddedMetricsObject.put(s.getName(), s.getValue());

        /* each stat will have a unique CloudWatchMetric object */
        cwMetricObjects.add(new CloudWatchMetricObject(namespace,
                Collections.singletonList(allDimensions),
                Collections.singletonList(new MetricPOJO(s.getName(), StandardUnit.None.toString())))
        );

    });

    /* finally add overall node with list of CWMetric objects */
    embeddedMetricsObject.put("_aws", new AWSMetricObject(timestamp, cwMetricObjects));

    return gson.toJson(embeddedMetricsObject);
}
 
Example #22
Source File: CloudWatchMeterRegistry.java    From micrometer with Apache License 2.0 4 votes vote down vote up
private Stream<MetricDatum> counterData(Counter counter) {
    return Stream.of(metricDatum(counter.getId(), "count", StandardUnit.Count, counter.count()));
}
 
Example #23
Source File: PutMetricAlarm.java    From aws-doc-sdk-examples with Apache License 2.0 4 votes vote down vote up
public static void main(String[] args) {

        final String USAGE =
            "To run this example, supply an alarm name and instance id\n" +
            "Ex: DeleteAlarm <alarm-name> <instance-id>\n";

        if (args.length != 2) {
            System.out.println(USAGE);
            System.exit(1);
        }

        String alarmName = args[0];
        String instanceId = args[1];

        final AmazonCloudWatch cw =
            AmazonCloudWatchClientBuilder.defaultClient();

        Dimension dimension = new Dimension()
            .withName("InstanceId")
            .withValue(instanceId);

        PutMetricAlarmRequest request = new PutMetricAlarmRequest()
            .withAlarmName(alarmName)
            .withComparisonOperator(
                ComparisonOperator.GreaterThanThreshold)
            .withEvaluationPeriods(1)
            .withMetricName("CPUUtilization")
            .withNamespace("AWS/EC2")
            .withPeriod(60)
            .withStatistic(Statistic.Average)
            .withThreshold(70.0)
            .withActionsEnabled(false)
            .withAlarmDescription(
                "Alarm when server CPU utilization exceeds 70%")
            .withUnit(StandardUnit.Seconds)
            .withDimensions(dimension);

        PutMetricAlarmResult response = cw.putMetricAlarm(request);

        System.out.printf(
            "Successfully created alarm with name %s", alarmName);

    }
 
Example #24
Source File: CloudWatchRecorderTest.java    From swage with Apache License 2.0 4 votes vote down vote up
@Test
public void aggregation() throws Exception {
    final DimensionMapper mapper = new DimensionMapper.Builder()
            .addGlobalDimension(ContextData.ID)
            .build();

    final String namespace = "testytesttest";
    final String id = UUID.randomUUID().toString();

    final double[] timeVals = {867, 5309};
    final double[] percVals = {0.01, 97.3, 3.1415};
    final int[] failCnts = {1, 3, 0, 42};

    final List<MetricDatum> expected = new ArrayList<>(3);
    expected.add(makeDatum(id,
                           M_TIME.toString(),
                           Arrays.stream(timeVals).sum(),
                           Arrays.stream(timeVals).min().getAsDouble(),
                           Arrays.stream(timeVals).max().getAsDouble(),
                           timeVals.length,
                           StandardUnit.Milliseconds));
    expected.add(makeDatum(id,
                           M_PERC.toString(),
                           Arrays.stream(percVals).sum(),
                           Arrays.stream(percVals).min().getAsDouble(),
                           Arrays.stream(percVals).max().getAsDouble(),
                           percVals.length,
                           StandardUnit.Percent));
    expected.add(makeDatum(id,
                           M_FAIL.toString(),
                           Arrays.stream(failCnts).sum(),
                           Arrays.stream(failCnts).min().getAsInt(),
                           Arrays.stream(failCnts).max().getAsInt(),
                           failCnts.length,
                           StandardUnit.Count));


    final AmazonCloudWatch client = mock(AmazonCloudWatch.class);

    CloudWatchRecorder recorder = null;
    try {
        // no jitter, publish soon
        recorder = new CloudWatchRecorder.Builder()
                .client(client)
                .namespace(namespace)
                .maxJitter(0)
                .publishFrequency(1)
                .dimensionMapper(mapper)
                .build();

        final TypedMap data = ContextData.withId(id).build();
        final MetricContext context = recorder.context(data);

        context.count(M_FAIL, failCnts[0]);
        context.record(M_PERC, percVals[0], Unit.PERCENT, Instant.now());
        context.record(M_TIME, timeVals[0], Unit.MILLISECOND, Instant.now());
        context.count(M_FAIL, failCnts[1]);
        context.record(M_PERC, percVals[1], Unit.PERCENT, Instant.now());
        context.record(M_TIME, timeVals[1], Unit.MILLISECOND, Instant.now());
        context.count(M_FAIL, failCnts[2]);
        context.record(M_PERC, percVals[2], Unit.PERCENT, Instant.now());
        context.count(M_FAIL, failCnts[3]);
        context.close();

        // allow time for one publish
        Thread.sleep(1024);
    } finally {
        recorder.shutdown();
    }

    verify(client).putMetricData(argThat(new RequestMatcher(namespace, expected)));
}
 
Example #25
Source File: CloudWatchRecorderTest.java    From swage with Apache License 2.0 4 votes vote down vote up
@Test
public void no_aggregation() throws Exception {
    final DimensionMapper mapper = new DimensionMapper.Builder()
            .addGlobalDimension(ContextData.ID)
            .build();

    final String namespace = "testytesttest";
    final String id = UUID.randomUUID().toString();
    final Integer time = Integer.valueOf(23);
    final Integer load = Integer.valueOf(87);

    final AmazonCloudWatch client = mock(AmazonCloudWatch.class);

    CloudWatchRecorder recorder = null;
    try {
        // no jitter, publish soon
        recorder = new CloudWatchRecorder.Builder()
                .client(client)
                .namespace(namespace)
                .maxJitter(0)
                .publishFrequency(1)
                .dimensionMapper(mapper)
                .build();

        final TypedMap data = ContextData.withId(id).build();
        final MetricContext context = recorder.context(data);

        final Instant timestamp = Instant.now();

        context.record(M_TIME, time, Unit.MILLISECOND, timestamp);
        context.count(M_FAIL, 1);
        context.record(M_PERC, load, Unit.PERCENT, timestamp);
        context.close();

        // allow time for one publish
        Thread.sleep(1024);
    } finally {
        recorder.shutdown();
    }

    final List<MetricDatum> expected = new ArrayList<>(2);
    expected.add(makeDatum(id, M_TIME.toString(), time, time, time, 1, StandardUnit.Milliseconds));
    expected.add(makeDatum(id, M_PERC.toString(), load, load, load, 1, StandardUnit.Percent));
    expected.add(makeDatum(id, M_FAIL.toString(), 1, 1, 1, 1, StandardUnit.Count));

    verify(client).putMetricData(argThat(new RequestMatcher(namespace, expected)));
}