-3 describes the State Sensor metrics. State Sensors support a default metric
value, as well as optional metrics. The optional
minValue and
maxValue metrics only apply for State Sensors if the State Sensor represents a numeric Java primitive (of type integer, double, or long).."
A Noun name is a simple string, not including a delimiter. For example,
BasicBinomial is a Noun name. A Noun full name consists of the Noun name, preceded by the full name of its parent, and a delimiter. For example
/dmsDemo/BasicBinomial.. following list outlines Sensors.
The ImprovedBinomial servlet expands on the BasicBinomial and illustrates measuring the improved code, as compared with the BasicBinomial. ImprovedBinomial servlet also shows how to add more costly metrics that gather more detailed information.
Refer to the sample code for full details on the examples in this chapter.
To use DMS instrumentation, add DMS calls by performing the following steps:
Section A.2.1, "Including DMS Imports"
Section A.2.2, "Organizing Performance Data"
Section A.2.3, "Defining and Using Metrics for Timing"
Section A.2.4, "Defining and Using Metrics for Counting"
Section A.2.5, "Defining and Using Metrics for Recording Status Information (State Sensors)"
To use DMS you need to add DMS imports. The following example shows the imports that the sample application
BasicBinomial.java requires.
import oracle.dms.instrument.DMSConsole; import oracle.dms.instrument.Event; import oracle.dms.instrument.Noun; import oracle.dms.instrument.PhaseEvent; import oracle.dms.instrument.State; import oracle.dms.instrument.Sensor;-5 shows a code segment from
BasicBinomial.java that uses the
start and
stop methods for the
/dmsDemo/BasicBinomial/computeSeries.time metric. The
long value named
token that is returned from the PhaseEvent
start method must be passed to the corresponding PhaseEvent
stop method. This value is a timestamp representing the start time. Passing this value to the
stop method-5 Using start and stop With PhaseEvent Sensors
long token = 0; // DMS try { token = binComp.start(); // DMS BigInteger bins[] = bin(length); out.println("<H2>Binomial series for " + length + "</H2>"); for (int i = 0; i < length; i++) out.println("<br>" + bins[i]); } finally { binComp.stop(token); // DMS out.close(); }
Example A-5 shows code instrumented such that each time a phase starts, it is stopped (since the
stop method is placed in the finally clause). This prevents runaway Phase Sensors; however, this can result in the time required to throw an exception possibly contributing to phase statistics. To prevent exception handling from impacting a PhaseEvent, use the
abort method, as shown in Example A-6.
Example A-6 shows a code sample where a Phase that is not successfully stopped can be closed. The abort call removes the statistics corresponding to the corresponding start, and these statistics do not contribute to metric calculations.
Example A-6 Using abort with PhaseEvent Sensors
PhaseEvent pe = heavyPhase(param); long token1 = 0; long token2 = 0; boolean stopped = false; try { token1 = binComp.start(); if (pe != null) token2 = pe.start(); BigInteger bins[] = bin(length); out.println("<H2>ImprovedBinomial series for " + length + "</H2>"); for (int i = 0; i < length; i++) out.println("<br>" + bins[i]); if (pe != null) pe.stop(token2); binComp.stop(token1); stopped = true; } finally { if (!stopped) { if (pe != null) pe.abort(token2); binComp.abort(token1); } }
To create metrics that count the occurrences of an event, define and use an Event Sensor: shows the
occurred call for an Event Sensor that increments the
/dmsDemo/BasicBinomial/loops.count metric.
DMS captures status information with State Sensors. State Sensors track the value of Java primitives or the content of a Java Object. The supported types include integer, double, long, and object, as specified in the third argument to the
create method. When a Java primitive State Sensor is updated with the wrong type, DMS attempts to convert the supplied value to the correct type. For object type State Sensors, DMS stores a reference to the object and by default-9 Defining State Sensors
private State binLast; // Value of the last computed element in series. ... binLast = State.create(binRoot, "lastComputed", State.OBJECT, "", "Value of last computed series element");
When you define a State Sensor, use an empty string in the fourth argument to the
create method if no value is associated with the State Sensor, otherwise use a string listing the appropriate values (see Example A-9). State Sensors are created without an initial value. If you need to check whether a State Sensor has been initialized, use the
isInitialized method.
If you want your State Sensor to store the string value of an object, and not store a reference to the object, use the
setCopy method with the value
TRUE. This tells the State Sensor to store the result of calling
toString on an object rather than using a reference to the object for the metric value.
When an application calls a State Sensor's
update method, DMS updates the value of the State Sensor. Example that all the metric names added using DMS instrumentation appear in your display or saved set of metrics.
Do unexpected metrics appear in the display? Verify that you have only added the metrics that you planned to add.
Are the metric values you see within reasonable ranges? Usually, upper and lower bounds for metrics can be established. You then test that the reported values for metrics do not exceed the expected bounds.
For example, a "size of pool" metric should never report a negative value.
Ensure the new metrics are needed. For example, if you add a PhaseEvent that always measures an event of very short duration, consider changing the metric to an Event metric, or remove the metric.
Ensure the new metrics are accurate. For most applications using DMS metrics, accuracy is more important than the performance cost of adding the DMS instrumentation. New DMS metrics should provide reliable and useful information.
Testing for accuracy can be difficult. However, if an alternate means of measuring a particular metric is available then use it to verify metric values. For example, if you submit a known number of requests to a server and measure total time for the experiment, then you predict correct values for the relevant metrics and compare them with the actual monitored values. As another example, you can verify an Event Sensor
count metric by examining records that you write to a log file or to the console.
Check for timing inaccuracies that may apply for the metrics. Timing inaccuracies may be caused when low-resolution clocks time metrics for an interval of short duration. For example on Windows systems, the default Java clock advances only once every 15 milliseconds. DMS metrics reported for brief events on these systems must be analyzed with care. Consider using the high resolution clock to address this issue.
The use of DMS metrics has some influence on application performance. When adding metrics, note the following:
The processing required for computing and storing metrics can slow down the execution of an application. DMS is fast, but it may have some required performance cost. In addition, DMS cannot prevent developers from using the DMS API inefficiently. Therefore, before adding DMS instrumentation, establish reasonable expectations. After completing the implementation, measure the actual costs and compare them to your expectations. Be prepared to make changes to the instrumentation to reduce.
You should run your performance tests with and without DMS enabled. If your tests show unacceptable results with DMS enabled, then you may want to re-design or re-implement metrics.
DMS metrics do not support user-based access to DMS reports. When you define and use a DMS metric, the metric is available to any administrator that has access to DMS metrics. This means when you add DMS metrics, it is good practice to avoid placing customer-sensitive information in the metrics.
Use the DMS Sensor weight feature to conditionally limit your instrumentation. With Sensor weight, you specify that applications execute expensive instrumentation only when the Sensor weight is set to a particular value. Using this feature enables you to include expensive metrics that you may only need for debugging.
Example Using SensorWeight for Conditional Instrumentation
/* DMS Method * * If the SensorWeight is high enough, return a phase with the * parameter in the name. Otherwise, return null. */ PhaseEvent heavyPhase(String param) { PhaseEvent pe = null; if (DMSConsole.getSensorWeight() > DMSConsole.NORMAL) { Noun base = Noun.create(binRoot, param, "MathSeries"); pe = PhaseEvent.create(base, "computeSeries", "Time to compute a Binomial series"); pe.deriveMetric(Sensor.all); } return pe; }
In a Java application, use the following method to dump DMS metrics to a file.
The following code.
The
Sensor abstract class provides methods to control PhaseEvent, Event, and State Sensors. The
reset method resets a Sensor's metrics to initial values. The
getResetTime method determines if a Sensor has been reset. The
destroy method removes a Sensor from DMS and releases references to its underlying resources..
The following list includes coding recommendations for working with DMS.
There is a global name space for DMS metrics. When you create a new Noun Sensor (PhaseEvent, Event, or State), its full name must not conflict with names in use by Oracle built-in metrics, or by other applications. It is therefore a good idea to have a root Noun for your application that contains the application's full name. This prevents name space collisions.
See Also:Section A.1.4.1, "General DMS Naming"
Be sure all PhaseEvents are stopped. If the code block to be measured is not in a
try block, then put it in a
try block that includes PhaseEvent's
start. Put the PhaseEvent's
stop in a
finally block. Alternatively, make use of the
abort method in the
finally block, as shown in Example A-6.
Follow DMS naming conventions.
See Also:Section A.1.4, "DMS Naming Conventions"
Avoid creating any DMS Sensor or Noun more than once. The DMS API enables this, and avoids creation of multiple objects, but DMS performs lookups for each subsequent creation attempt. Thus, whenever possible, you should define Sensors and Nouns during static initialization, or in the case of a Servlet, in the
init method.
Assign a type for each Noun that contains Sensors. If no type is assigned, the type is given the value "n/a" (not available). Nouns with the type specified as "n/a" are not shown in the Spy servlet.
Only use PhaseEvents to measure a section of code that is expensive to execute, and takes a significant time to execute under some conditions. In the case where the code never takes significant time to execute, use an Event metric, or remove the PhaseEvent.
The DMS API calls are threadsafe; they provide sufficient synchronization to prevent races and access bugs..
Try to observe the following guidelines when you add DMS metrics:
Add PhaseEvent Sensors.
Following these guidelines for adding PhaseEvent metrics provides the following benefits:
Helps limit the amount of information that DMS collects.
Enables those analyzing the system to prove that a module gives the expected run time performance.
Ensures that people viewing DMS metrics can validate run time performance without seeing an overwhelming amount of data.
Enables those analyzing system performance to separate and track your module from other system modules that are either expensive or failure prone..-7 you set the clock with a value that does not match those listed in Table clock.
The default clock for measuring Oracle HTTP Server performance has a resolution of microseconds (usecs). You can optionally select a higher resolution clock to monitor C processes running under Oracle HTTP Server. To use the high resolution clock under Oracle HTTP Server, you need to set configuration options in httpd.conf, or specify environment variables on the command line.
Table.