/*******************************************************************************
* Copyright (c) 2006-2010 eBay Inc. All Rights Reserved.
* 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
*******************************************************************************/
package org.ebayopensource.turmeric.runtime.common.impl.monitoring.storage;
import java.util.Collection;
import java.util.Formatter;
import java.util.Map;
import org.ebayopensource.turmeric.runtime.common.exceptions.ServiceException;
import org.ebayopensource.turmeric.runtime.common.monitoring.MetricClassifier;
import org.ebayopensource.turmeric.runtime.common.monitoring.MetricId;
import org.ebayopensource.turmeric.runtime.common.monitoring.MetricsStorageProvider;
import org.ebayopensource.turmeric.runtime.common.monitoring.value.MetricComponentValue;
import org.ebayopensource.turmeric.runtime.common.monitoring.value.MetricValue;
import org.ebayopensource.turmeric.runtime.common.monitoring.value.MetricValueAggregator;
/**
* This is an abstract base class for storage provider. It implements the
* MetricsSotrageProvider interface. The saveMetricSnapshot method has
* interception points: prelude, saveMetricValue, epilog, finalProcessing)
* for subclass to customize the logging behaviors.
* prelude customizes the header;
* epilog customizes the tailer;
* saveMetricValue logs the metric value for one metric.
* finalProcessing cleans up the logger after a snapshot is logged.
*
* @author wdeng
*/
public abstract class SnapshotLogger implements MetricsStorageProvider {
String m_collectionLocation;
Integer m_snapshotInterval;
public void init(Map<String,String> options, String name, String collectionLocation, Integer snapshotInterval) {
m_collectionLocation = collectionLocation;
m_snapshotInterval = snapshotInterval;
}
public final void saveMetricSnapshot(long timeSnapshot, Collection<MetricValueAggregator> snapshot) throws ServiceException
{
if (snapshot.isEmpty()) {
return;
}
if (snapshot.size() == 0) {
return;
}
try {
prelude(timeSnapshot, snapshot);
for (MetricValueAggregator aggr: snapshot) {
aggr = getAggregator(aggr);
MetricId id = aggr.getMetricId();
Collection<MetricClassifier> clzfers = aggr.getClassifiers();
for (MetricClassifier clzfer: clzfers) {
MetricValue value = aggr.getValue(clzfer);
saveMetricValue(timeSnapshot, id, clzfer, value);
}
}
epilog(timeSnapshot, snapshot);
} finally {
finalProcessing(timeSnapshot, snapshot);
}
}
/**
* This method provides the hook-point for converting the aggregated value to
* its value for output. For example, diff based provider will find the difference
* between the passed in value and the previous value and returns the diff.
*
* By default it dose nothing but return the argument value.
*
* @param value
* @return
*/
protected MetricValueAggregator getAggregator(MetricValueAggregator value) {
return value;
}
/**
* Used to customize the header of a snapshot log. default is do nothing.
*
* @param snapshotTime
* @param snapshot
* @throws ServiceException
*/
protected void prelude(long snapshotTime, Collection<MetricValueAggregator> snapshot)
throws ServiceException {
// subclasses can hook in
}
/**
* Used to customize the tailer of a snapshot log. default is do nothing.
*
* @param snapshotTime
* @param snapshot
* @throws ServiceException
*/
protected void epilog(long snapshotTime, Collection<MetricValueAggregator> snapshot) throws ServiceException {
// subclasses can hook in
}
/**
* Defines clean up behaviors after a snapshot is logged.
*
* @param snapshotTime
* @param snapshot
*/
protected void finalProcessing(long snapshotTime, Collection<MetricValueAggregator> snapshot) {
// subclasses can hook in
}
/**
* Defines the way to log one metric value.
*
* @param timeSnapshot
* @param id
* @param key
* @param value
*/
protected abstract void saveMetricValue(long timeSnapshot, MetricId id,
MetricClassifier key, MetricValue value);
protected static void formatComponentValue(MetricComponentValue value, Formatter formatter) {
Object v = value.getValue();
if (v instanceof Float || v instanceof Double) {
formatter.format("%1$30.4f", v);
return;
}
formatter.format("%1$s", v);
}
public String getCollectionLocation() {
return m_collectionLocation;
}
}