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 < 1) { 1061449Stomee System.err.println("Usage: java TestAPI <script> [ 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 < Record > 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->ts = vtimestamp; 2411449Stomee } 2421449Stomee 2431449Stomee sdt:::interrupt-complete 2441449Stomee / self->ts && arg0 / 2451449Stomee { 2461449Stomee this->devi = (struct dev_info *)arg0; 2471449Stomee @counts[stringof(`devnamesp[this->devi->devi_major].dn_name), 2481449Stomee this->devi->devi_instance, cpu] = count(); 2491449Stomee @times[stringof(`devnamesp[this->devi->devi_major].dn_name), 2501449Stomee this->devi->devi_instance, cpu] = sum(vtimestamp - self->ts); 2511449Stomee self->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