xref: /onnv-gate/usr/src/lib/libdtrace_jni/java/docs/html/fast.html (revision 3483:b37715fdf521)
11449Stomee<!--
2*3483Stomee   Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
31449Stomee   Use is subject to license terms.
41449Stomee
51449Stomee   ident	"%Z%%M%	%I%	%E% SMI"
61449Stomee
71449Stomee   CDDL HEADER START
81449Stomee
91449Stomee   The contents of this file are subject to the terms of the
101449Stomee   Common Development and Distribution License (the "License").
111449Stomee   You may not use this file except in compliance with the License.
121449Stomee
131449Stomee   You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
141449Stomee   or http://www.opensolaris.org/os/licensing.
151449Stomee   See the License for the specific language governing permissions
161449Stomee   and limitations under the License.
171449Stomee
181449Stomee   When distributing Covered Code, include this CDDL HEADER in each
191449Stomee   file and include the License file at usr/src/OPENSOLARIS.LICENSE.
201449Stomee   If applicable, add the following below this CDDL HEADER, with the
211449Stomee   fields enclosed by brackets "[]" replaced with your own identifying
221449Stomee   information: Portions Copyright [yyyy] [name of copyright owner]
231449Stomee
241449Stomee   CDDL HEADER END
251449Stomee-->
261449Stomee<html>
271449Stomee<head>
281449Stomee  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
291449Stomee  <title>Quick Start Guide to the Java DTrace API</title>
301449Stomee</head>
311449Stomee<body>
321449Stomee<h1><a name="Quick_Start_Guide_to_the_Java_DTrace_API_"></a>Quick Start
331449StomeeGuide</h1>
341449Stomee<h1><small><small>to the</small> Java DTrace API</small></h1>
351449Stomee<hr style="width: 100%; height: 2px;">
361449Stomee<h2>Contents</h2>
371449Stomee<ul>
381449Stomee  <li><a href="#Hello_World">"hello, world" Example</a></li>
391449Stomee  <ul>
401449Stomee    <li><a href="#Writing_a_Simple_Consumer">Writing a Simple Consumer</a></li>
411449Stomee    <li><a href="#Running_hello.d_Script">Running the <tt>hello.d</tt>
421449Stomee	Script</a></li>
431449Stomee  </ul>
441449Stomee  <li><a href="#Aggregations">Aggregations</a></li>
451449Stomee  <li><a href="#Target_Process">Target Process ID</a></li>
461449Stomee  <li><a href="#Closing_Consumers">Closing Consumers</a></li>
471449Stomee  <li><a href="#Learning_DTrace">Learning More</a><br>
481449Stomee  </li>
491449Stomee</ul>
501449Stomee<h2><a name="Hello_World"></a>"hello, world" Example</h2>
511449StomeeTo demonstrate how to use the Java DTrace API, let's write a simple Java
521449Stomeeprogram that runs a D script, in this case <tt>hello.d</tt> (prints
531449Stomee"hello, world" and exits).  You will need root permission to use the
541449StomeeJava DTrace API (just as you do to use the <tt>dtrace(1M)</tt> command).
551449StomeeYou may want to eliminate this inconvenience by adding the following
561449Stomeeline to <tt>/etc/user_attr</tt>:
571449Stomee<br>
581449Stomee<br>
591449Stomee<tt><i>user-name</i>::::defaultpriv=basic,dtrace_kernel,dtrace_proc</tt>
601449Stomee<br>
611449Stomee<br>
621449Stomee<i>(Substitute your user name.)</i>  See the <a
631449Stomeehref=http://docs.sun.com/app/docs/doc/817-6223/6mlkidln0?a=view>
641449Stomee<b>Security</b></a> chapter of the <i>Solaris Dynamic Tracing Guide</i>
651449Stomeefor more information.
661449Stomee<br>
671449Stomee<h4><a name="Writing_a_Simple_Consumer"></a>Writing a Simple Consumer</h4>
681449StomeeCreating a DTrace <a
691449Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html">consumer</a>
701449Stomeeis easy:
711449Stomee<pre><tt>
721449Stomee    Consumer consumer = new LocalConsumer();
731449Stomee</tt></pre>
741449Stomee<br>
751449StomeeBefore you can do anything with the consumer, you must first open it.
761449StomeeThen you simply compile and enable one or more D programs and run it:
771449Stomee<pre><tt>
781449Stomee    consumer.open();
791449Stomee    consumer.compile(program);
801449Stomee    consumer.enable();
811449Stomee    consumer.go();	// runs in a background thread
821449Stomee</tt></pre>
831449Stomee<br>
841449StomeeTo get the data generated by DTrace, you also need to add a <a
851449Stomeehref="../api/org/opensolaris/os/dtrace/ConsumerListener.html">listener</a>:
861449Stomee<pre><tt>
871449Stomee    consumer.addConsumerListener(new ConsumerAdapter() {
881449Stomee	public void dataReceived(DataEvent e) {
891449Stomee	    System.out.println(e.getProbeData());
901449Stomee	}
911449Stomee    });
921449Stomee</tt></pre>
931449Stomee<br>
941449StomeeHere is a simple example that runs a given D script:<br>
951449Stomee<br>
961449Stomee<b>Java program (<a href="../examples/TestAPI.java">TestAPI.java</a>)</b>
971449Stomee<pre><tt><font color=#aaaaaa>
981449Stomee    import org.opensolaris.os.dtrace.*;
991449Stomee    import java.io.File;
1001449Stomee
1011449Stomee    public class TestAPI {
1021449Stomee	public static void
1031449Stomee	main(String[] args)
1041449Stomee	{
1051449Stomee	    if (args.length &lt; 1) {
1061449Stomee		System.err.println("Usage: java TestAPI &lt;script&gt; [ macroargs... ]");
1071449Stomee		System.exit(2);
1081449Stomee	    }
1091449Stomee
1101449Stomee	    File file = new File(args[0]);
1111449Stomee	    String[] macroArgs = new String[args.length - 1];
1121449Stomee	    System.arraycopy(args, 1, macroArgs, 0, (args.length - 1));</font>
1131449Stomee
1141449Stomee	    Consumer consumer = new LocalConsumer();
1151449Stomee	    consumer.addConsumerListener(new ConsumerAdapter() {
1161449Stomee		public void dataReceived(DataEvent e) {
1171449Stomee		    System.out.println(e.getProbeData());
1181449Stomee		}
1191449Stomee	    });
1201449Stomee<font color=#aaaaaa>
1211449Stomee	    try {</font>
1221449Stomee		consumer.open();
1231449Stomee		consumer.compile(file, macroArgs);
1241449Stomee		consumer.enable();
1251449Stomee		consumer.go();<font color=#aaaaaa>
1261449Stomee	    } catch (Exception e) {
1271449Stomee		e.printStackTrace();
1281449Stomee		System.exit(1);
1291449Stomee	    }
1301449Stomee	}
1311449Stomee    }</font>
1321449Stomee</tt></pre>
1331449Stomee<br>
1341449StomeeCompile the test program as follows:
1351449Stomee<pre><tt>
136*3483Stomee    javac -cp /usr/share/lib/java/dtrace.jar TestAPI.java
1371449Stomee</tt></pre>
1381449Stomee<br>
1391449Stomee<h4><a name="Running_hello.d_Script"></a>Running the <tt>hello.d</tt> Script</h4>
1401449StomeeNow we need a D script for the program to run.  The following is a
1411449Stomeesimple example that prints "hello, world" and exits:<br>
1421449Stomee<b>D script (<a href="../examples/hello.d">hello.d</a>)</b>
1431449Stomee<pre><tt>
1441449Stomee    dtrace:::BEGIN
1451449Stomee    {
1461449Stomee	    trace("hello, world");
1471449Stomee	    exit(0);
1481449Stomee    }
1491449Stomee</tt></pre>
1501449Stomee<br>
1511449StomeeRun as follows:<br>
1521449Stomee<pre><tt>
153*3483Stomee    java -cp .:/usr/share/lib/java/dtrace.jar TestAPI hello.d
1541449Stomee</tt></pre>
1551449Stomee<br>
156*3483StomeeThe output should look like this:
1571449Stomee<pre><tt>
1581449Stomee    org.opensolaris.os.dtrace.ProbeData[epid = 1, cpu = 1,
1591449Stomee    enabledProbeDescription = dtrace:::BEGIN, flow = null, records =
1601449Stomee    ["hello, world", 0]]
1611449Stomee</tt></pre>
1621449Stomee<br>
1631449StomeeThere is one record in the <a
1641449Stomeehref="../api/org/opensolaris/os/dtrace/ProbeData.html"><tt>ProbeData</tt></a>
1651449Stomeefor each action in the D script.  The first record is generated by the
1661449Stomee<tt>trace()</tt> action.  The second is generated by the <tt>exit()</tt>
1671449Stomeeaction.  For prettier output, you could change the <tt>ConsumerAdapter <a
1681449Stomee	href="../api/org/opensolaris/os/dtrace/ConsumerAdapter.html#dataReceived%28org.opensolaris.os.dtrace.DataEvent%29">dataReceived()</a></tt>
1691449Stomeeimplementation as follows:
1701449Stomee<pre><tt><font color=#aaaaaa>
1711449Stomee    consumer.addConsumerListener(new ConsumerAdapter() {
1721449Stomee	public void dataReceived(DataEvent e) {
1731449Stomee	    // System.out.println(e.getProbeData());</font>
1741449Stomee	    ProbeData data = e.getProbeData();
1751449Stomee	    java.util.List &lt; Record &gt; records = data.getRecords();
1761449Stomee	    for (Record r : records) {
1771449Stomee		if (r instanceof ExitRecord) {
1781449Stomee		} else {
1791449Stomee		    System.out.println(r);
1801449Stomee		}
1811449Stomee	    }<font color=#aaaaaa>
1821449Stomee	}
1831449Stomee    });</font>
1841449Stomee</tt></pre>
1851449Stomee<br>
1861449Stomee<h2><a name="Aggregations"></a>Aggregations</h2>
1871449StomeeThe example Java program can just as easily run a more complex script,
1881449Stomeesuch as an aggregation:<br>
1891449Stomee<b>D script (<a href="../examples/syscall.d">syscall.d</a>)</b>
1901449Stomee<pre><tt>
1911449Stomee    syscall:::entry
1921449Stomee    / execname == $$1 /
1931449Stomee    {
1941449Stomee	    @[probefunc] = count();
1951449Stomee    }
1961449Stomee
1971449Stomee    profile:::tick-1sec
1981449Stomee    {
1991449Stomee	    printa(@);
2001449Stomee	    clear(@);
2011449Stomee    }
2021449Stomee</tt></pre>
2031449Stomee<br>
2041449StomeeThe above script uses the <tt>$$1</tt> macro variable as a placeholder
2051449Stomeefor whatever executable you'd like to trace.  See the <a
2061449Stomeehref=http://docs.sun.com/app/docs/doc/817-6223/6mlkidliq?a=view><b>
2071449StomeeMacro Arguments</b></a> section of the <b>Scripting</b> chapter of the
2081449Stomee<i>Solaris Dynamic Tracing Guide</i>.  Using two dollar signs (<tt>$$1</tt>)
2091449Stomeeinstead of one (<tt>$1</tt>) forces expansion of the macro variable to
2101449Stomeetype string.<br>
2111449Stomee<br>
2121449StomeeTo run the example Java program using the above D script, you need to
213*3483Stomeespecify an argument to the <tt>execname</tt> placeholder, such as
214*3483Stomee"java":<br>
2151449Stomee<pre><tt>
216*3483Stomee    java -cp .:/usr/share/lib/java/dtrace.jar TestAPI syscall.d java
2171449Stomee</tt></pre>
2181449Stomee<br>
2191449StomeeA data record generated by the <tt>printa()</tt> action is printed to
2201449Stomeethe console once every second.  It contains counts of system calls by
2211449Stomeefunction name made by java.  No record is generated by the
2221449Stomee<tt>clear()</tt> action.<br>
2231449Stomee<br>
2241449StomeeIf you omit the argument to the <tt>execname</tt> placeholder, the
2251449Stomeeprogram fails to compile and the API throws the following exception:
2261449Stomee<pre><tt>
2271449Stomee    org.opensolaris.os.dtrace.DTraceException: failed to compile script
2281449Stomee    syscall.d: line 2: macro argument $$1 is not defined
2291449Stomee	at org.opensolaris.os.dtrace.LocalConsumer._compileFile(Native Method)
2301449Stomee	at org.opensolaris.os.dtrace.LocalConsumer.compile(LocalConsumer.java:342)
2311449Stomee	at TestAPI.main(TestAPI.java:26)
2321449Stomee</tt></pre>
2331449Stomee<br>
2341449StomeeA DTrace script may have more than one aggregation.  In that case, each
2351449Stomeeaggregation needs a distinct name:<br>
2361449Stomee<b>D script (<a href="../examples/intrstat.d">intrstat.d</a>)</b>
2371449Stomee<pre><tt>
2381449Stomee    sdt:::interrupt-start
2391449Stomee    {
2401449Stomee	    self-&gt;ts = vtimestamp;
2411449Stomee    }
2421449Stomee
2431449Stomee    sdt:::interrupt-complete
2441449Stomee    / self-&gt;ts &amp;&amp; arg0 /
2451449Stomee    {
2461449Stomee	    this-&gt;devi = (struct dev_info *)arg0;
2471449Stomee	    @counts[stringof(`devnamesp[this-&gt;devi-&gt;devi_major].dn_name),
2481449Stomee		this-&gt;devi-&gt;devi_instance, cpu] = count();
2491449Stomee	    @times[stringof(`devnamesp[this-&gt;devi-&gt;devi_major].dn_name),
2501449Stomee		this-&gt;devi-&gt;devi_instance, cpu] = sum(vtimestamp - self-&gt;ts);
2511449Stomee	    self-&gt;ts = 0;
2521449Stomee    }
2531449Stomee</tt></pre>
2541449Stomee<br>
2551449StomeeThe <tt>@counts</tt> and <tt>@times</tt> aggregations both accumulate
2561449Stomeevalues for each unique combination of device name, device instance, and
2571449StomeeCPU (a three-element tuple).  In this example we drop the <tt>tick</tt>
2581449Stomeeprobe to demonstrate a more convenient way to get aggregation data
2591449Stomeewithout the use of the <tt>printa()</tt> action.  The <a
2601449Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#getAggregate%28%29">
261*3483Stomee<tt>getAggregate()</tt></a> method allows us to get a read-consistent
262*3483Stomeesnapshot of all aggregations at once on a programmatic interval.<br>
2631449Stomee<b>Java program (<a href="../examples/TestAPI2.java">TestAPI2.java</a>)</b>
2641449Stomee<pre><tt><font color=#aaaaaa>
2651449Stomee    ...
2661449Stomee
2671449Stomee    try {
2681449Stomee	consumer.open();
2691449Stomee	consumer.compile(file, macroArgs);
2701449Stomee	consumer.enable();
2711449Stomee	consumer.go();</font>
2721449Stomee
2731449Stomee	Aggregate a;
2741449Stomee	do {
2751449Stomee	    Thread.sleep(1000); // 1 second
2761449Stomee	    a = consumer.getAggregate();
2771449Stomee	    if (!a.asMap().isEmpty()) {
2781449Stomee		System.out.println(a);
2791449Stomee	    }
2801449Stomee	} while (consumer.isRunning());<font color=#aaaaaa>
2811449Stomee    } catch (Exception e) {
2821449Stomee	e.printStackTrace();
2831449Stomee	System.exit(1);
2841449Stomee    }
2851449Stomee
2861449Stomee    ...</font>
2871449Stomee</tt></pre>
2881449Stomee<br>
2891449StomeeCompile and run:
2901449Stomee<pre><tt>
291*3483Stomee    javac -cp /usr/share/lib/java/dtrace.jar TestAPI2.java
2921449Stomee</tt></pre>
2931449Stomee<pre><tt>
294*3483Stomee    java -cp .:/usr/share/lib/java/dtrace.jar TestAPI2 intrstat.d
2951449Stomee</tt></pre>
2961449Stomee<br>
2971449StomeeTry removing the <tt>tick</tt> probe from the <tt>syscall.d</tt> example
2981449Stomeeand running it again with the above modification (<tt>TestAPI2</tt>).<br>
2991449Stomee<br>
3001449StomeeBy default, the requested aggregate includes every aggregation and
3011449Stomeeaccumulates running totals.  To display values per time interval
3021449Stomee(instead of running totals), clear the aggregations each time you call
3031449Stomee<tt>getAggregate()</tt>.  Clearing an aggregation resets all counts to
304*3483Stomeezero without removing any elements.  The following modification to the
3051449Stomeeexample above clears all aggregations:
3061449Stomee<pre><tt><font color=#aaaaaa>
3071449Stomee	    // a = consumer.getAggregate();</font>
3081449Stomee	    a = consumer.getAggregate(null, null); // included, cleared
3091449Stomee</tt></pre>
3101449Stomee<br>
3111449StomeeEach <tt>Set</tt> of aggregation names, <tt>included</tt> and
3121449Stomee<tt>cleared</tt>, specifies <i>all</i> aggregations if <tt>null</tt> and
3131449Stomeeno aggregations if empty.  Any subset is possible.  However, if an
3141449Stomeeaggregation has ever been used in the <tt>printa()</tt> action, it is no
3151449Stomeelonger available to the <tt>getAggregate()</tt> method.<br>
3161449Stomee<br>
3171449StomeeBe aware that you cannot call <tt>getAggregate()</tt> on an interval
3181449Stomeefaster that the <tt>aggrate</tt> setting.  See the <a
3191449Stomeehref=http://docs.sun.com/app/docs/doc/817-6223/6mlkidlis?a=view>
3201449Stomee<b>Options and Tunables</b></a> chapter of the <i>Solaris Dynamic
3211449StomeeTracing Guide</i>.  See also the <a
3221449Stomeehref=http://docs.sun.com/app/docs/doc/817-6223/6mlkidlhf?a=view>
3231449Stomee<b>Minimizing Drops</b></a> section of the <b>Aggregations</b> chapter
3241449Stomeefor specific information about the <tt>aggrate</tt> option.  The default
3251449Stomee<tt>aggrate</tt> is once per second.  Here's an example of how you might
3261449Stomeedouble the <tt>aggrate</tt> to minimize drops:
3271449Stomee<pre><tt>
3281449Stomee    consumer.setOption(Option.aggrate, Option.millis(500)); // every half second
3291449Stomee</tt></pre>
3301449Stomee<br>
3311449StomeeEven a single drop terminates the consumer unless you override the <a
3321449Stomeehref="../api/org/opensolaris/os/dtrace/ConsumerAdapter.html#dataDropped%28org.opensolaris.os.dtrace.DropEvent%29">
3331449Stomee<tt>dataDropped()</tt></a> method of <tt>ConsumerAdapter</tt> to handle
3341449Stomeedrops differently.  To avoid drops, it is probably better to increase
3351449Stomeethe <tt>aggsize</tt> option, since increasing the <tt>aggrate</tt> makes
3361449Stomeethe consumer work harder.  In most cases, the <tt>aggrate</tt> should
3371449Stomeeonly be increased when you need to update a display of aggregation data
3381449Stomeemore frequently than once per second.  Many runtime options, including
3391449Stomee<tt>aggrate</tt>, can be changed dynamically while the consumer is
3401449Stomeerunning.<br>
3411449Stomee<br>
3421449StomeeIt's also worth mentioning that a D aggregation may omit square
3431449Stomeebrackets and aggregate only a single value:
3441449Stomee<pre><tt>
3451449Stomee    @total = count();
3461449Stomee</tt></pre>
3471449Stomee<br>
3481449StomeeThe resulting singleton <a
3491449Stomeehref="../api/org/opensolaris/os/dtrace/Aggregation.html">
350*3483Stomee<tt>Aggregation</tt></a> has one record that may be obtained as follows:
3511449Stomee<pre><tt>
3521449Stomee    Aggregate a = consumer.getAggregate();
3531449Stomee    Aggregation total = a.getAggregation("total");
3541449Stomee    AggregationRecord totalRecord = total.getRecord(Tuple.EMPTY);
3551449Stomee</tt></pre>
3561449Stomee<br>
3571449Stomee<h2><a name="Target_Process"></a>Target Process ID</h2>
3581449StomeeIn addition to supporting macro arguments (see the <tt>syscall.d</tt>
3591449Stomeeaggregation example above), the Java DTrace API also supports the
3601449Stomee<tt>$target</tt> macro variable.  (See the <a
3611449Stomeehref=http://docs.sun.com/app/docs/doc/817-6223/6mlkidlir?a=view>
3621449Stomee<b>Target Process ID</b></a> section of the <b>Scripting</b> chapter of
3631449Stomeethe <i>Solaris Dynamic Tracing Guide</i>.)  This allows you to trace a
3641449Stomeeprocess from the very beginning of its execution, rather than sometime
3651449Stomeeafter you manually obtain its process ID.  The API does this by creating
3661449Stomeea process that is initially suspended and allowed to start only after <a
3671449Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#go%28%29">
368*3483Stomee<tt>go()</tt></a> has initiated tracing.  For example, you can aggregate
369*3483Stomeeall the system calls from start to finish made by the <tt>date</tt>
370*3483Stomeecommand:<br>
3711449Stomee<b>D script (<a href="../examples/target.d">target.d</a>)</b>
3721449Stomee<pre><tt>
3731449Stomee    syscall:::entry
3741449Stomee    / pid == $target /
3751449Stomee    {
3761449Stomee	    @[probefunc] = count();
3771449Stomee    }
3781449Stomee</tt></pre>
3791449Stomee<br>
3801449StomeeA modified version of the <tt>TestAPI.java</tt> program adds the <a
3811449Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#createProcess%28java.lang.String%29">
3821449Stomee<tt>createProcess()</tt></a> call to execute the given command but
3831449Stomeeprevent it from starting until the consumer is running:<br>
3841449Stomee<b>Java program (<a href="../examples/TestTarget.java">TestTarget.java</a>)</b>
3851449Stomee<pre><tt><font color=#aaaaaa>
3861449Stomee    ...
3871449Stomee    consumer.open();</font>
3881449Stomee    consumer.createProcess(command);<font color=#aaaaaa>
3891449Stomee    consumer.compile(file);
3901449Stomee    consumer.enable();
3911449Stomee    consumer.go();
3921449Stomee    ...</font>
3931449Stomee</tt></pre>
3941449Stomee<br>
3951449StomeeIt also overrides the <a
3961449Stomeehref="../api/org/opensolaris/os/dtrace/ConsumerAdapter.html#processStateChanged%28org.opensolaris.os.dtrace.ProcessEvent%29">
3971449Stomee<tt>processStateChanged()</tt></a> method of the
3981449Stomee<tt>ConsumerAdapter</tt> to print a notification when the process has
3991449Stomeeended:
4001449Stomee<pre><tt><font color=#aaaaaa>
4011449Stomee    ...
4021449Stomee    consumer.addConsumerListener(new ConsumerAdapter() {
4031449Stomee	public void dataReceived(DataEvent e) {
4041449Stomee	    System.out.println(e.getProbeData());
4051449Stomee	}
4061449Stomee	public void consumerStopped(ConsumerEvent e) {
4071449Stomee	    try {
4081449Stomee		Aggregate a = consumer.getAggregate();
4091449Stomee		for (Aggregation agg : a.asMap().values()) {
4101449Stomee		    for (AggregationRecord rec : agg.asMap().values()) {
4111449Stomee			System.out.println(rec.getTuple() + " " +
4121449Stomee				rec.getValue());
4131449Stomee		    }
4141449Stomee		}
4151449Stomee	    } catch (Exception x) {
4161449Stomee		x.printStackTrace();
4171449Stomee		System.exit(1);
4181449Stomee	    }
4191449Stomee	    consumer.close();
4201449Stomee	}</font>
4211449Stomee	public void processStateChanged(ProcessEvent e) {
4221449Stomee	    System.out.println(e.getProcessState());
4231449Stomee	}<font color=#aaaaaa>
4241449Stomee    });
4251449Stomee    ...</font>
4261449Stomee</tt></pre>
4271449Stomee<br>
4281449StomeeCompile and run:
4291449Stomee<pre><tt>
430*3483Stomee    javac -cp /usr/share/lib/java/dtrace.jar TestTarget.java
4311449Stomee</tt></pre>
4321449Stomee<pre><tt>
433*3483Stomee    java -cp .:/usr/share/lib/java/dtrace.jar TestTarget target.d date
4341449Stomee</tt></pre>
4351449Stomee<br>
4361449StomeeThe consumer exits automatically when the target <tt>date</tt> process
4371449Stomeecompletes.<br>
4381449Stomee<h2><a name="Closing_Consumers"></a>Closing Consumers</h2>
4391449StomeeAn application using the Java DTrace API may run multiple consumers
4401449Stomeesimultaneously.  When a consumer stops running, the programmer is
4411449Stomeeresponsible for closing it in order to release the system resources it
4421449Stomeeholds.  A consumer may stop running for any of the following reasons:
4431449Stomee<ul>
4441449Stomee  <li>It was stopped explicitly by a call to its <a
4451449Stomeehref=../api/org/opensolaris/os/dtrace/Consumer.html#stop()>
4461449Stomee<tt>stop()</tt></a> method</li>
4471449Stomee  <li>It encountered the <tt>exit()</tt> action</li>
4481449Stomee  <li>Its <tt>$target</tt> process or processes (if any) all completed</li>
4491449Stomee  <li>It encountered an exception</li>
4501449Stomee</ul>
4511449StomeeBy default, an exception prints a stack trace to <tt>stderr</tt> before
4521449Stomeenotifying listeners that the consumer has stopped.  You can define
4531449Stomeedifferent behavior by setting an <a
4541449Stomeehref=../api/org/opensolaris/os/dtrace/ExceptionHandler.html>
4551449Stomee<tt>ExceptionHandler</tt></a>, but the consumer is still stopped.<br>
4561449Stomee<br>
4571449StomeeThe same listener that receives probe data generated by DTrace is also
4581449Stomeenotified when the consumer stops.  This is a good place to close the
4591449Stomeeconsumer:
4601449Stomee<pre><tt><font color=#aaaaaa>
4611449Stomee    consumer.addConsumerListener(new ConsumerAdapter() {
4621449Stomee	public void dataReceived(DataEvent e) {
4631449Stomee	    System.out.println(e.getProbeData());
4641449Stomee	}</font>
4651449Stomee	public void consumerStopped(ConsumerEvent e) {
4661449Stomee	    Consumer consumer = (Consumer)e.getSource();
4671449Stomee		consumer.close();
4681449Stomee	    }
4691449Stomee	}<font color=#aaaaaa>
4701449Stomee    });</font>
4711449Stomee</tt></pre>
4721449Stomee<br>
4731449StomeeThis releases the resources held by the consumer in all cases, i.e.
4741449Stomeeafter it exits for <i>any</i> of the reasons listed above.<br>
4751449Stomee<br>
4761449StomeeYou can request the last aggregate snapshot made by a stopped consumer,
4771449Stomeeas long as it has not yet been closed:
4781449Stomee<pre><tt>
4791449Stomee    Aggregate a = consumer.getAggregate();
4801449Stomee</tt></pre>
4811449Stomee<br>
4821449StomeeNote however that any aggregation that has already appeared in a <a
4831449Stomeehref=../api/org/opensolaris/os/dtrace/PrintaRecord.html>
4841449Stomee<tt>PrintaRecord</tt></a> as a result of the <tt>printa()</tt> action
4851449Stomeeaction will not be included in the requested aggregate.
4861449Stomee<h2><a name="Learning_DTrace"></a>Learning More</h2>
4871449Stomee<br>
4881449StomeeThe <a href="http://www.opensolaris.org/os/community/dtrace/">
4891449StomeeOpenSolaris DTrace page</a> has links to resources to help you learn
4901449StomeeDTrace.  In particular, you should read the <a
4912777Stomeehref="http://docs.sun.com/app/docs/doc/817-6223"><i>Solaris Dynamic Tracing
4921449Stomee    Guide</i></a>.<br>
4931449Stomee<br>
4941449StomeeTry the example Java programs on this page with other D scripts.  You
4951449Stomeeneed not remove <tt>#!/usr/sbin/dtrace -s</tt> from the top of an
4961449Stomeeexecutable script.  You may want to remove <tt>profile:::tick*</tt>
4971449Stomeeclauses if you plan to use the <tt>Consumer</tt> <a
4981449Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#getAggregate%28%29">
499*3483Stomee<tt>getAggregate()</tt></a> method and control the data interval
5001449Stomeeprogrammatically.  If the script uses the pre-compiler, you will need to
5011449Stomeecall the <tt>Consumer</tt> <a
5021449Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#setOption%28java.lang.String%29">
5031449Stomee<tt>setOption()</tt></a> method with the <a
5041449Stomeehref="../api/org/opensolaris/os/dtrace/Option.html#cpp">
5051449Stomee<tt>Option.cpp</tt></a> argument.<br>
5061449Stomee<br>
5071449StomeeTo quickly familiarize yourself with the Java DTrace API, take a look at
5081449Stomeethe overview <a href="JavaDTraceAPI.html">diagram</a>.<br>
5091449Stomee<br>
5101449Stomee<a href="#Quick_Start_Guide_to_the_Java_DTrace_API_">Back to top</a><br>
5111449Stomee<br>
5121449Stomee</body>
5131449Stomee</html>
514