001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */
017: package org.apache.jmeter.monitor.util;
018:
019: import org.apache.jmeter.monitor.model.Connector;
020: import org.apache.jmeter.monitor.model.Status;
021:
022: /**
023: *
024: * Description:
025: * <p>
026: * Stats is responsible for calculating the load and health of a given server.
027: * It uses tomcat's status servlet results. A schema was generated for the XML
028: * output and JAXB was used to generate classes.
029: * <p>
030: * The equations are:
031: * <p>
032: * memory weight = (int)(50 * (free/max))<br>
033: * thread weight = (int)(50 * (current/max))
034: * <p>
035: * The load factors are stored in the properties files. Simply change the values
036: * in the properties to change how load is calculated. The defaults values are
037: * memory (50) and threads (50). The sum of the factors must equal 100.
038: */
039: public class Stats {
040:
041: public static final int DEAD = 0;
042:
043: public static final int ACTIVE = 2;
044:
045: public static final int WARNING = 1;
046:
047: public static final int HEALTHY = 3;
048:
049: public static final int DEFAULT_MEMORY_FACTOR = 50;
050:
051: public static final int DEFAULT_THREAD_FACTOR = 50;
052:
053: public static final double HEALTHY_PER = 0.00;
054:
055: public static final double ACTIVE_PER = 0.25;
056:
057: public static final double WARNING_PER = 0.67;
058:
059: /**
060: * The method is responsible for taking a status object and calculating an
061: * int value from 1 to 100. We use a combination of free memory and free
062: * threads. The current factor is 50/50.
063: * <p>
064: *
065: * @param stat
066: * @return calculated load value
067: */
068: public static int calculateLoad(Status stat) {
069: if (stat != null) {
070: // equation for calculating the weight
071: // w = (int)(33 * (used/max))
072: long totMem = stat.getJvm().getMemory().getTotal();
073: long freeMem = stat.getJvm().getMemory().getFree();
074: long usedMem = totMem - freeMem;
075: double memdiv = (double) usedMem / (double) totMem;
076: double memWeight = DEFAULT_MEMORY_FACTOR * memdiv;
077:
078: // changed the logic for BEA Weblogic in the case a
079: // user uses Tomcat's status servlet without any
080: // modifications. Weblogic will return nothing for
081: // the connector, therefore we need to check the size
082: // of the list. Peter 12.22.04
083: double threadWeight = 0;
084: if (stat.getConnector().size() > 0) {
085: Connector cntr = (Connector) stat.getConnector().get(0);
086: int maxThread = cntr.getThreadInfo().getMaxThreads();
087: int curThread = cntr.getThreadInfo()
088: .getCurrentThreadsBusy();
089: double thdiv = (double) curThread / (double) maxThread;
090: threadWeight = DEFAULT_THREAD_FACTOR * thdiv;
091: }
092: return (int) (memWeight + threadWeight);
093: } else {
094: return 0;
095: }
096: }
097:
098: /**
099: * Method should calculate if the server is: dead, active, warning or
100: * healthy. We do this by looking at the current busy threads.
101: * <ol>
102: * <li> free > spare is healthy
103: * <li> free < spare is active
104: * <li> busy threads > 75% is warning
105: * <li> none of the above is dead
106: * </ol>
107: *
108: * @param stat
109: * @return integer representing the status
110: */
111: public static int calculateStatus(Status stat) {
112: if (stat != null && stat.getConnector().size() > 0) {
113: Connector cntr = (Connector) stat.getConnector().get(0);
114: int max = cntr.getThreadInfo().getMaxThreads();
115: int current = cntr.getThreadInfo().getCurrentThreadsBusy();
116: // int spare = cntr.getThreadInfo().getMaxSpareThreads();
117: double per = (double) current / (double) max;
118: if (per > WARNING_PER) {
119: return WARNING;
120: } else if (per >= ACTIVE_PER && per <= WARNING_PER) {
121: return ACTIVE;
122: } else if (per < ACTIVE_PER && per > HEALTHY_PER) {
123: return HEALTHY;
124: } else {
125: return DEAD;
126: }
127: } else {
128: return DEAD;
129: }
130: }
131:
132: /**
133: * Method will calculate the memory load: used / max = load. The load value
134: * is an integer between 1 and 100. It is the percent memory used. Changed
135: * this to be more like other system monitors. Peter Lin 2-11-05
136: *
137: * @param stat
138: * @return memory load
139: */
140: public static int calculateMemoryLoad(Status stat) {
141: double load = 0;
142: if (stat != null) {
143: double total = stat.getJvm().getMemory().getTotal();
144: double free = stat.getJvm().getMemory().getFree();
145: double used = total - free;
146: load = (used / total);
147: }
148: return (int) (load * 100);
149: }
150:
151: /**
152: * Method will calculate the thread load: busy / max = load. The value is an
153: * integer between 1 and 100. It is the percent busy.
154: *
155: * @param stat
156: * @return thread load
157: */
158: public static int calculateThreadLoad(Status stat) {
159: int load = 0;
160: if (stat != null && stat.getConnector().size() > 0) {
161: Connector cntr = (Connector) stat.getConnector().get(0);
162: double max = cntr.getThreadInfo().getMaxThreads();
163: double current = cntr.getThreadInfo()
164: .getCurrentThreadsBusy();
165: load = (int) ((current / max) * 100);
166: }
167: return load;
168: }
169:
170: }
|