/** * Helios, OpenSource Monitoring * Brought to you by the Helios Development Group * * Copyright 2007, Helios Development Group and individual contributors * as indicated by the @author tags. See the copyright.txt file in the * distribution for a full listing of individual contributors. * * This is free software; you can redistribute it and/or modify it * under the terms of the GNU Lesser General Public License as * published by the Free Software Foundation; either version 2.1 of * the License, or (at your option) any later version. * * This software is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this software; if not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA, or see the FSF site: http://www.fsf.org. * */ package org.helios.apmrouter.destination.chronicletimeseries; import java.util.Date; import java.util.Map; import java.util.TreeMap; import org.helios.apmrouter.catalog.EntryStatus; import vanilla.java.chronicle.impl.IndexedChronicle; import vanilla.java.chronicle.impl.UnsafeExcerpt; /** * <p>Title: SeriesEntry</p> * <p>Description: Represents a time-series tier for one metric type within one tier</p> * <p>Company: Helios Development Group LLC</p> * @author Whitehead (nwhitehead AT heliosdev DOT org) * <p><code>org.helios.apmrouter.destination.chronicletimeseries.SeriesEntry</code></p> */ public class SeriesEntry implements SeriesEntryMBean { /** The metric ID */ protected final long metricId; /** The start time of the first period in the window */ protected long startPeriod = -1; /** The start time of the last period in the window */ protected long endPeriod = -1; /** The number of periods in the window */ protected int periodCount = -1; /** The up/down status for this entry */ protected EntryStatus status = EntryStatus.ACTIVE; /** The excerpt used to read/write this entry */ protected final UnsafeExcerpt<IndexedChronicle> excerpt; /** The values recorded in each period in the window keyed by the timestamp of the period */ protected final Map<Long, long[]> periods = new TreeMap<Long, long[]>(); /** * Creates a new SeriesEntry for the specified metric * @param ex The excerpt to read with * @param metricId The metric id to read * @param includePeriods true to incliude the period detail, false for the header only */ SeriesEntry(UnsafeExcerpt<IndexedChronicle> ex, long metricId, boolean includePeriods) { if(!ex.index(metricId)) throw new InvalidIndexExcetpion("Invalid index [" + metricId + "]", new Throwable()); excerpt = ex; this.metricId = metricId; startPeriod = ex.readLong(); endPeriod = ex.readLong(); periodCount = ex.readInt(); status = EntryStatus.forByte(ex.readByte()); if(includePeriods) { for(int i = 0; i < periodCount; i++) { long ts = ex.readLong(); long[] values = new long[4]; for(int x = 0; x < 4; x++) { values[x] = ex.readLong(); } periods.put(ts, values); } } } public String toString() { StringBuilder b = new StringBuilder("Metric ID:"); b.append(metricId); b.append("\nStart Period:").append(new Date(startPeriod)); b.append("\nEnd Period:").append(new Date(endPeriod)); b.append("\nStatus:").append(status.name()); b.append("\nPeriod Count:").append(periodCount).append("/").append(periods.size()); if(!periods.isEmpty()) { for(Map.Entry<Long, long[]> pentry: periods.entrySet()) { long[] arr = pentry.getValue(); b.append("\n\tPeriod:").append(new Date(pentry.getKey())) .append(" Min:").append(arr[0]) .append(" Max:").append(arr[1]) .append(" Avg:").append(arr[2]) .append(" Cnt:").append(arr[3]); } } return b.toString(); } /** * {@inheritDoc} * @see org.helios.apmrouter.destination.chronicletimeseries.SeriesEntryMBean#getMetricId() */ @Override public long getMetricId() { return metricId; } /** * {@inheritDoc} * @see org.helios.apmrouter.destination.chronicletimeseries.SeriesEntryMBean#getStartPeriod() */ @Override public Date getStartPeriod() { return new Date(startPeriod); } /** * {@inheritDoc} * @see org.helios.apmrouter.destination.chronicletimeseries.SeriesEntryMBean#getStartPeriodTimestamp() */ @Override public long getStartPeriodTimestamp() { return startPeriod; } /** * {@inheritDoc} * @see org.helios.apmrouter.destination.chronicletimeseries.SeriesEntryMBean#getEndPeriod() */ @Override public Date getEndPeriod() { return new Date(endPeriod); } /** * {@inheritDoc} * @see org.helios.apmrouter.destination.chronicletimeseries.SeriesEntryMBean#getEndPeriodTimestamp() */ @Override public long getEndPeriodTimestamp() { return endPeriod; } /** * {@inheritDoc} * @see org.helios.apmrouter.destination.chronicletimeseries.SeriesEntryMBean#getPeriodCount() */ @Override public int getPeriodCount() { return periodCount; } /** * {@inheritDoc} * @see org.helios.apmrouter.destination.chronicletimeseries.SeriesEntryMBean#getEntryStatus() */ @Override public EntryStatus getEntryStatus() { return status; } /** * {@inheritDoc} * @see org.helios.apmrouter.destination.chronicletimeseries.SeriesEntryMBean#getPeriods() */ @Override public Map<Long, long[]> getPeriods() { return periods; } /** * {@inheritDoc} * @see org.helios.apmrouter.destination.chronicletimeseries.SeriesEntryMBean#updateStatus(org.helios.apmrouter.catalog.EntryStatus) */ @Override public EntryStatus updateStatus(final EntryStatus status) { EntryStatus tmp = this.status; this.status = status; this.excerpt.write(ChronicleTier.H_STATUS, this.status.byteOrdinal()); return this.status!=tmp ? tmp : null; } }