Coverage report

  %line %branch
net.sf.infrared.agent.StatisticsCollector
1% 
62% 

 1  
 /* 
 2  
  * Copyright 2005 Tavant Technologies and Contributors
 3  
  * 
 4  
  * Licensed under the Apache License, Version 2.0 (the "License")
 5  
  * you may not use this file except in compliance with the License.
 6  
  * You may obtain a copy of the License at
 7  
  *
 8  
  *     http://www.apache.org/licenses/LICENSE-2.0
 9  
  *
 10  
  * Unless required by applicable law or agreed to in writing, software
 11  
  * distributed under the License is distributed on an "AS IS" BASIS,
 12  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 13  
  * See the License for the specific language governing permissions and
 14  
  * limitations under the License.
 15  
  * 
 16  
  * 
 17  
  *
 18  
  * Original Author: kamal.govindraj (Tavant Technologies) 
 19  
  * Contributor(s):  binil.thomas
 20  
  *
 21  
  */
 22  
 package net.sf.infrared.agent;
 23  
 
 24  
 import java.util.Date;
 25  
 import java.util.List;
 26  
 import java.util.Map;
 27  
 
 28  
 import net.sf.infrared.agent.transport.CollectionStrategy;
 29  
 import net.sf.infrared.base.model.ExecutionTimer;
 30  
 import net.sf.infrared.base.model.OperationStatistics;
 31  
 import net.sf.infrared.base.util.LoggingFactory;
 32  
 import net.sf.infrared.base.util.Tree;
 33  
 
 34  
 import org.apache.log4j.Logger;
 35  
 
 36  
 /**
 37  
  * 
 38  
  * @author kamal.govindraj
 39  
  * @author binil.thomas
 40  
  */
 41  
 public class StatisticsCollector {
 42  2
     private static final Logger log = LoggingFactory.getLogger(StatisticsCollector.class);
 43  
     
 44  1
     private static final Logger healthLog = LoggingFactory.getLogger("net.sf.infrared.agent.health");
 45  
 
 46  0
     private MonitorConfig configuration = null;
 47  
 
 48  0
     private String applicationName = "all applications";
 49  
 
 50  0
     private String instanceId = "unknown instance";
 51  
 
 52  0
     private CollectionStrategy collectionStrategy = null;
 53  
 
 54  0
     private ChildTimeTracker childTracker = new ChildTimeTrackerImpl();
 55  
 
 56  0
     private LayerTimeTracker layerTracker = new LayerTimeTracker();
 57  
 
 58  0
     private TreeBuilder treeBuilder = new TreeBuilder();
 59  
 
 60  0
     private ExecutionTimeTracker executionTracker = new ExecutionTimeTracker();
 61  
 
 62  0
     private int depth = 0;
 63  
     
 64  0
     private long startTime = -1;
 65  
     
 66  0
     private long endTime = -1;
 67  
     
 68  0
     private int numOfExecutionsTracked = 0;
 69  
     
 70  0
     private int numOfExecutionsIgnored = 0;
 71  
     
 72  
     // These 2 fields are added to cache the values of callTracing and pruneBelowTime
 73  
     // This is to avoid going back to the configuration for every execution that is 
 74  
     // recorded.
 75  
     private boolean callTracing;
 76  
     
 77  
     private long pruneBelowTime;
 78  
     
 79  0
     private boolean callInProgress = false;
 80  
 
 81  
     public StatisticsCollector(CollectionStrategy collectionStrategy, String applicationName,
 82  0
             String instanceId, MonitorConfig configuration) {
 83  
 
 84  0
         this.collectionStrategy = collectionStrategy;
 85  0
         this.applicationName = applicationName;
 86  0
         this.instanceId = instanceId;
 87  0
         this.configuration = configuration;
 88  
 
 89  0
         if (log.isDebugEnabled()) {
 90  0
             log.debug("Created Statistics Collector for application " + applicationName
 91  
                     + " on host " + instanceId + " thread " + Thread.currentThread());
 92  
         }
 93  
         
 94  0
         callTracing = configuration.isCallTracingEnabled();
 95  0
         pruneBelowTime = configuration.getPruneThreshold();
 96  0
         treeBuilder.setPruneBelowTime(pruneBelowTime);
 97  0
         layerTracker.setPruneBelowTime(pruneBelowTime);
 98  
 
 99  0
     }
 100  
 
 101  0
     StatisticsCollector() {
 102  0
     }
 103  
 
 104  
     public void recordExecutionBegin(ExecutionTimer timer) {
 105  0
         if (callInProgress) {
 106  0
             return;
 107  
         }
 108  0
         callInProgress = true;
 109  0
         begin(timer);
 110  0
         timer.start();        
 111  0
         callInProgress = false;
 112  0
     }
 113  
     
 114  
     void begin(ExecutionTimer timer) {
 115  0
         incrementDepthCount();
 116  
 
 117  0
         childTracker.begin();
 118  0
         layerTracker.enterLayer(timer);
 119  0
         if (isCallTracingEnabled()) {
 120  0
             treeBuilder.begin(timer);
 121  
         }
 122  
         
 123  0
         if (log.isDebugEnabled()) {
 124  0
             log.debug(this + " - Recording beginining of execution of " + timer.getContext()
 125  
                     + " at depth " + depth);
 126  
         }
 127  0
     }
 128  
 
 129  
     public void recordExecutionEnd(ExecutionTimer timer) {     
 130  0
         if (callInProgress) {
 131  0
             return;
 132  
         }
 133  0
         callInProgress = true;
 134  0
         timer.stop();
 135  0
         end(timer);
 136  0
         callInProgress = false;
 137  0
     }
 138  
 
 139  
     void end(ExecutionTimer timer) {
 140  0
         if (log.isDebugEnabled()) {
 141  0
             log.debug(this + " - Recorded end of execution of " + timer.getContext()
 142  
                     + " at depth " + depth);
 143  
         }
 144  
 
 145  0
         setExclusiveTime(timer);
 146  
 
 147  0
         boolean ok = true;
 148  0
         if (isCallTracingEnabled()) {
 149  0
             ok = treeBuilder.end(timer) && ok;
 150  
         }
 151  0
         if (timer.getInclusiveTime() > pruneBelowTime) {
 152  0
             executionTracker.recordExecution(layerTracker.getCurrentLayer(), timer);            
 153  
             // @TODO bug!! Layer time of those ignored executions will be recorded
 154  
         } else {
 155  0
             if (log.isDebugEnabled()) {
 156  0
                 log.debug("Discarded tracking execution of " + timer.getContext() + 
 157  
                         " because the time (" + timer.getInclusiveTime() + 
 158  
                         ") <= prune threshold (" + pruneBelowTime + ")");
 159  
             }
 160  
         }
 161  0
         ok = ok && layerTracker.leaveLayer(timer);
 162  0
         childTracker.end();
 163  
         
 164  0
         ok = ok && decrementDepthCount();
 165  
 
 166  0
         if (!ok) {
 167  0
             log.error(this + " - Mismatch detected in begin/end calls, "
 168  
                     + "dumping stats collected so far");
 169  0
             dumpStatsAndResetTrackers();
 170  
         }
 171  0
     }
 172  
     
 173  
     public CollectionStrategy getCollectionStrategy() {
 174  0
         return collectionStrategy;
 175  
     }
 176  
 
 177  
     public void setCollectionStrategy(CollectionStrategy cs) {
 178  0
         this.collectionStrategy = cs;
 179  0
     }
 180  
 
 181  
     public String getApplicationName() {
 182  0
         return applicationName;
 183  
     }
 184  
 
 185  
     public void setApplicationName(String name) {
 186  0
         this.applicationName = name;
 187  0
     }
 188  
 
 189  
     public String getHostName() {
 190  0
         return instanceId;
 191  
     }
 192  
 
 193  
     public void setHostName(String host) {
 194  0
         this.instanceId = host;
 195  0
     }
 196  
 
 197  
     public MonitorConfig getConfiguration() {
 198  0
         return configuration;
 199  
     }
 200  
 
 201  
     public void setConfiguration(MonitorConfig configuration) {
 202  0
         this.configuration = configuration;
 203  0
     }
 204  
 
 205  
     public String toString() {
 206  0
         return "StatisticsCollector[" + getApplicationName() + " on " + getHostName()
 207  
                 + ", thread = " + Thread.currentThread() + "]";
 208  
     }
 209  
 
 210  
     void setExclusiveTime(ExecutionTimer timer) {
 211  0
         long inclusiveTime = timer.getInclusiveTime();
 212  0
         long exclusiveTime = inclusiveTime;
 213  0
         if (inclusiveTime > pruneBelowTime) {
 214  0
             childTracker.recordChildExecutionTime(inclusiveTime);
 215  0
             exclusiveTime = inclusiveTime - childTracker.getChildExecutionTime();
 216  0
             numOfExecutionsTracked++;
 217  
         } else {
 218  0
             numOfExecutionsIgnored++;
 219  
         }
 220  0
         timer.setExclusiveTime(exclusiveTime);
 221  0
     }
 222  
 
 223  
     void incrementDepthCount() {
 224  0
         if (depth == 0) {
 225  
             // This is to ensure that the value of pruneBelowTime and callTracing is 
 226  
             // not stale. It is done once when the depth is 0 which means that a new
 227  
             // request has just started.
 228  0
             pruneBelowTime = getConfiguration().getPruneThreshold();
 229  0
             callTracing = getConfiguration().isCallTracingEnabled();
 230  0
             treeBuilder.setPruneBelowTime(pruneBelowTime);
 231  0
             layerTracker.setPruneBelowTime(pruneBelowTime);
 232  0
             startTime = System.currentTimeMillis();
 233  
         }
 234  0
         depth++;
 235  0
     }
 236  
 
 237  
     boolean decrementDepthCount() {
 238  0
         depth--;
 239  
 
 240  0
         if (depth < 0) {
 241  0
             log.error("Depth count should have been positive, it is now " + depth);
 242  0
             return false;
 243  
         }
 244  
 
 245  0
         if (depth == 0) {
 246  0
             endTime = System.currentTimeMillis();
 247  0
             if (log.isDebugEnabled()) {
 248  0
                 log.debug(this + " - Reached end of an operation; collecting stats "
 249  
                         + "and resetting trackers");
 250  
             }            
 251  0
             collectStatsAndResetTrackers();            
 252  
         }
 253  0
         return true;
 254  
     }
 255  
 
 256  
     long getPruneBelowTime() {
 257  0
         return pruneBelowTime;
 258  
     }
 259  
 
 260  
     boolean isCallTracingEnabled() {
 261  0
         return callTracing;
 262  
     }
 263  
 
 264  
     void collectStatsAndResetTrackers() {      
 265  0
         childTracker.reset();
 266  0
         Map executionTimings = executionTracker.reset();
 267  0
         Map layerTimings = layerTracker.reset(false);
 268  0
         Tree requestTree = null;
 269  0
         if (isCallTracingEnabled()) {
 270  0
             requestTree = treeBuilder.reset();
 271  
         }
 272  
 
 273  0
         OperationStatistics stats = createOperationStats(executionTimings, layerTimings,
 274  
                 requestTree);
 275  0
         getCollectionStrategy().collect(stats);
 276  0
         logAgentHealth();
 277  0
         startTime = endTime = -1;
 278  0
         numOfExecutionsTracked = numOfExecutionsIgnored = 0;
 279  0
     }
 280  
 
 281  
     OperationStatistics createOperationStats(Map executionTimings, Map layerTimings,
 282  
             Tree requestTree) {
 283  0
         OperationStatistics operationStats = 
 284  
                 new OperationStatistics(getApplicationName(), getHostName());
 285  0
         operationStats.setExecutionTimes(executionTimings);
 286  0
         operationStats.setLayerTimes(layerTimings);
 287  0
         operationStats.setOperationTree(requestTree);
 288  0
         operationStats.setApplicationName(applicationName);
 289  0
         operationStats.setInstanceId(instanceId);
 290  0
         operationStats.setStartTime(startTime);
 291  0
         operationStats.setEndTime(endTime);
 292  0
         operationStats.setNumOfExecutions(numOfExecutionsTracked, numOfExecutionsIgnored);
 293  0
         return operationStats;
 294  
     }
 295  
     
 296  
     void logAgentHealth() {
 297  0
         if (healthLog.isDebugEnabled()) {
 298  0
             Date startDate = new Date(startTime);
 299  0
             Date endDate = new Date(endTime);
 300  0
             healthLog.debug("Agent collected stats for operation that started at " + startDate
 301  
                     + " and ended at " + endDate + ". Tracked " + numOfExecutionsTracked 
 302  
                     + " and ignored " + numOfExecutionsIgnored);
 303  
         }
 304  0
     }
 305  
 
 306  
     void dumpStatsAndResetTrackers() {
 307  0
         layerTracker.reset(true);
 308  0
         childTracker.reset();
 309  0
         treeBuilder.reset();
 310  0
         executionTracker.reset();
 311  0
     }
 312  
 }

This report is generated by jcoverage, Maven and Maven JCoverage Plugin.