View Javadoc

1   /* ==========================================
2    * JperfProbe : Java Performance Probes
3    * ==========================================
4    *
5    * Project Info:  http://jperfprobe.sourceforge.net/
6    * Project Lead:  Tor-Erik Larsen (http://sourceforge.net/users/uptime62)
7    *
8    * (C) Copyright 2005, by Tor-Erik Larsen and Contributors.
9    *
10   * This library is free software; you can redistribute it and/or modify it
11   * under the terms of the GNU Lesser General Public License as published by
12   * the Free Software Foundation; either version 2.1 of the License, or
13   * (at your option) any later version.
14   *
15   * This library is distributed in the hope that it will be useful, but
16   * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
17   * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
18   * License for more details.
19   *
20   * You should have received a copy of the GNU Lesser General Public License
21   * along with this library; if not, write to the Free Software Foundation, Inc.,
22   * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
23   */
24  package net.sf.jperfprobe;
25  
26  import org.slf4j.*;
27  
28  import java.io.*;
29  import java.util.*;
30  import java.util.concurrent.locks.*;
31  
32  /**
33   * The ProbeManager is the probe factory. It makes it possible start start and stop a probe.
34   * The probe can be started in different ways:<br><br>
35   * <p/>
36   * 1. Start and stop from same scope, same thread, via probe name<br>
37   * 2. Start probes multithreaded from same scope, via probe name<br>
38   * 3. Start in one scope and stop in another scope singlethreaded via probe name<br>
39   * 4. Start in one scope and stop in another scope multithreaded via probe instance<br>
40   */
41  
42  public final class ProbeManagerImpl implements Serializable, ProbeManager {
43      final Logger log = LoggerFactory.getLogger(ProbeManagerImpl.class);
44  
45  
46      /**
47       * presentation unit enum
48       */
49      public static enum Presentation {
50          SECONDS(1000000000.0d, "s"),
51          MILLIS(1000000.0d, "ms"),
52          MICROS(1000.0d, "us"),
53          NANOS(1.0d, "ns");
54  
55          private final double timeFactor;
56          private final String unit;
57  
58          Presentation(double timeFactor, String u) {
59              this.timeFactor = timeFactor;
60              this.unit = u;
61          }
62  
63          /**
64           * Get the time factor for a presentation
65           *
66           * @return
67           */
68          public double getTimeFactor() {
69              return timeFactor;
70          }
71  
72          /**
73           * Get unit as string
74           *
75           * @return
76           */
77          /*
78          public String getUnit() {
79              return unit;
80          }
81          */
82      }
83  
84      private Presentation presentation = Presentation.NANOS;
85  
86      private int firstSamplesToSkip;
87  
88      // map containing all created results
89      private final Map<String, Result> resultMap = new HashMap<String, Result>();
90  
91      private final ReentrantReadWriteLock rmapRwl = new ReentrantReadWriteLock();
92      private final Lock rLock = rmapRwl.readLock();
93      private final Lock wLock = rmapRwl.writeLock();
94  
95  
96      private Time time = TimeFactory.getTime();
97  
98      /**
99       * Constructor of probe
100      */
101     public ProbeManagerImpl() {
102     }
103 
104 
105     /**
106      * Constr
107      *
108      * @param firstSamplesToSkip, samples to skip before recording
109      * @param presentation,       of measured values
110      * @param time,               the time implementation to use
111      */
112     public ProbeManagerImpl(int firstSamplesToSkip, Presentation presentation, Time time) {
113         this.firstSamplesToSkip = firstSamplesToSkip;
114         this.presentation = presentation;
115         this.time = time;
116     }
117 
118     /**
119      * Put a probe into the manager, if the probe exist it will be overwritten. This makes it possible
120      * to create a Probe outside the ProbeManager and insert it later.
121      *
122      * @param probeName
123      * @param probe
124      */
125     public void put(String probeName, Probe probe) {
126         getResult(probeName).addprobe(probe);
127     }
128 
129 
130     /**
131      * Get a result for a given probe
132      *
133      * @param probeName
134      * @return Result
135      */
136     public Result getResult(String probeName) {
137         Result result;
138 
139         synchronized (resultMap) {
140             result = resultMap.get(probeName);
141 
142             if (result == null) {
143                 result = new Result(firstSamplesToSkip, probeName);
144                 resultMap.put(probeName, result);
145             }
146         }
147 
148         return result;
149     }
150 
151     /**
152      * Get all the results
153      *
154      * @return
155      */
156     public Collection<Result> getResults() {
157         return resultMap.values();
158     }
159 
160     /**
161      * Get instance of a named probe, if it is non existent, a default probe will be created.
162      * And time will be set to null.
163      *
164      * @param probeName identifying name of probe
165      * @return probe, null if it cant look it up
166      */
167     public Probe getProbeInstance(String probeName) {
168         Result result = getResult(probeName);
169 
170         Probe probe;
171         synchronized (result) {
172             probe = result.getProbe();
173 
174             if (probe == null) {
175                 probe = new DefaultProbe(probeName, time);
176                 result.addprobe(probe);
177             }
178         }
179 
180         return probe;
181     }
182 
183     /**
184      * Start probe, identified by probeName, if the probe does not exist, it will be created.
185      *
186      * @param probeName name of existing or new probe.
187      */
188     public Probe start(String probeName) {
189         Probe p = getProbeInstance(probeName);
190         p.start();
191 
192         return p;
193     }
194 
195     public Probe startSingle(String probeName) {
196         Result result = getResult(probeName);
197         Probe probe = result.getSingleProbe();
198 
199         if (probe == null) {
200             probe = new DefaultProbe(probeName, time);
201             result.setSingleProbe(probe);
202         }
203 
204         probe.start();
205 
206         return probe;
207     }
208 
209     /**
210      * Stop timing. If its non existent, no time or sample will be registered.
211      *
212      * @param probeName name of probe to stop
213      */
214     public void stop(String probeName) {
215         Result result = getResult(probeName);
216 
217         Probe probe = result.getSingleProbe();
218         synchronized (result) {
219             if (probe == null) {
220                 probe = result.getProbe();
221                 if (probe == null) {
222                     return;
223                 }
224             }
225             probe.stop();
226             result.addSample(probe.getElapsed());
227         }
228 
229     }
230 
231     /**
232      * Add a sample from a probe. The probe does not need to be managed by ProbeManager
233      *
234      * @param p
235      */
236     public void addSampleFromProbe(Probe p) {
237         Result r = getResult(p.getName());
238         r.addSample(p.getElapsed());
239     }
240 
241     /**
242      * Clear the result for a named probe
243      *
244      * @param probeName
245      */
246     public void clear(String probeName) {
247         getResult(probeName).clear();
248     }
249 
250     /**
251      * Clear the results for all probes
252      */
253     public void clear() {
254         for (Result r : resultMap.values()) {
255             r.clear();
256         }
257         // should we really do this, the results could stay
258         resultMap.clear();
259     }
260 
261     /**
262      * Disable a named probe
263      * @param probeName
264      */
265     public void disable(String probeName) {
266         getResult(probeName).disable();
267     }
268 
269     /**
270      * Disable all probes.
271      */
272     public void disable() {
273         for (Result r : resultMap.values()) {
274             r.disable();
275         }
276     }
277 
278     public void enable(String probeName) {
279         getResult(probeName).enable();
280     }
281 
282     /**
283      * Enable all probes.
284      */
285     public void enable() {
286         for (Result r : resultMap.values()) {
287             r.enable();
288         }
289     }
290 
291     /**
292      * Set the presentation unit for presentation.
293      *
294      * @param p presentation to set
295      */
296     public void setPresentation(Presentation p) {
297         presentation = p;
298     }
299 
300 
301     public int getFirstSamplesToSkip() {
302         return firstSamplesToSkip;
303     }
304 
305     /**
306      * Set how many samples to skip in the calculation of statistics. If set to ie. 5, the first 5 samples will
307      * not be taken into account when calculating max/min/n#samples and average.
308      *
309      * @param _firstSamplesToSkip
310      */
311     public void setFirstSamplesToSkip(int _firstSamplesToSkip) {
312         firstSamplesToSkip = _firstSamplesToSkip;
313     }
314 
315     /**
316      * Get the current presentation for the manager
317      *
318      * @return presentation
319      */
320     public Presentation getPresentation() {
321         return presentation;
322     }
323 
324     /**
325      * Set the Time implementation.
326      *
327      * @param tim
328      */
329     public void setTime(Time tim) {
330         time = tim;
331     }
332 
333     public Time getTime() {
334         return this.time;
335     }
336 
337     /**
338      * Get result as a string
339      *
340      * @param probe
341      * @return result
342      */
343     public String toString(String probe) {
344         Result p = getResult(probe);
345 
346         return "probe name=" + probe + ", #samples=" + p.getNSamples() + ", total=" + p.getTotal()
347                 / presentation.getTimeFactor() + " , average=" + p.getAverage() / presentation.getTimeFactor()
348                 + " , max=" + p.getMax() / presentation.getTimeFactor() + "  , min=" + p.getMin()
349                 / presentation.getTimeFactor() + " , units=" + presentation;
350     }
351 
352     /**
353      * Get all samples from a probe, as a string newline delimited
354      *
355      * @param probe
356      * @return samples
357      */
358     public long[] getSamples(String probe) {
359         return getResult(probe).getSamples();
360     }
361 
362     /**
363      * Get all probe names in the ProbeManager
364      *
365      * @return probename
366      */
367     public String[] getNames() {
368         Set<String> names = resultMap.keySet();
369         String[] ret = new String[names.size()];
370 
371         return names.toArray(ret);
372     }
373 }