/*
* Copyright 2016 KairosDB Authors
*
* 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
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License 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 org.kairosdb.core.reporting;
import com.google.common.collect.ImmutableSortedMap;
import org.kairosdb.core.DataPoint;
import org.kairosdb.core.DataPointSet;
import org.kairosdb.core.datapoints.LongDataPointFactory;
import org.kairosdb.core.datapoints.StringDataPointFactory;
import org.kairosdb.core.datastore.KairosDatastore;
import org.kairosdb.core.exception.DatastoreException;
import org.kairosdb.util.Tags;
import java.util.LinkedList;
import java.util.SortedMap;
import java.util.TreeMap;
/**
Created with IntelliJ IDEA.
User: bhawkins
Date: 9/4/13
Time: 2:56 PM
To change this template use File | Settings | File Templates.
*/
public class ThreadReporter
{
private static class ReporterDataPoint
{
private final String m_metricName;
private final long m_value;
private final String m_strValue;
private final ImmutableSortedMap.Builder<String, String> m_tags;
private final int m_ttl;
private ReporterDataPoint(String metricName, SortedMap<String, String> tags,
long value, int ttl)
{
m_metricName = metricName;
m_value = value;
m_tags = Tags.create();
m_tags.putAll(tags);
m_ttl = ttl;
m_strValue = null;
}
private ReporterDataPoint(String metricName, SortedMap<String, String> tags,
String value, int ttl)
{
m_metricName = metricName;
m_value = 0;
m_tags = Tags.create();
m_tags.putAll(tags);
m_ttl = ttl;
m_strValue = value;
}
public String getMetricName() { return (m_metricName); }
public long getValue() { return (m_value); }
public String getStrValue() { return m_strValue; }
public void addTag(String name, String value)
{
m_tags.put(name, value);
}
public int getTtl() { return (m_ttl); }
public boolean isStringValue() { return m_strValue != null; }
public ImmutableSortedMap<String, String> getTags() { return m_tags.build(); }
}
private static class CurrentTags extends ThreadLocal<SortedMap<String, String>>
{
@Override
protected synchronized SortedMap<String, String> initialValue()
{
return new TreeMap<String, String>();
}
}
private static class ReporterData extends ThreadLocal<LinkedList<ReporterDataPoint>>
{
@Override
protected synchronized LinkedList<ReporterDataPoint> initialValue()
{
return (new LinkedList<ReporterDataPoint>());
}
public void addDataPoint(ReporterDataPoint dps)
{
get().addLast(dps);
}
public ReporterDataPoint getNextDataPoint()
{
return get().removeFirst();
}
public int getListSize()
{
return get().size();
}
}
private static class ReporterTime extends ThreadLocal<Long>
{
@Override
protected synchronized Long initialValue()
{
return (0L);
}
}
private static ReporterData s_reporterData = new ReporterData();
private static CurrentTags s_currentTags = new CurrentTags();
private static ReporterTime s_reportTime = new ReporterTime();
private ThreadReporter()
{
}
public static void setReportTime(long time)
{
s_reportTime.set(time);
}
public static long getReportTime()
{
return s_reportTime.get();
}
public static void addTag(String name, String value)
{
s_currentTags.get().put(name, value);
}
public static void removeTag(String name)
{
s_currentTags.get().remove(name);
}
public static void clearTags()
{
s_currentTags.get().clear();
}
public static ReporterDataPoint addDataPoint(String metric, long value)
{
return addDataPoint(metric, value, 0);
}
public static ReporterDataPoint addDataPoint(String metric, long value, int ttl)
{
ReporterDataPoint rdp = new ReporterDataPoint(metric, s_currentTags.get(),
value, ttl);
s_reporterData.addDataPoint(rdp);
return rdp;
}
public static ReporterDataPoint addDataPoint(String metric, String value)
{
return addDataPoint(metric, value, 0);
}
public static ReporterDataPoint addDataPoint(String metric, String value, int ttl)
{
ReporterDataPoint rdp = new ReporterDataPoint(metric, s_currentTags.get(),
value, ttl);
s_reporterData.addDataPoint(rdp);
return rdp;
}
public static void submitData(LongDataPointFactory longDataPointFactory,
StringDataPointFactory stringDataPointFactory,
KairosDatastore datastore) throws DatastoreException
{
while (s_reporterData.getListSize() != 0)
{
ReporterDataPoint dp = s_reporterData.getNextDataPoint();
if (dp.isStringValue())
{
datastore.putDataPoint(dp.getMetricName(), dp.getTags(),
stringDataPointFactory.createDataPoint(s_reportTime.get(), dp.getStrValue()),
dp.getTtl());
}
else
{
datastore.putDataPoint(dp.getMetricName(), dp.getTags(),
longDataPointFactory.createDataPoint(s_reportTime.get(), dp.getValue()),
dp.getTtl());
}
}
}
/**
Used in finally block to clear out unsent data in case an exception occurred.
*/
public static void clear()
{
while (s_reporterData.getListSize() != 0)
s_reporterData.getNextDataPoint();
}
}