com.amediamanager.metrics.MetricBatcher.java Source code

Java tutorial

Introduction

Here is the source code for com.amediamanager.metrics.MetricBatcher.java

Source

/*
 * Copyright 2014 Amazon Technologies, 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://aws.amazon.com/apache2.0
 *
 * This file 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.amediamanager.metrics;

import java.util.Collection;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;

import com.amazonaws.handlers.AsyncHandler;
import com.amazonaws.services.cloudwatch.AmazonCloudWatchAsync;
import com.amazonaws.services.cloudwatch.model.MetricDatum;
import com.amazonaws.services.cloudwatch.model.PutMetricDataRequest;
import com.google.common.collect.LinkedListMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;

public class MetricBatcher {

    private static final Logger LOG = LoggerFactory.getLogger(MetricBatcher.class);
    private static final int BATCH_SIZE = 10;

    private final Multimap<String, MetricDatum> queuedDatums = Multimaps
            .synchronizedListMultimap(LinkedListMultimap.<String, MetricDatum>create());

    protected final AmazonCloudWatchAsync cloudWatch;

    public MetricBatcher(AmazonCloudWatchAsync cloudWatch) {
        this.cloudWatch = cloudWatch;
    }

    public final void addDatum(String namespace, MetricDatum datum) {
        queuedDatums.put(namespace, datum);
    }

    public final void addDatums(String namespace, Collection<MetricDatum> datums) {
        queuedDatums.putAll(namespace, datums);
    }

    @Scheduled(fixedDelay = 60000)
    private void send() {
        LOG.info("Sending metric data.");
        synchronized (queuedDatums) {
            sendBatch(LinkedListMultimap.create(queuedDatums).asMap());
            queuedDatums.clear();
        }
    }

    protected void sendBatch(Map<String, Collection<MetricDatum>> datums) {
        for (final Map.Entry<String, Collection<MetricDatum>> e : datums.entrySet()) {
            for (final List<MetricDatum> batch : Lists.partition(Lists.newLinkedList(e.getValue()), BATCH_SIZE)) {
                cloudWatch.putMetricDataAsync(
                        new PutMetricDataRequest().withNamespace(e.getKey()).withMetricData(batch),
                        new AsyncHandler<PutMetricDataRequest, Void>() {

                            @Override
                            public void onError(Exception exception) {
                                LOG.error("PutMetricData failed", exception);
                                LOG.info("Requeueing metric data.");
                                queuedDatums.putAll(e.getKey(), batch);
                            }

                            @Override
                            public void onSuccess(PutMetricDataRequest request, Void result) {
                                LOG.info("Successfully put " + request.getMetricData().size()
                                        + " datums for namespace " + request.getNamespace());
                                LOG.debug("Request", request);
                            }

                        });
            }
        }
    }
}