001package org.javasimon.callback.timeline; 002 003import org.javasimon.Simon; 004import org.javasimon.Split; 005import org.javasimon.Stopwatch; 006import org.javasimon.StopwatchSample; 007import org.javasimon.callback.CallbackSkeleton; 008 009/** 010 * Timeline callback aims at keeping simon data for the last N minutes. 011 * A "timeline" object is stored in each Simon, it's fixed size ring buffer 012 * of "time ranges". A "time range" aggregates Simon data for a fixed duration. 013 * <p/> 014 * Example: a timeline containing 6 time ranges of 10 minutes each can be used to 015 * see evolution for an hour. 016 * 017 * @author gerald 018 */ 019public class TimelineCallback extends CallbackSkeleton { 020 021 /** Default attribute name for storing timelines. */ 022 public static final String TIMELINE_ATTRIBUTE_NAME = "timeline"; 023 024 /** Attribute name for storing timeline in Simons. */ 025 private final String timelineAttributeName; 026 /** Number of time ranges to keep in the timeline. */ 027 private final int timelineCapacity; 028 /** Width in milliseconds of the time ranges. */ 029 private final long timeRangeWidth; 030 031 /** 032 * Main constructor. 033 * 034 * @param timelineAttributeName Simon attribute name used for storing Timeline 035 * @param timelineCapacity Timeline capacity (number of time ranges) 036 * @param timeRangeWidth Time range width (in milliseconds) 037 */ 038 public TimelineCallback(String timelineAttributeName, int timelineCapacity, long timeRangeWidth) { 039 this.timelineAttributeName = timelineAttributeName; 040 this.timelineCapacity = timelineCapacity; 041 this.timeRangeWidth = timeRangeWidth; 042 } 043 044 /** 045 * Constructor using default attribute name. 046 * 047 * @param timelineCapacity Timeline capacity (number of time ranges) 048 * @param timeRangeWidth Time range width (in milliseconds) 049 */ 050 public TimelineCallback(int timelineCapacity, long timeRangeWidth) { 051 this(TIMELINE_ATTRIBUTE_NAME, timelineCapacity, timeRangeWidth); 052 } 053 054 /** 055 * Constructor using default attribute name, default timeline capacity of 6 056 * and default timeline width of 10 minutes. Timeline stores an hour of data. 057 */ 058 public TimelineCallback() { 059 this(6, 1000L * 60L * 6L); 060 } 061 062 /** 063 * Returns timeline for given Stopwatch. 064 * 065 * @param stopwatch Stopwatch 066 * @return Stopwatch timeline 067 */ 068 private StopwatchTimeline getStopwatchTimeline(Stopwatch stopwatch) { 069 return (StopwatchTimeline) stopwatch.getAttribute(timelineAttributeName); 070 } 071 072 /** 073 * On simon creation a timeline attribute is added (for Stopwatches only). 074 * 075 * @param simon created simon 076 */ 077 @Override 078 public void onSimonCreated(Simon simon) { 079 if (simon instanceof Stopwatch) { 080 simon.setAttribute(timelineAttributeName, new StopwatchTimeline(timelineCapacity, timeRangeWidth)); 081 } 082 } 083 084 @Override 085 public void onStopwatchAdd(Stopwatch stopwatch, Split split, StopwatchSample sample) { 086 StopwatchTimeline timeline = getStopwatchTimeline(stopwatch); 087 if (timeline != null) { 088 timeline.addSplit(split); 089 } 090 } 091 092 @Override 093 public void onStopwatchStop(Split split, StopwatchSample sample) { 094 StopwatchTimeline timeline = getStopwatchTimeline(split.getStopwatch()); 095 if (timeline != null) { 096 timeline.addSplit(split); 097 } 098 } 099}