/*
* Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package javax.management.monitor;
import static com.sun.jmx.defaults.JmxProperties.MONITOR_LOGGER;
import java.util.logging.Level;
import javax.management.ObjectName;
import javax.management.MBeanNotificationInfo;
import static javax.management.monitor.Monitor.NumericalType.*;
import static javax.management.monitor.MonitorNotification.*;
Defines a monitor MBean designed to observe the values of a counter
attribute.
A counter monitor sends a threshold
notification
when the value of the counter reaches or exceeds a threshold known as the comparison level. The notify flag must be set to true
.
In addition, an offset mechanism enables particular counting
intervals to be detected. If the offset value is not zero,
whenever the threshold is triggered by the counter value reaching a
comparison level, that comparison level is incremented by the
offset value. This is regarded as taking place instantaneously,
that is, before the count is incremented. Thus, for each level,
the threshold triggers an event notification every time the count
increases by an interval equal to the offset value.
If the counter can wrap around its maximum value, the modulus
needs to be specified. The modulus is the value at which the
counter is reset to zero.
If the counter difference mode is used, the value of the
derived gauge is calculated as the difference between the observed
counter values for two successive observations. If this difference
is negative, the value of the derived gauge is incremented by the
value of the modulus. The derived gauge value (V[t]) is calculated
using the following method:
- if (counter[t] - counter[t-GP]) is positive then
V[t] = counter[t] - counter[t-GP]
- if (counter[t] - counter[t-GP]) is negative then
V[t] = counter[t] - counter[t-GP] + MODULUS
This implementation of the counter monitor requires the observed
attribute to be of the type integer (Byte
,
Integer
, Short
, Long
).
Since: 1.5
/**
* Defines a monitor MBean designed to observe the values of a counter
* attribute.
*
* <P> A counter monitor sends a {@link
* MonitorNotification#THRESHOLD_VALUE_EXCEEDED threshold
* notification} when the value of the counter reaches or exceeds a
* threshold known as the comparison level. The notify flag must be
* set to <CODE>true</CODE>.
*
* <P> In addition, an offset mechanism enables particular counting
* intervals to be detected. If the offset value is not zero,
* whenever the threshold is triggered by the counter value reaching a
* comparison level, that comparison level is incremented by the
* offset value. This is regarded as taking place instantaneously,
* that is, before the count is incremented. Thus, for each level,
* the threshold triggers an event notification every time the count
* increases by an interval equal to the offset value.
*
* <P> If the counter can wrap around its maximum value, the modulus
* needs to be specified. The modulus is the value at which the
* counter is reset to zero.
*
* <P> If the counter difference mode is used, the value of the
* derived gauge is calculated as the difference between the observed
* counter values for two successive observations. If this difference
* is negative, the value of the derived gauge is incremented by the
* value of the modulus. The derived gauge value (V[t]) is calculated
* using the following method:
*
* <UL>
* <LI>if (counter[t] - counter[t-GP]) is positive then
* V[t] = counter[t] - counter[t-GP]
* <LI>if (counter[t] - counter[t-GP]) is negative then
* V[t] = counter[t] - counter[t-GP] + MODULUS
* </UL>
*
* This implementation of the counter monitor requires the observed
* attribute to be of the type integer (<CODE>Byte</CODE>,
* <CODE>Integer</CODE>, <CODE>Short</CODE>, <CODE>Long</CODE>).
*
*
* @since 1.5
*/
public class CounterMonitor extends Monitor implements CounterMonitorMBean {
/*
* ------------------------------------------
* PACKAGE CLASSES
* ------------------------------------------
*/
static class CounterMonitorObservedObject extends ObservedObject {
public CounterMonitorObservedObject(ObjectName observedObject) {
super(observedObject);
}
public final synchronized Number getThreshold() {
return threshold;
}
public final synchronized void setThreshold(Number threshold) {
this.threshold = threshold;
}
public final synchronized Number getPreviousScanCounter() {
return previousScanCounter;
}
public final synchronized void setPreviousScanCounter(
Number previousScanCounter) {
this.previousScanCounter = previousScanCounter;
}
public final synchronized boolean getModulusExceeded() {
return modulusExceeded;
}
public final synchronized void setModulusExceeded(
boolean modulusExceeded) {
this.modulusExceeded = modulusExceeded;
}
public final synchronized Number getDerivedGaugeExceeded() {
return derivedGaugeExceeded;
}
public final synchronized void setDerivedGaugeExceeded(
Number derivedGaugeExceeded) {
this.derivedGaugeExceeded = derivedGaugeExceeded;
}
public final synchronized boolean getDerivedGaugeValid() {
return derivedGaugeValid;
}
public final synchronized void setDerivedGaugeValid(
boolean derivedGaugeValid) {
this.derivedGaugeValid = derivedGaugeValid;
}
public final synchronized boolean getEventAlreadyNotified() {
return eventAlreadyNotified;
}
public final synchronized void setEventAlreadyNotified(
boolean eventAlreadyNotified) {
this.eventAlreadyNotified = eventAlreadyNotified;
}
public final synchronized NumericalType getType() {
return type;
}
public final synchronized void setType(NumericalType type) {
this.type = type;
}
private Number threshold;
private Number previousScanCounter;
private boolean modulusExceeded;
private Number derivedGaugeExceeded;
private boolean derivedGaugeValid;
private boolean eventAlreadyNotified;
private NumericalType type;
}
/*
* ------------------------------------------
* PRIVATE VARIABLES
* ------------------------------------------
*/
Counter modulus.
The default value is a null Integer object.
/**
* Counter modulus.
* <BR>The default value is a null Integer object.
*/
private Number modulus = INTEGER_ZERO;
Counter offset.
The default value is a null Integer object.
/**
* Counter offset.
* <BR>The default value is a null Integer object.
*/
private Number offset = INTEGER_ZERO;
Flag indicating if the counter monitor notifies when exceeding
the threshold. The default value is set to
false
.
/**
* Flag indicating if the counter monitor notifies when exceeding
* the threshold. The default value is set to
* <CODE>false</CODE>.
*/
private boolean notify = false;
Flag indicating if the counter difference mode is used. If the
counter difference mode is used, the derived gauge is the
difference between two consecutive observed values. Otherwise,
the derived gauge is directly the value of the observed
attribute. The default value is set to false
.
/**
* Flag indicating if the counter difference mode is used. If the
* counter difference mode is used, the derived gauge is the
* difference between two consecutive observed values. Otherwise,
* the derived gauge is directly the value of the observed
* attribute. The default value is set to <CODE>false</CODE>.
*/
private boolean differenceMode = false;
Initial counter threshold. This value is used to initialize
the threshold when a new object is added to the list and reset
the threshold to its initial value each time the counter
resets.
/**
* Initial counter threshold. This value is used to initialize
* the threshold when a new object is added to the list and reset
* the threshold to its initial value each time the counter
* resets.
*/
private Number initThreshold = INTEGER_ZERO;
private static final String[] types = {
RUNTIME_ERROR,
OBSERVED_OBJECT_ERROR,
OBSERVED_ATTRIBUTE_ERROR,
OBSERVED_ATTRIBUTE_TYPE_ERROR,
THRESHOLD_ERROR,
THRESHOLD_VALUE_EXCEEDED
};
private static final MBeanNotificationInfo[] notifsInfo = {
new MBeanNotificationInfo(
types,
"javax.management.monitor.MonitorNotification",
"Notifications sent by the CounterMonitor MBean")
};
/*
* ------------------------------------------
* CONSTRUCTORS
* ------------------------------------------
*/
Default constructor.
/**
* Default constructor.
*/
public CounterMonitor() {
}
/*
* ------------------------------------------
* PUBLIC METHODS
* ------------------------------------------
*/
Starts the counter monitor.
/**
* Starts the counter monitor.
*/
public synchronized void start() {
if (isActive()) {
MONITOR_LOGGER.logp(Level.FINER, CounterMonitor.class.getName(),
"start", "the monitor is already active");
return;
}
// Reset values.
//
for (ObservedObject o : observedObjects) {
final CounterMonitorObservedObject cmo =
(CounterMonitorObservedObject) o;
cmo.setThreshold(initThreshold);
cmo.setModulusExceeded(false);
cmo.setEventAlreadyNotified(false);
cmo.setPreviousScanCounter(null);
}
doStart();
}
Stops the counter monitor.
/**
* Stops the counter monitor.
*/
public synchronized void stop() {
doStop();
}
// GETTERS AND SETTERS
//--------------------
Gets the derived gauge of the specified object, if this object is
contained in the set of observed MBeans, or null
otherwise.
Params: - object – the name of the object whose derived gauge is to
be returned.
Returns: The derived gauge of the specified object.
/**
* Gets the derived gauge of the specified object, if this object is
* contained in the set of observed MBeans, or <code>null</code> otherwise.
*
* @param object the name of the object whose derived gauge is to
* be returned.
*
* @return The derived gauge of the specified object.
*
*/
@Override
public synchronized Number getDerivedGauge(ObjectName object) {
return (Number) super.getDerivedGauge(object);
}
Gets the derived gauge timestamp of the specified object, if
this object is contained in the set of observed MBeans, or
0
otherwise.
Params: - object – the name of the object whose derived gauge
timestamp is to be returned.
Returns: The derived gauge timestamp of the specified object.
/**
* Gets the derived gauge timestamp of the specified object, if
* this object is contained in the set of observed MBeans, or
* <code>0</code> otherwise.
*
* @param object the name of the object whose derived gauge
* timestamp is to be returned.
*
* @return The derived gauge timestamp of the specified object.
*
*/
@Override
public synchronized long getDerivedGaugeTimeStamp(ObjectName object) {
return super.getDerivedGaugeTimeStamp(object);
}
Gets the current threshold value of the specified object, if
this object is contained in the set of observed MBeans, or
null
otherwise.
Params: - object – the name of the object whose threshold is to be
returned.
Returns: The threshold value of the specified object.
/**
* Gets the current threshold value of the specified object, if
* this object is contained in the set of observed MBeans, or
* <code>null</code> otherwise.
*
* @param object the name of the object whose threshold is to be
* returned.
*
* @return The threshold value of the specified object.
*
*/
public synchronized Number getThreshold(ObjectName object) {
final CounterMonitorObservedObject o =
(CounterMonitorObservedObject) getObservedObject(object);
if (o == null)
return null;
// If the counter that is monitored rolls over when it reaches a
// maximum value, then the modulus value needs to be set to that
// maximum value. The threshold will then also roll over whenever
// it strictly exceeds the modulus value. When the threshold rolls
// over, it is reset to the value that was specified through the
// latest call to the monitor's setInitThreshold method, before
// any offsets were applied.
//
if (offset.longValue() > 0L &&
modulus.longValue() > 0L &&
o.getThreshold().longValue() > modulus.longValue()) {
return initThreshold;
} else {
return o.getThreshold();
}
}
Gets the initial threshold value common to all observed objects.
See Also: Returns: The initial threshold.
/**
* Gets the initial threshold value common to all observed objects.
*
* @return The initial threshold.
*
* @see #setInitThreshold
*
*/
public synchronized Number getInitThreshold() {
return initThreshold;
}
Sets the initial threshold value common to all observed objects.
The current threshold of every object in the set of
observed MBeans is updated consequently.
Params: - value – The initial threshold value.
Throws: - IllegalArgumentException – The specified
threshold is null or the threshold value is less than zero.
See Also:
/**
* Sets the initial threshold value common to all observed objects.
*
* <BR>The current threshold of every object in the set of
* observed MBeans is updated consequently.
*
* @param value The initial threshold value.
*
* @exception IllegalArgumentException The specified
* threshold is null or the threshold value is less than zero.
*
* @see #getInitThreshold
*
*/
public synchronized void setInitThreshold(Number value)
throws IllegalArgumentException {
if (value == null) {
throw new IllegalArgumentException("Null threshold");
}
if (value.longValue() < 0L) {
throw new IllegalArgumentException("Negative threshold");
}
if (initThreshold.equals(value))
return;
initThreshold = value;
// Reset values.
//
int index = 0;
for (ObservedObject o : observedObjects) {
resetAlreadyNotified(o, index++, THRESHOLD_ERROR_NOTIFIED);
final CounterMonitorObservedObject cmo =
(CounterMonitorObservedObject) o;
cmo.setThreshold(value);
cmo.setModulusExceeded(false);
cmo.setEventAlreadyNotified(false);
}
}
Returns the derived gauge of the first object in the set of
observed MBeans.
Returns: The derived gauge. Deprecated: As of JMX 1.2, replaced by getDerivedGauge(ObjectName)
/**
* Returns the derived gauge of the first object in the set of
* observed MBeans.
*
* @return The derived gauge.
*
* @deprecated As of JMX 1.2, replaced by
* {@link #getDerivedGauge(ObjectName)}
*/
@Deprecated
public synchronized Number getDerivedGauge() {
if (observedObjects.isEmpty()) {
return null;
} else {
return (Number) observedObjects.get(0).getDerivedGauge();
}
}
Gets the derived gauge timestamp of the first object in the set
of observed MBeans.
Returns: The derived gauge timestamp. Deprecated: As of JMX 1.2, replaced by getDerivedGaugeTimeStamp(ObjectName)
/**
* Gets the derived gauge timestamp of the first object in the set
* of observed MBeans.
*
* @return The derived gauge timestamp.
*
* @deprecated As of JMX 1.2, replaced by
* {@link #getDerivedGaugeTimeStamp(ObjectName)}
*/
@Deprecated
public synchronized long getDerivedGaugeTimeStamp() {
if (observedObjects.isEmpty()) {
return 0;
} else {
return observedObjects.get(0).getDerivedGaugeTimeStamp();
}
}
Gets the threshold value of the first object in the set of
observed MBeans.
See Also: Returns: The threshold value. Deprecated: As of JMX 1.2, replaced by getThreshold(ObjectName)
/**
* Gets the threshold value of the first object in the set of
* observed MBeans.
*
* @return The threshold value.
*
* @see #setThreshold
*
* @deprecated As of JMX 1.2, replaced by {@link #getThreshold(ObjectName)}
*/
@Deprecated
public synchronized Number getThreshold() {
return getThreshold(getObservedObject());
}
Sets the initial threshold value.
Params: - value – The initial threshold value.
Throws: - IllegalArgumentException – The specified threshold is
null or the threshold value is less than zero.
See Also: Deprecated: As of JMX 1.2, replaced by setInitThreshold
/**
* Sets the initial threshold value.
*
* @param value The initial threshold value.
*
* @exception IllegalArgumentException The specified threshold is
* null or the threshold value is less than zero.
*
* @see #getThreshold()
*
* @deprecated As of JMX 1.2, replaced by {@link #setInitThreshold}
*/
@Deprecated
public synchronized void setThreshold(Number value)
throws IllegalArgumentException {
setInitThreshold(value);
}
Gets the offset value common to all observed MBeans.
See Also: Returns: The offset value.
/**
* Gets the offset value common to all observed MBeans.
*
* @return The offset value.
*
* @see #setOffset
*/
public synchronized Number getOffset() {
return offset;
}
Sets the offset value common to all observed MBeans.
Params: - value – The offset value.
Throws: - IllegalArgumentException – The specified
offset is null or the offset value is less than zero.
See Also:
/**
* Sets the offset value common to all observed MBeans.
*
* @param value The offset value.
*
* @exception IllegalArgumentException The specified
* offset is null or the offset value is less than zero.
*
* @see #getOffset
*/
public synchronized void setOffset(Number value)
throws IllegalArgumentException {
if (value == null) {
throw new IllegalArgumentException("Null offset");
}
if (value.longValue() < 0L) {
throw new IllegalArgumentException("Negative offset");
}
if (offset.equals(value))
return;
offset = value;
int index = 0;
for (ObservedObject o : observedObjects) {
resetAlreadyNotified(o, index++, THRESHOLD_ERROR_NOTIFIED);
}
}
Gets the modulus value common to all observed MBeans.
See Also: - setModulus
Returns: The modulus value.
/**
* Gets the modulus value common to all observed MBeans.
*
* @see #setModulus
*
* @return The modulus value.
*/
public synchronized Number getModulus() {
return modulus;
}
Sets the modulus value common to all observed MBeans.
Params: - value – The modulus value.
Throws: - IllegalArgumentException – The specified
modulus is null or the modulus value is less than zero.
See Also:
/**
* Sets the modulus value common to all observed MBeans.
*
* @param value The modulus value.
*
* @exception IllegalArgumentException The specified
* modulus is null or the modulus value is less than zero.
*
* @see #getModulus
*/
public synchronized void setModulus(Number value)
throws IllegalArgumentException {
if (value == null) {
throw new IllegalArgumentException("Null modulus");
}
if (value.longValue() < 0L) {
throw new IllegalArgumentException("Negative modulus");
}
if (modulus.equals(value))
return;
modulus = value;
// Reset values.
//
int index = 0;
for (ObservedObject o : observedObjects) {
resetAlreadyNotified(o, index++, THRESHOLD_ERROR_NOTIFIED);
final CounterMonitorObservedObject cmo =
(CounterMonitorObservedObject) o;
cmo.setModulusExceeded(false);
}
}
Gets the notification's on/off switch value common to all
observed MBeans.
See Also: Returns: true
if the counter monitor notifies when
exceeding the threshold, false
otherwise.
/**
* Gets the notification's on/off switch value common to all
* observed MBeans.
*
* @return <CODE>true</CODE> if the counter monitor notifies when
* exceeding the threshold, <CODE>false</CODE> otherwise.
*
* @see #setNotify
*/
public synchronized boolean getNotify() {
return notify;
}
Sets the notification's on/off switch value common to all
observed MBeans.
Params: - value – The notification's on/off switch value.
See Also:
/**
* Sets the notification's on/off switch value common to all
* observed MBeans.
*
* @param value The notification's on/off switch value.
*
* @see #getNotify
*/
public synchronized void setNotify(boolean value) {
if (notify == value)
return;
notify = value;
}
Gets the difference mode flag value common to all observed MBeans.
See Also: Returns: true
if the difference mode is used,
false
otherwise.
/**
* Gets the difference mode flag value common to all observed MBeans.
*
* @return <CODE>true</CODE> if the difference mode is used,
* <CODE>false</CODE> otherwise.
*
* @see #setDifferenceMode
*/
public synchronized boolean getDifferenceMode() {
return differenceMode;
}
Sets the difference mode flag value common to all observed MBeans.
Params: - value – The difference mode flag value.
See Also:
/**
* Sets the difference mode flag value common to all observed MBeans.
*
* @param value The difference mode flag value.
*
* @see #getDifferenceMode
*/
public synchronized void setDifferenceMode(boolean value) {
if (differenceMode == value)
return;
differenceMode = value;
// Reset values.
//
for (ObservedObject o : observedObjects) {
final CounterMonitorObservedObject cmo =
(CounterMonitorObservedObject) o;
cmo.setThreshold(initThreshold);
cmo.setModulusExceeded(false);
cmo.setEventAlreadyNotified(false);
cmo.setPreviousScanCounter(null);
}
}
Returns a NotificationInfo
object containing the
name of the Java class of the notification and the notification
types sent by the counter monitor.
/**
* Returns a <CODE>NotificationInfo</CODE> object containing the
* name of the Java class of the notification and the notification
* types sent by the counter monitor.
*/
@Override
public MBeanNotificationInfo[] getNotificationInfo() {
return notifsInfo.clone();
}
/*
* ------------------------------------------
* PRIVATE METHODS
* ------------------------------------------
*/
Updates the derived gauge attribute of the observed object.
Params: - scanCounter – The value of the observed attribute.
- o – The observed object.
Returns: true
if the derived gauge value is valid,
false
otherwise. The derived gauge value is
invalid when the differenceMode flag is set to
true
and it is the first notification (so we
haven't 2 consecutive values to update the derived gauge).
/**
* Updates the derived gauge attribute of the observed object.
*
* @param scanCounter The value of the observed attribute.
* @param o The observed object.
* @return <CODE>true</CODE> if the derived gauge value is valid,
* <CODE>false</CODE> otherwise. The derived gauge value is
* invalid when the differenceMode flag is set to
* <CODE>true</CODE> and it is the first notification (so we
* haven't 2 consecutive values to update the derived gauge).
*/
private synchronized boolean updateDerivedGauge(
Object scanCounter, CounterMonitorObservedObject o) {
boolean is_derived_gauge_valid;
// The counter difference mode is used.
//
if (differenceMode) {
// The previous scan counter has been initialized.
//
if (o.getPreviousScanCounter() != null) {
setDerivedGaugeWithDifference((Number)scanCounter, null, o);
// If derived gauge is negative it means that the
// counter has wrapped around and the value of the
// threshold needs to be reset to its initial value.
//
if (((Number)o.getDerivedGauge()).longValue() < 0L) {
if (modulus.longValue() > 0L) {
setDerivedGaugeWithDifference((Number)scanCounter,
modulus, o);
}
o.setThreshold(initThreshold);
o.setEventAlreadyNotified(false);
}
is_derived_gauge_valid = true;
}
// The previous scan counter has not been initialized.
// We cannot update the derived gauge...
//
else {
is_derived_gauge_valid = false;
}
o.setPreviousScanCounter((Number)scanCounter);
}
// The counter difference mode is not used.
//
else {
o.setDerivedGauge((Number)scanCounter);
is_derived_gauge_valid = true;
}
return is_derived_gauge_valid;
}
Updates the notification attribute of the observed object
and notifies the listeners only once if the notify flag
is set to true
.
Params: - o – The observed object.
/**
* Updates the notification attribute of the observed object
* and notifies the listeners only once if the notify flag
* is set to <CODE>true</CODE>.
* @param o The observed object.
*/
private synchronized MonitorNotification updateNotifications(
CounterMonitorObservedObject o) {
MonitorNotification n = null;
// Send notification if notify is true.
//
if (!o.getEventAlreadyNotified()) {
if (((Number)o.getDerivedGauge()).longValue() >=
o.getThreshold().longValue()) {
if (notify) {
n = new MonitorNotification(THRESHOLD_VALUE_EXCEEDED,
this,
0,
0,
"",
null,
null,
null,
o.getThreshold());
}
if (!differenceMode) {
o.setEventAlreadyNotified(true);
}
}
} else {
if (MONITOR_LOGGER.isLoggable(Level.FINER)) {
final StringBuilder strb = new StringBuilder()
.append("The notification:")
.append("\n\tNotification observed object = ")
.append(o.getObservedObject())
.append("\n\tNotification observed attribute = ")
.append(getObservedAttribute())
.append("\n\tNotification threshold level = ")
.append(o.getThreshold())
.append("\n\tNotification derived gauge = ")
.append(o.getDerivedGauge())
.append("\nhas already been sent");
MONITOR_LOGGER.logp(Level.FINER, CounterMonitor.class.getName(),
"updateNotifications", strb.toString());
}
}
return n;
}
Updates the threshold attribute of the observed object.
Params: - o – The observed object.
/**
* Updates the threshold attribute of the observed object.
* @param o The observed object.
*/
private synchronized void updateThreshold(CounterMonitorObservedObject o) {
// Calculate the new threshold value if the threshold has been
// exceeded and if the offset value is greater than zero.
//
if (((Number)o.getDerivedGauge()).longValue() >=
o.getThreshold().longValue()) {
if (offset.longValue() > 0L) {
// Increment the threshold until its value is greater
// than the one for the current derived gauge.
//
long threshold_value = o.getThreshold().longValue();
while (((Number)o.getDerivedGauge()).longValue() >=
threshold_value) {
threshold_value += offset.longValue();
}
// Set threshold attribute.
//
switch (o.getType()) {
case INTEGER:
o.setThreshold(Integer.valueOf((int)threshold_value));
break;
case BYTE:
o.setThreshold(Byte.valueOf((byte)threshold_value));
break;
case SHORT:
o.setThreshold(Short.valueOf((short)threshold_value));
break;
case LONG:
o.setThreshold(Long.valueOf(threshold_value));
break;
default:
// Should never occur...
MONITOR_LOGGER.logp(Level.FINEST,
CounterMonitor.class.getName(),
"updateThreshold",
"the threshold type is invalid");
break;
}
// If the counter can wrap around when it reaches
// its maximum and we are not dealing with counter
// differences then we need to reset the threshold
// to its initial value too.
//
if (!differenceMode) {
if (modulus.longValue() > 0L) {
if (o.getThreshold().longValue() >
modulus.longValue()) {
o.setModulusExceeded(true);
o.setDerivedGaugeExceeded(
(Number) o.getDerivedGauge());
}
}
}
// Threshold value has been modified so we can notify again.
//
o.setEventAlreadyNotified(false);
} else {
o.setModulusExceeded(true);
o.setDerivedGaugeExceeded((Number) o.getDerivedGauge());
}
}
}
Sets the derived gauge of the specified observed object when the
differenceMode flag is set to true
. Integer types
only are allowed.
Params: - scanCounter – The value of the observed attribute.
- mod – The counter modulus value.
- o – The observed object.
/**
* Sets the derived gauge of the specified observed object when the
* differenceMode flag is set to <CODE>true</CODE>. Integer types
* only are allowed.
*
* @param scanCounter The value of the observed attribute.
* @param mod The counter modulus value.
* @param o The observed object.
*/
private synchronized void setDerivedGaugeWithDifference(
Number scanCounter, Number mod, CounterMonitorObservedObject o) {
/* We do the arithmetic using longs here even though the
result may end up in a smaller type. Since
l == (byte)l (mod 256) for any long l,
(byte) ((byte)l1 + (byte)l2) == (byte) (l1 + l2),
and likewise for subtraction. So it's the same as if
we had done the arithmetic in the smaller type.*/
long derived =
scanCounter.longValue() - o.getPreviousScanCounter().longValue();
if (mod != null)
derived += modulus.longValue();
switch (o.getType()) {
case INTEGER: o.setDerivedGauge(Integer.valueOf((int) derived)); break;
case BYTE: o.setDerivedGauge(Byte.valueOf((byte) derived)); break;
case SHORT: o.setDerivedGauge(Short.valueOf((short) derived)); break;
case LONG: o.setDerivedGauge(Long.valueOf(derived)); break;
default:
// Should never occur...
MONITOR_LOGGER.logp(Level.FINEST, CounterMonitor.class.getName(),
"setDerivedGaugeWithDifference",
"the threshold type is invalid");
break;
}
}
/*
* ------------------------------------------
* PACKAGE METHODS
* ------------------------------------------
*/
Factory method for ObservedObject creation.
Since: 1.6
/**
* Factory method for ObservedObject creation.
*
* @since 1.6
*/
@Override
ObservedObject createObservedObject(ObjectName object) {
final CounterMonitorObservedObject cmo =
new CounterMonitorObservedObject(object);
cmo.setThreshold(initThreshold);
cmo.setModulusExceeded(false);
cmo.setEventAlreadyNotified(false);
cmo.setPreviousScanCounter(null);
return cmo;
}
This method globally sets the derived gauge type for the given
"object" and "attribute" after checking that the type of the
supplied observed attribute value is one of the value types
supported by this monitor.
/**
* This method globally sets the derived gauge type for the given
* "object" and "attribute" after checking that the type of the
* supplied observed attribute value is one of the value types
* supported by this monitor.
*/
@Override
synchronized boolean isComparableTypeValid(ObjectName object,
String attribute,
Comparable<?> value) {
final CounterMonitorObservedObject o =
(CounterMonitorObservedObject) getObservedObject(object);
if (o == null)
return false;
// Check that the observed attribute is of type "Integer".
//
if (value instanceof Integer) {
o.setType(INTEGER);
} else if (value instanceof Byte) {
o.setType(BYTE);
} else if (value instanceof Short) {
o.setType(SHORT);
} else if (value instanceof Long) {
o.setType(LONG);
} else {
return false;
}
return true;
}
@Override
synchronized Comparable<?> getDerivedGaugeFromComparable(
ObjectName object,
String attribute,
Comparable<?> value) {
final CounterMonitorObservedObject o =
(CounterMonitorObservedObject) getObservedObject(object);
if (o == null)
return null;
// Check if counter has wrapped around.
//
if (o.getModulusExceeded()) {
if (((Number)o.getDerivedGauge()).longValue() <
o.getDerivedGaugeExceeded().longValue()) {
o.setThreshold(initThreshold);
o.setModulusExceeded(false);
o.setEventAlreadyNotified(false);
}
}
// Update the derived gauge attributes and check the
// validity of the new value. The derived gauge value
// is invalid when the differenceMode flag is set to
// true and it is the first notification, i.e. we
// haven't got 2 consecutive values to update the
// derived gauge.
//
o.setDerivedGaugeValid(updateDerivedGauge(value, o));
return (Comparable<?>) o.getDerivedGauge();
}
@Override
synchronized void onErrorNotification(MonitorNotification notification) {
final CounterMonitorObservedObject o = (CounterMonitorObservedObject)
getObservedObject(notification.getObservedObject());
if (o == null)
return;
// Reset values.
//
o.setModulusExceeded(false);
o.setEventAlreadyNotified(false);
o.setPreviousScanCounter(null);
}
@Override
synchronized MonitorNotification buildAlarmNotification(
ObjectName object,
String attribute,
Comparable<?> value) {
final CounterMonitorObservedObject o =
(CounterMonitorObservedObject) getObservedObject(object);
if (o == null)
return null;
// Notify the listeners and update the threshold if
// the updated derived gauge value is valid.
//
final MonitorNotification alarm;
if (o.getDerivedGaugeValid()) {
alarm = updateNotifications(o);
updateThreshold(o);
} else {
alarm = null;
}
return alarm;
}
Tests if the threshold, offset and modulus of the specified observed
object are of the same type as the counter. Only integer types are
allowed.
Note:
If the optional offset or modulus have not been initialized, their
default value is an Integer object with a value equal to zero.
Params: - object – The observed object.
- attribute – The observed attribute.
- value – The sample value.
Returns: true
if type is the same,
false
otherwise.
/**
* Tests if the threshold, offset and modulus of the specified observed
* object are of the same type as the counter. Only integer types are
* allowed.
*
* Note:
* If the optional offset or modulus have not been initialized, their
* default value is an Integer object with a value equal to zero.
*
* @param object The observed object.
* @param attribute The observed attribute.
* @param value The sample value.
* @return <CODE>true</CODE> if type is the same,
* <CODE>false</CODE> otherwise.
*/
@Override
synchronized boolean isThresholdTypeValid(ObjectName object,
String attribute,
Comparable<?> value) {
final CounterMonitorObservedObject o =
(CounterMonitorObservedObject) getObservedObject(object);
if (o == null)
return false;
Class<? extends Number> c = classForType(o.getType());
return (c.isInstance(o.getThreshold()) &&
isValidForType(offset, c) &&
isValidForType(modulus, c));
}
}