Coverage Report - net.admin4j.monitor.ConcurrentUsageDetector
 
Classes in this File Line Coverage Branch Coverage Complexity
ConcurrentUsageDetector
94%
37/39
100%
16/16
1.889
 
 1  
 /*
 2  
  * This software is licensed under the Apache License, Version 2.0
 3  
  * (the "License") agreement; you may not use this file except in compliance with
 4  
  * the License.  You may obtain a copy of the License at
 5  
  * 
 6  
  *      http://www.apache.org/licenses/LICENSE-2.0
 7  
  * 
 8  
  * Unless required by applicable law or agreed to in writing, software
 9  
  * distributed under the License is distributed on an "AS IS" BASIS,
 10  
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 11  
  * See the License for the specific language governing permissions and
 12  
  * limitations under the License.
 13  
  */
 14  
 package net.admin4j.monitor;
 15  
 
 16  
 import java.util.Arrays;
 17  
 import java.util.Date;
 18  
 import java.util.HashMap;
 19  
 import java.util.Map;
 20  
 import java.util.concurrent.atomic.AtomicInteger;
 21  
 
 22  
 import net.admin4j.deps.commons.lang3.Validate;
 23  
 import net.admin4j.util.GuiUtils;
 24  
 import net.admin4j.util.HostUtils;
 25  
 import net.admin4j.util.notify.Notifier;
 26  
 import net.admin4j.util.threaddumper.ThreadDumperFactory;
 27  
 
 28  
 /**
 29  
  * Will send out alerts and thread dumps at configurable usage levels.  Notice
 30  
  * will also be sent when usage returns to normal.
 31  
  * @author D. Ashmore
 32  
  * @since 1.0.1
 33  
  */
 34  
 public class ConcurrentUsageDetector extends Detector {
 35  
     
 36  9
     public static final Integer[] DEFAULT_ALERT_LEVELS = new Integer[]{100};
 37  
     public static final long DEFAULT_SLEEP_INTERVAL=30000;
 38  
 
 39  
     private Integer[] alertLevels;
 40  15
     private AtomicInteger currentUsageLevel = new AtomicInteger(0);
 41  15
     private Integer lastAlertLevelOffset = -1;
 42  
     
 43  
     public ConcurrentUsageDetector(Notifier notifier) {
 44  0
         this(notifier, DEFAULT_ALERT_LEVELS);
 45  0
     }
 46  
     
 47  
     public ConcurrentUsageDetector(Notifier notifier, Integer[] alertLevels) {
 48  15
         super(notifier);
 49  
         
 50  
         Validate.notEmpty(alertLevels, "Null or empty alertLevels not allowed");
 51  15
         Arrays.sort(alertLevels);
 52  15
         this.alertLevels = alertLevels;
 53  15
     }
 54  
 
 55  
     public void run() {
 56  99
         Integer currentLevel = currentUsageLevel.get();
 57  
         
 58  369
         for (int i = alertLevels.length - 1; i >= 0; i--) {
 59  270
             if (currentLevel >= alertLevels[i] && lastAlertLevelOffset < i) {
 60  27
                 lastAlertLevelOffset = i;
 61  27
                 this.sendHighUsageNotice(currentLevel, alertLevels[i]);
 62  27
                 i = -1;
 63  
             }
 64  243
             else if (i == 0 && lastAlertLevelOffset >= 0 && currentLevel < alertLevels[0]) {
 65  9
                 lastAlertLevelOffset = -1;
 66  9
                 this.sendNormalUsageNotice(currentLevel);
 67  
             }
 68  
         }
 69  
 
 70  99
     }
 71  
     
 72  
     protected void sendNormalUsageNotice(Integer currentLevel) {
 73  9
         this.sendNotice("Concurrent Usage returned to normal.  Usage=" + currentLevel, "Concurrent Usage Returned to normal", currentLevel);
 74  9
     }
 75  
     
 76  
     protected void sendHighUsageNotice(Integer currentLevel, Integer threshold) {
 77  27
         this.sendNotice("Concurrent Usage exceeded " + threshold + ".  Usage=" + currentLevel, "High Concurrent Usage Detected", currentLevel);
 78  27
     }
 79  
     
 80  
     private void sendNotice(String subjectLine, String title, Integer currentLevel) {
 81  36
         Map<String, Object> variableMap = new HashMap<String, Object>();
 82  36
         variableMap.put("host", HostUtils.getHostName());
 83  36
         variableMap.put("currentDatetime", new Date());
 84  36
         variableMap.put("currentLevel", currentLevel);
 85  36
         variableMap.put("titleArg", title);
 86  36
         variableMap.put("GuiUtils", new GuiUtils());
 87  36
         variableMap.put("threadInfoArray", ThreadDumperFactory.getThreadDumper().dumpAllThreads());
 88  
         
 89  36
         if (this.getNotifier().supportsHtml()) {            
 90  12
             this.sendMessage(HostUtils.getHostName() + ": " + subjectLine, "concurrentUsageNoticeHtml.ftl", variableMap);
 91  
         }
 92  24
         else if (this.getNotifier().supportsSMS()) {
 93  12
             this.getNotifier().notify(HostUtils.getHostName() + 
 94  
                     ": " + subjectLine, "");
 95  
         }
 96  
         else {
 97  12
             this.sendMessage(HostUtils.getHostName()  + ": " + subjectLine, "concurrentUsageNoticeText.ftl", variableMap);
 98  
         }
 99  36
     }
 100  
     
 101  
     public Integer increment() {
 102  33
         return currentUsageLevel.addAndGet(1);
 103  
     }
 104  
     
 105  
     public Integer decrement() {
 106  33
         return currentUsageLevel.addAndGet(-1);
 107  
     }
 108  
     
 109  
     protected Integer getCurrentUsageLevel() {
 110  54
         return currentUsageLevel.get();
 111  
     }
 112  
 
 113  
 }