xref: /illumos-gate/usr/src/lib/libdtrace_jni/java/docs/html/fast.html (revision bbf215553c7233fbab8a0afdf1fac74c44781867)
1fb3fb4f3Stomee<!--
291cfa10aStomee   Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
3fb3fb4f3Stomee   Use is subject to license terms.
4fb3fb4f3Stomee
5fb3fb4f3Stomee   CDDL HEADER START
6fb3fb4f3Stomee
7fb3fb4f3Stomee   The contents of this file are subject to the terms of the
8fb3fb4f3Stomee   Common Development and Distribution License (the "License").
9fb3fb4f3Stomee   You may not use this file except in compliance with the License.
10fb3fb4f3Stomee
11fb3fb4f3Stomee   You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
12fb3fb4f3Stomee   or http://www.opensolaris.org/os/licensing.
13fb3fb4f3Stomee   See the License for the specific language governing permissions
14fb3fb4f3Stomee   and limitations under the License.
15fb3fb4f3Stomee
16fb3fb4f3Stomee   When distributing Covered Code, include this CDDL HEADER in each
17fb3fb4f3Stomee   file and include the License file at usr/src/OPENSOLARIS.LICENSE.
18fb3fb4f3Stomee   If applicable, add the following below this CDDL HEADER, with the
19fb3fb4f3Stomee   fields enclosed by brackets "[]" replaced with your own identifying
20fb3fb4f3Stomee   information: Portions Copyright [yyyy] [name of copyright owner]
21fb3fb4f3Stomee
22fb3fb4f3Stomee   CDDL HEADER END
23fb3fb4f3Stomee-->
24fb3fb4f3Stomee<html>
25fb3fb4f3Stomee<head>
26fb3fb4f3Stomee  <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
27fb3fb4f3Stomee  <title>Quick Start Guide to the Java DTrace API</title>
28fb3fb4f3Stomee</head>
29fb3fb4f3Stomee<body>
30fb3fb4f3Stomee<h1><a name="Quick_Start_Guide_to_the_Java_DTrace_API_"></a>Quick Start
31fb3fb4f3StomeeGuide</h1>
32fb3fb4f3Stomee<h1><small><small>to the</small> Java DTrace API</small></h1>
33fb3fb4f3Stomee<hr style="width: 100%; height: 2px;">
34fb3fb4f3Stomee<h2>Contents</h2>
35fb3fb4f3Stomee<ul>
36fb3fb4f3Stomee  <li><a href="#Hello_World">"hello, world" Example</a></li>
37fb3fb4f3Stomee  <ul>
38fb3fb4f3Stomee    <li><a href="#Writing_a_Simple_Consumer">Writing a Simple Consumer</a></li>
39fb3fb4f3Stomee    <li><a href="#Running_hello.d_Script">Running the <tt>hello.d</tt>
40fb3fb4f3Stomee	Script</a></li>
41fb3fb4f3Stomee  </ul>
42fb3fb4f3Stomee  <li><a href="#Aggregations">Aggregations</a></li>
43fb3fb4f3Stomee  <li><a href="#Target_Process">Target Process ID</a></li>
44fb3fb4f3Stomee  <li><a href="#Closing_Consumers">Closing Consumers</a></li>
45fb3fb4f3Stomee  <li><a href="#Learning_DTrace">Learning More</a><br>
46fb3fb4f3Stomee  </li>
47fb3fb4f3Stomee</ul>
48fb3fb4f3Stomee<h2><a name="Hello_World"></a>"hello, world" Example</h2>
49fb3fb4f3StomeeTo demonstrate how to use the Java DTrace API, let's write a simple Java
50fb3fb4f3Stomeeprogram that runs a D script, in this case <tt>hello.d</tt> (prints
51fb3fb4f3Stomee"hello, world" and exits).  You will need root permission to use the
52*bbf21555SRichard LoweJava DTrace API (just as you do to use the <tt>dtrace(8)</tt> command).
53fb3fb4f3StomeeYou may want to eliminate this inconvenience by adding the following
54fb3fb4f3Stomeeline to <tt>/etc/user_attr</tt>:
55fb3fb4f3Stomee<br>
56fb3fb4f3Stomee<br>
57fb3fb4f3Stomee<tt><i>user-name</i>::::defaultpriv=basic,dtrace_kernel,dtrace_proc</tt>
58fb3fb4f3Stomee<br>
59fb3fb4f3Stomee<br>
60fb3fb4f3Stomee<i>(Substitute your user name.)</i>  See the <a
613a931819SPeter Tribblehref=http://dtrace.org/guide/chp-sec.html>
623a931819SPeter Tribble<b>Security</b></a> chapter of the <i>Dynamic Tracing Guide</i>
63fb3fb4f3Stomeefor more information.
64fb3fb4f3Stomee<br>
65fb3fb4f3Stomee<h4><a name="Writing_a_Simple_Consumer"></a>Writing a Simple Consumer</h4>
66fb3fb4f3StomeeCreating a DTrace <a
67fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html">consumer</a>
68fb3fb4f3Stomeeis easy:
69fb3fb4f3Stomee<pre><tt>
70fb3fb4f3Stomee    Consumer consumer = new LocalConsumer();
71fb3fb4f3Stomee</tt></pre>
72fb3fb4f3Stomee<br>
73fb3fb4f3StomeeBefore you can do anything with the consumer, you must first open it.
74fb3fb4f3StomeeThen you simply compile and enable one or more D programs and run it:
75fb3fb4f3Stomee<pre><tt>
76fb3fb4f3Stomee    consumer.open();
77fb3fb4f3Stomee    consumer.compile(program);
78fb3fb4f3Stomee    consumer.enable();
79fb3fb4f3Stomee    consumer.go();	// runs in a background thread
80fb3fb4f3Stomee</tt></pre>
81fb3fb4f3Stomee<br>
82fb3fb4f3StomeeTo get the data generated by DTrace, you also need to add a <a
83fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/ConsumerListener.html">listener</a>:
84fb3fb4f3Stomee<pre><tt>
85fb3fb4f3Stomee    consumer.addConsumerListener(new ConsumerAdapter() {
86fb3fb4f3Stomee	public void dataReceived(DataEvent e) {
87fb3fb4f3Stomee	    System.out.println(e.getProbeData());
88fb3fb4f3Stomee	}
89fb3fb4f3Stomee    });
90fb3fb4f3Stomee</tt></pre>
91fb3fb4f3Stomee<br>
92fb3fb4f3StomeeHere is a simple example that runs a given D script:<br>
93fb3fb4f3Stomee<br>
94fb3fb4f3Stomee<b>Java program (<a href="../examples/TestAPI.java">TestAPI.java</a>)</b>
95fb3fb4f3Stomee<pre><tt><font color=#aaaaaa>
96fb3fb4f3Stomee    import org.opensolaris.os.dtrace.*;
97fb3fb4f3Stomee    import java.io.File;
98fb3fb4f3Stomee
99fb3fb4f3Stomee    public class TestAPI {
100fb3fb4f3Stomee	public static void
101fb3fb4f3Stomee	main(String[] args)
102fb3fb4f3Stomee	{
103fb3fb4f3Stomee	    if (args.length &lt; 1) {
104fb3fb4f3Stomee		System.err.println("Usage: java TestAPI &lt;script&gt; [ macroargs... ]");
105fb3fb4f3Stomee		System.exit(2);
106fb3fb4f3Stomee	    }
107fb3fb4f3Stomee
108fb3fb4f3Stomee	    File file = new File(args[0]);
109fb3fb4f3Stomee	    String[] macroArgs = new String[args.length - 1];
110fb3fb4f3Stomee	    System.arraycopy(args, 1, macroArgs, 0, (args.length - 1));</font>
111fb3fb4f3Stomee
112fb3fb4f3Stomee	    Consumer consumer = new LocalConsumer();
113fb3fb4f3Stomee	    consumer.addConsumerListener(new ConsumerAdapter() {
114fb3fb4f3Stomee		public void dataReceived(DataEvent e) {
115fb3fb4f3Stomee		    System.out.println(e.getProbeData());
116fb3fb4f3Stomee		}
117fb3fb4f3Stomee	    });
118fb3fb4f3Stomee<font color=#aaaaaa>
119fb3fb4f3Stomee	    try {</font>
120fb3fb4f3Stomee		consumer.open();
121fb3fb4f3Stomee		consumer.compile(file, macroArgs);
122fb3fb4f3Stomee		consumer.enable();
123fb3fb4f3Stomee		consumer.go();<font color=#aaaaaa>
124fb3fb4f3Stomee	    } catch (Exception e) {
125fb3fb4f3Stomee		e.printStackTrace();
126fb3fb4f3Stomee		System.exit(1);
127fb3fb4f3Stomee	    }
128fb3fb4f3Stomee	}
129fb3fb4f3Stomee    }</font>
130fb3fb4f3Stomee</tt></pre>
131fb3fb4f3Stomee<br>
132fb3fb4f3StomeeCompile the test program as follows:
133fb3fb4f3Stomee<pre><tt>
13491cfa10aStomee    javac -cp /usr/share/lib/java/dtrace.jar TestAPI.java
135fb3fb4f3Stomee</tt></pre>
136fb3fb4f3Stomee<br>
137fb3fb4f3Stomee<h4><a name="Running_hello.d_Script"></a>Running the <tt>hello.d</tt> Script</h4>
138fb3fb4f3StomeeNow we need a D script for the program to run.  The following is a
139fb3fb4f3Stomeesimple example that prints "hello, world" and exits:<br>
140fb3fb4f3Stomee<b>D script (<a href="../examples/hello.d">hello.d</a>)</b>
141fb3fb4f3Stomee<pre><tt>
142fb3fb4f3Stomee    dtrace:::BEGIN
143fb3fb4f3Stomee    {
144fb3fb4f3Stomee	    trace("hello, world");
145fb3fb4f3Stomee	    exit(0);
146fb3fb4f3Stomee    }
147fb3fb4f3Stomee</tt></pre>
148fb3fb4f3Stomee<br>
149fb3fb4f3StomeeRun as follows:<br>
150fb3fb4f3Stomee<pre><tt>
15191cfa10aStomee    java -cp .:/usr/share/lib/java/dtrace.jar TestAPI hello.d
152fb3fb4f3Stomee</tt></pre>
153fb3fb4f3Stomee<br>
15491cfa10aStomeeThe output should look like this:
155fb3fb4f3Stomee<pre><tt>
156fb3fb4f3Stomee    org.opensolaris.os.dtrace.ProbeData[epid = 1, cpu = 1,
157fb3fb4f3Stomee    enabledProbeDescription = dtrace:::BEGIN, flow = null, records =
158fb3fb4f3Stomee    ["hello, world", 0]]
159fb3fb4f3Stomee</tt></pre>
160fb3fb4f3Stomee<br>
161fb3fb4f3StomeeThere is one record in the <a
162fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/ProbeData.html"><tt>ProbeData</tt></a>
163fb3fb4f3Stomeefor each action in the D script.  The first record is generated by the
164fb3fb4f3Stomee<tt>trace()</tt> action.  The second is generated by the <tt>exit()</tt>
165fb3fb4f3Stomeeaction.  For prettier output, you could change the <tt>ConsumerAdapter <a
166fb3fb4f3Stomee	href="../api/org/opensolaris/os/dtrace/ConsumerAdapter.html#dataReceived%28org.opensolaris.os.dtrace.DataEvent%29">dataReceived()</a></tt>
167fb3fb4f3Stomeeimplementation as follows:
168fb3fb4f3Stomee<pre><tt><font color=#aaaaaa>
169fb3fb4f3Stomee    consumer.addConsumerListener(new ConsumerAdapter() {
170fb3fb4f3Stomee	public void dataReceived(DataEvent e) {
171fb3fb4f3Stomee	    // System.out.println(e.getProbeData());</font>
172fb3fb4f3Stomee	    ProbeData data = e.getProbeData();
173fb3fb4f3Stomee	    java.util.List &lt; Record &gt; records = data.getRecords();
174fb3fb4f3Stomee	    for (Record r : records) {
175fb3fb4f3Stomee		if (r instanceof ExitRecord) {
176fb3fb4f3Stomee		} else {
177fb3fb4f3Stomee		    System.out.println(r);
178fb3fb4f3Stomee		}
179fb3fb4f3Stomee	    }<font color=#aaaaaa>
180fb3fb4f3Stomee	}
181fb3fb4f3Stomee    });</font>
182fb3fb4f3Stomee</tt></pre>
183fb3fb4f3Stomee<br>
184fb3fb4f3Stomee<h2><a name="Aggregations"></a>Aggregations</h2>
185fb3fb4f3StomeeThe example Java program can just as easily run a more complex script,
186fb3fb4f3Stomeesuch as an aggregation:<br>
187fb3fb4f3Stomee<b>D script (<a href="../examples/syscall.d">syscall.d</a>)</b>
188fb3fb4f3Stomee<pre><tt>
189fb3fb4f3Stomee    syscall:::entry
190fb3fb4f3Stomee    / execname == $$1 /
191fb3fb4f3Stomee    {
192fb3fb4f3Stomee	    @[probefunc] = count();
193fb3fb4f3Stomee    }
194fb3fb4f3Stomee
195fb3fb4f3Stomee    profile:::tick-1sec
196fb3fb4f3Stomee    {
197fb3fb4f3Stomee	    printa(@);
198fb3fb4f3Stomee	    clear(@);
199fb3fb4f3Stomee    }
200fb3fb4f3Stomee</tt></pre>
201fb3fb4f3Stomee<br>
202fb3fb4f3StomeeThe above script uses the <tt>$$1</tt> macro variable as a placeholder
203fb3fb4f3Stomeefor whatever executable you'd like to trace.  See the <a
2043a931819SPeter Tribblehref=http://dtrace.org/guide/chp-script.html#chp-script-3><b>
205fb3fb4f3StomeeMacro Arguments</b></a> section of the <b>Scripting</b> chapter of the
2063a931819SPeter Tribble<i>Dynamic Tracing Guide</i>.  Using two dollar signs (<tt>$$1</tt>)
207fb3fb4f3Stomeeinstead of one (<tt>$1</tt>) forces expansion of the macro variable to
208fb3fb4f3Stomeetype string.<br>
209fb3fb4f3Stomee<br>
210fb3fb4f3StomeeTo run the example Java program using the above D script, you need to
21191cfa10aStomeespecify an argument to the <tt>execname</tt> placeholder, such as
21291cfa10aStomee"java":<br>
213fb3fb4f3Stomee<pre><tt>
21491cfa10aStomee    java -cp .:/usr/share/lib/java/dtrace.jar TestAPI syscall.d java
215fb3fb4f3Stomee</tt></pre>
216fb3fb4f3Stomee<br>
217fb3fb4f3StomeeA data record generated by the <tt>printa()</tt> action is printed to
218fb3fb4f3Stomeethe console once every second.  It contains counts of system calls by
219fb3fb4f3Stomeefunction name made by java.  No record is generated by the
220fb3fb4f3Stomee<tt>clear()</tt> action.<br>
221fb3fb4f3Stomee<br>
222fb3fb4f3StomeeIf you omit the argument to the <tt>execname</tt> placeholder, the
223fb3fb4f3Stomeeprogram fails to compile and the API throws the following exception:
224fb3fb4f3Stomee<pre><tt>
225fb3fb4f3Stomee    org.opensolaris.os.dtrace.DTraceException: failed to compile script
226fb3fb4f3Stomee    syscall.d: line 2: macro argument $$1 is not defined
227fb3fb4f3Stomee	at org.opensolaris.os.dtrace.LocalConsumer._compileFile(Native Method)
228fb3fb4f3Stomee	at org.opensolaris.os.dtrace.LocalConsumer.compile(LocalConsumer.java:342)
229fb3fb4f3Stomee	at TestAPI.main(TestAPI.java:26)
230fb3fb4f3Stomee</tt></pre>
231fb3fb4f3Stomee<br>
232fb3fb4f3StomeeA DTrace script may have more than one aggregation.  In that case, each
233fb3fb4f3Stomeeaggregation needs a distinct name:<br>
234fb3fb4f3Stomee<b>D script (<a href="../examples/intrstat.d">intrstat.d</a>)</b>
235fb3fb4f3Stomee<pre><tt>
236fb3fb4f3Stomee    sdt:::interrupt-start
237fb3fb4f3Stomee    {
238fb3fb4f3Stomee	    self-&gt;ts = vtimestamp;
239fb3fb4f3Stomee    }
240fb3fb4f3Stomee
241fb3fb4f3Stomee    sdt:::interrupt-complete
242fb3fb4f3Stomee    / self-&gt;ts &amp;&amp; arg0 /
243fb3fb4f3Stomee    {
244fb3fb4f3Stomee	    this-&gt;devi = (struct dev_info *)arg0;
245fb3fb4f3Stomee	    @counts[stringof(`devnamesp[this-&gt;devi-&gt;devi_major].dn_name),
246fb3fb4f3Stomee		this-&gt;devi-&gt;devi_instance, cpu] = count();
247fb3fb4f3Stomee	    @times[stringof(`devnamesp[this-&gt;devi-&gt;devi_major].dn_name),
248fb3fb4f3Stomee		this-&gt;devi-&gt;devi_instance, cpu] = sum(vtimestamp - self-&gt;ts);
249fb3fb4f3Stomee	    self-&gt;ts = 0;
250fb3fb4f3Stomee    }
251fb3fb4f3Stomee</tt></pre>
252fb3fb4f3Stomee<br>
253fb3fb4f3StomeeThe <tt>@counts</tt> and <tt>@times</tt> aggregations both accumulate
254fb3fb4f3Stomeevalues for each unique combination of device name, device instance, and
255fb3fb4f3StomeeCPU (a three-element tuple).  In this example we drop the <tt>tick</tt>
256fb3fb4f3Stomeeprobe to demonstrate a more convenient way to get aggregation data
257fb3fb4f3Stomeewithout the use of the <tt>printa()</tt> action.  The <a
258fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#getAggregate%28%29">
25991cfa10aStomee<tt>getAggregate()</tt></a> method allows us to get a read-consistent
26091cfa10aStomeesnapshot of all aggregations at once on a programmatic interval.<br>
261fb3fb4f3Stomee<b>Java program (<a href="../examples/TestAPI2.java">TestAPI2.java</a>)</b>
262fb3fb4f3Stomee<pre><tt><font color=#aaaaaa>
263fb3fb4f3Stomee    ...
264fb3fb4f3Stomee
265fb3fb4f3Stomee    try {
266fb3fb4f3Stomee	consumer.open();
267fb3fb4f3Stomee	consumer.compile(file, macroArgs);
268fb3fb4f3Stomee	consumer.enable();
269fb3fb4f3Stomee	consumer.go();</font>
270fb3fb4f3Stomee
271fb3fb4f3Stomee	Aggregate a;
272fb3fb4f3Stomee	do {
273fb3fb4f3Stomee	    Thread.sleep(1000); // 1 second
274fb3fb4f3Stomee	    a = consumer.getAggregate();
275fb3fb4f3Stomee	    if (!a.asMap().isEmpty()) {
276fb3fb4f3Stomee		System.out.println(a);
277fb3fb4f3Stomee	    }
278fb3fb4f3Stomee	} while (consumer.isRunning());<font color=#aaaaaa>
279fb3fb4f3Stomee    } catch (Exception e) {
280fb3fb4f3Stomee	e.printStackTrace();
281fb3fb4f3Stomee	System.exit(1);
282fb3fb4f3Stomee    }
283fb3fb4f3Stomee
284fb3fb4f3Stomee    ...</font>
285fb3fb4f3Stomee</tt></pre>
286fb3fb4f3Stomee<br>
287fb3fb4f3StomeeCompile and run:
288fb3fb4f3Stomee<pre><tt>
28991cfa10aStomee    javac -cp /usr/share/lib/java/dtrace.jar TestAPI2.java
290fb3fb4f3Stomee</tt></pre>
291fb3fb4f3Stomee<pre><tt>
29291cfa10aStomee    java -cp .:/usr/share/lib/java/dtrace.jar TestAPI2 intrstat.d
293fb3fb4f3Stomee</tt></pre>
294fb3fb4f3Stomee<br>
295fb3fb4f3StomeeTry removing the <tt>tick</tt> probe from the <tt>syscall.d</tt> example
296fb3fb4f3Stomeeand running it again with the above modification (<tt>TestAPI2</tt>).<br>
297fb3fb4f3Stomee<br>
298fb3fb4f3StomeeBy default, the requested aggregate includes every aggregation and
299fb3fb4f3Stomeeaccumulates running totals.  To display values per time interval
300fb3fb4f3Stomee(instead of running totals), clear the aggregations each time you call
301fb3fb4f3Stomee<tt>getAggregate()</tt>.  Clearing an aggregation resets all counts to
30291cfa10aStomeezero without removing any elements.  The following modification to the
303fb3fb4f3Stomeeexample above clears all aggregations:
304fb3fb4f3Stomee<pre><tt><font color=#aaaaaa>
305fb3fb4f3Stomee	    // a = consumer.getAggregate();</font>
306fb3fb4f3Stomee	    a = consumer.getAggregate(null, null); // included, cleared
307fb3fb4f3Stomee</tt></pre>
308fb3fb4f3Stomee<br>
309fb3fb4f3StomeeEach <tt>Set</tt> of aggregation names, <tt>included</tt> and
310fb3fb4f3Stomee<tt>cleared</tt>, specifies <i>all</i> aggregations if <tt>null</tt> and
311fb3fb4f3Stomeeno aggregations if empty.  Any subset is possible.  However, if an
312fb3fb4f3Stomeeaggregation has ever been used in the <tt>printa()</tt> action, it is no
313fb3fb4f3Stomeelonger available to the <tt>getAggregate()</tt> method.<br>
314fb3fb4f3Stomee<br>
315fb3fb4f3StomeeBe aware that you cannot call <tt>getAggregate()</tt> on an interval
316fb3fb4f3Stomeefaster that the <tt>aggrate</tt> setting.  See the <a
3173a931819SPeter Tribblehref=http://dtrace.org/guide/chp-opt.html>
3183a931819SPeter Tribble<b>Options and Tunables</b></a> chapter of the <i>Dynamic
319fb3fb4f3StomeeTracing Guide</i>.  See also the <a
3203a931819SPeter Tribblehref=http://dtrace.org/guide/chp-aggs.html#chp-aggs-4>
321fb3fb4f3Stomee<b>Minimizing Drops</b></a> section of the <b>Aggregations</b> chapter
322fb3fb4f3Stomeefor specific information about the <tt>aggrate</tt> option.  The default
323fb3fb4f3Stomee<tt>aggrate</tt> is once per second.  Here's an example of how you might
324fb3fb4f3Stomeedouble the <tt>aggrate</tt> to minimize drops:
325fb3fb4f3Stomee<pre><tt>
326fb3fb4f3Stomee    consumer.setOption(Option.aggrate, Option.millis(500)); // every half second
327fb3fb4f3Stomee</tt></pre>
328fb3fb4f3Stomee<br>
329fb3fb4f3StomeeEven a single drop terminates the consumer unless you override the <a
330fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/ConsumerAdapter.html#dataDropped%28org.opensolaris.os.dtrace.DropEvent%29">
331fb3fb4f3Stomee<tt>dataDropped()</tt></a> method of <tt>ConsumerAdapter</tt> to handle
332fb3fb4f3Stomeedrops differently.  To avoid drops, it is probably better to increase
333fb3fb4f3Stomeethe <tt>aggsize</tt> option, since increasing the <tt>aggrate</tt> makes
334fb3fb4f3Stomeethe consumer work harder.  In most cases, the <tt>aggrate</tt> should
335fb3fb4f3Stomeeonly be increased when you need to update a display of aggregation data
336fb3fb4f3Stomeemore frequently than once per second.  Many runtime options, including
337fb3fb4f3Stomee<tt>aggrate</tt>, can be changed dynamically while the consumer is
338fb3fb4f3Stomeerunning.<br>
339fb3fb4f3Stomee<br>
340fb3fb4f3StomeeIt's also worth mentioning that a D aggregation may omit square
341fb3fb4f3Stomeebrackets and aggregate only a single value:
342fb3fb4f3Stomee<pre><tt>
343fb3fb4f3Stomee    @total = count();
344fb3fb4f3Stomee</tt></pre>
345fb3fb4f3Stomee<br>
346fb3fb4f3StomeeThe resulting singleton <a
347fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/Aggregation.html">
34891cfa10aStomee<tt>Aggregation</tt></a> has one record that may be obtained as follows:
349fb3fb4f3Stomee<pre><tt>
350fb3fb4f3Stomee    Aggregate a = consumer.getAggregate();
351fb3fb4f3Stomee    Aggregation total = a.getAggregation("total");
352fb3fb4f3Stomee    AggregationRecord totalRecord = total.getRecord(Tuple.EMPTY);
353fb3fb4f3Stomee</tt></pre>
354fb3fb4f3Stomee<br>
355fb3fb4f3Stomee<h2><a name="Target_Process"></a>Target Process ID</h2>
356fb3fb4f3StomeeIn addition to supporting macro arguments (see the <tt>syscall.d</tt>
357fb3fb4f3Stomeeaggregation example above), the Java DTrace API also supports the
358fb3fb4f3Stomee<tt>$target</tt> macro variable.  (See the <a
3593a931819SPeter Tribblehref=http://dtrace.org/guide/chp-script.html#chp-script-4>
360fb3fb4f3Stomee<b>Target Process ID</b></a> section of the <b>Scripting</b> chapter of
3613a931819SPeter Tribblethe <i>Dynamic Tracing Guide</i>.)  This allows you to trace a
362fb3fb4f3Stomeeprocess from the very beginning of its execution, rather than sometime
363fb3fb4f3Stomeeafter you manually obtain its process ID.  The API does this by creating
364fb3fb4f3Stomeea process that is initially suspended and allowed to start only after <a
365fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#go%28%29">
36691cfa10aStomee<tt>go()</tt></a> has initiated tracing.  For example, you can aggregate
36791cfa10aStomeeall the system calls from start to finish made by the <tt>date</tt>
36891cfa10aStomeecommand:<br>
369fb3fb4f3Stomee<b>D script (<a href="../examples/target.d">target.d</a>)</b>
370fb3fb4f3Stomee<pre><tt>
371fb3fb4f3Stomee    syscall:::entry
372fb3fb4f3Stomee    / pid == $target /
373fb3fb4f3Stomee    {
374fb3fb4f3Stomee	    @[probefunc] = count();
375fb3fb4f3Stomee    }
376fb3fb4f3Stomee</tt></pre>
377fb3fb4f3Stomee<br>
378fb3fb4f3StomeeA modified version of the <tt>TestAPI.java</tt> program adds the <a
379fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#createProcess%28java.lang.String%29">
380fb3fb4f3Stomee<tt>createProcess()</tt></a> call to execute the given command but
381fb3fb4f3Stomeeprevent it from starting until the consumer is running:<br>
382fb3fb4f3Stomee<b>Java program (<a href="../examples/TestTarget.java">TestTarget.java</a>)</b>
383fb3fb4f3Stomee<pre><tt><font color=#aaaaaa>
384fb3fb4f3Stomee    ...
385fb3fb4f3Stomee    consumer.open();</font>
386fb3fb4f3Stomee    consumer.createProcess(command);<font color=#aaaaaa>
387fb3fb4f3Stomee    consumer.compile(file);
388fb3fb4f3Stomee    consumer.enable();
389fb3fb4f3Stomee    consumer.go();
390fb3fb4f3Stomee    ...</font>
391fb3fb4f3Stomee</tt></pre>
392fb3fb4f3Stomee<br>
393fb3fb4f3StomeeIt also overrides the <a
394fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/ConsumerAdapter.html#processStateChanged%28org.opensolaris.os.dtrace.ProcessEvent%29">
395fb3fb4f3Stomee<tt>processStateChanged()</tt></a> method of the
396fb3fb4f3Stomee<tt>ConsumerAdapter</tt> to print a notification when the process has
397fb3fb4f3Stomeeended:
398fb3fb4f3Stomee<pre><tt><font color=#aaaaaa>
399fb3fb4f3Stomee    ...
400fb3fb4f3Stomee    consumer.addConsumerListener(new ConsumerAdapter() {
401fb3fb4f3Stomee	public void dataReceived(DataEvent e) {
402fb3fb4f3Stomee	    System.out.println(e.getProbeData());
403fb3fb4f3Stomee	}
404fb3fb4f3Stomee	public void consumerStopped(ConsumerEvent e) {
405fb3fb4f3Stomee	    try {
406fb3fb4f3Stomee		Aggregate a = consumer.getAggregate();
407fb3fb4f3Stomee		for (Aggregation agg : a.asMap().values()) {
408fb3fb4f3Stomee		    for (AggregationRecord rec : agg.asMap().values()) {
409fb3fb4f3Stomee			System.out.println(rec.getTuple() + " " +
410fb3fb4f3Stomee				rec.getValue());
411fb3fb4f3Stomee		    }
412fb3fb4f3Stomee		}
413fb3fb4f3Stomee	    } catch (Exception x) {
414fb3fb4f3Stomee		x.printStackTrace();
415fb3fb4f3Stomee		System.exit(1);
416fb3fb4f3Stomee	    }
417fb3fb4f3Stomee	    consumer.close();
418fb3fb4f3Stomee	}</font>
419fb3fb4f3Stomee	public void processStateChanged(ProcessEvent e) {
420fb3fb4f3Stomee	    System.out.println(e.getProcessState());
421fb3fb4f3Stomee	}<font color=#aaaaaa>
422fb3fb4f3Stomee    });
423fb3fb4f3Stomee    ...</font>
424fb3fb4f3Stomee</tt></pre>
425fb3fb4f3Stomee<br>
426fb3fb4f3StomeeCompile and run:
427fb3fb4f3Stomee<pre><tt>
42891cfa10aStomee    javac -cp /usr/share/lib/java/dtrace.jar TestTarget.java
429fb3fb4f3Stomee</tt></pre>
430fb3fb4f3Stomee<pre><tt>
43191cfa10aStomee    java -cp .:/usr/share/lib/java/dtrace.jar TestTarget target.d date
432fb3fb4f3Stomee</tt></pre>
433fb3fb4f3Stomee<br>
434fb3fb4f3StomeeThe consumer exits automatically when the target <tt>date</tt> process
435fb3fb4f3Stomeecompletes.<br>
436fb3fb4f3Stomee<h2><a name="Closing_Consumers"></a>Closing Consumers</h2>
437fb3fb4f3StomeeAn application using the Java DTrace API may run multiple consumers
438fb3fb4f3Stomeesimultaneously.  When a consumer stops running, the programmer is
439fb3fb4f3Stomeeresponsible for closing it in order to release the system resources it
440fb3fb4f3Stomeeholds.  A consumer may stop running for any of the following reasons:
441fb3fb4f3Stomee<ul>
442fb3fb4f3Stomee  <li>It was stopped explicitly by a call to its <a
443fb3fb4f3Stomeehref=../api/org/opensolaris/os/dtrace/Consumer.html#stop()>
444fb3fb4f3Stomee<tt>stop()</tt></a> method</li>
445fb3fb4f3Stomee  <li>It encountered the <tt>exit()</tt> action</li>
446fb3fb4f3Stomee  <li>Its <tt>$target</tt> process or processes (if any) all completed</li>
447fb3fb4f3Stomee  <li>It encountered an exception</li>
448fb3fb4f3Stomee</ul>
449fb3fb4f3StomeeBy default, an exception prints a stack trace to <tt>stderr</tt> before
450fb3fb4f3Stomeenotifying listeners that the consumer has stopped.  You can define
451fb3fb4f3Stomeedifferent behavior by setting an <a
452fb3fb4f3Stomeehref=../api/org/opensolaris/os/dtrace/ExceptionHandler.html>
453fb3fb4f3Stomee<tt>ExceptionHandler</tt></a>, but the consumer is still stopped.<br>
454fb3fb4f3Stomee<br>
455fb3fb4f3StomeeThe same listener that receives probe data generated by DTrace is also
456fb3fb4f3Stomeenotified when the consumer stops.  This is a good place to close the
457fb3fb4f3Stomeeconsumer:
458fb3fb4f3Stomee<pre><tt><font color=#aaaaaa>
459fb3fb4f3Stomee    consumer.addConsumerListener(new ConsumerAdapter() {
460fb3fb4f3Stomee	public void dataReceived(DataEvent e) {
461fb3fb4f3Stomee	    System.out.println(e.getProbeData());
462fb3fb4f3Stomee	}</font>
463fb3fb4f3Stomee	public void consumerStopped(ConsumerEvent e) {
464fb3fb4f3Stomee	    Consumer consumer = (Consumer)e.getSource();
465fb3fb4f3Stomee		consumer.close();
466fb3fb4f3Stomee	    }
467fb3fb4f3Stomee	}<font color=#aaaaaa>
468fb3fb4f3Stomee    });</font>
469fb3fb4f3Stomee</tt></pre>
470fb3fb4f3Stomee<br>
471fb3fb4f3StomeeThis releases the resources held by the consumer in all cases, i.e.
472fb3fb4f3Stomeeafter it exits for <i>any</i> of the reasons listed above.<br>
473fb3fb4f3Stomee<br>
474fb3fb4f3StomeeYou can request the last aggregate snapshot made by a stopped consumer,
475fb3fb4f3Stomeeas long as it has not yet been closed:
476fb3fb4f3Stomee<pre><tt>
477fb3fb4f3Stomee    Aggregate a = consumer.getAggregate();
478fb3fb4f3Stomee</tt></pre>
479fb3fb4f3Stomee<br>
480fb3fb4f3StomeeNote however that any aggregation that has already appeared in a <a
481fb3fb4f3Stomeehref=../api/org/opensolaris/os/dtrace/PrintaRecord.html>
482fb3fb4f3Stomee<tt>PrintaRecord</tt></a> as a result of the <tt>printa()</tt> action
483fb3fb4f3Stomeeaction will not be included in the requested aggregate.
484fb3fb4f3Stomee<h2><a name="Learning_DTrace"></a>Learning More</h2>
485fb3fb4f3Stomee<br>
4863a931819SPeter TribbleThe <a href="http://dtrace.org/">
4873a931819SPeter TribbleDTrace page</a> has links to resources to help you learn
488fb3fb4f3StomeeDTrace.  In particular, you should read the <a
4893a931819SPeter Tribblehref="http://dtrace.org/guide/"><i>Dynamic Tracing
490fb3fb4f3Stomee    Guide</i></a>.<br>
491fb3fb4f3Stomee<br>
492fb3fb4f3StomeeTry the example Java programs on this page with other D scripts.  You
493fb3fb4f3Stomeeneed not remove <tt>#!/usr/sbin/dtrace -s</tt> from the top of an
494fb3fb4f3Stomeeexecutable script.  You may want to remove <tt>profile:::tick*</tt>
495fb3fb4f3Stomeeclauses if you plan to use the <tt>Consumer</tt> <a
496fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#getAggregate%28%29">
49791cfa10aStomee<tt>getAggregate()</tt></a> method and control the data interval
498fb3fb4f3Stomeeprogrammatically.  If the script uses the pre-compiler, you will need to
499fb3fb4f3Stomeecall the <tt>Consumer</tt> <a
500fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/Consumer.html#setOption%28java.lang.String%29">
501fb3fb4f3Stomee<tt>setOption()</tt></a> method with the <a
502fb3fb4f3Stomeehref="../api/org/opensolaris/os/dtrace/Option.html#cpp">
503fb3fb4f3Stomee<tt>Option.cpp</tt></a> argument.<br>
504fb3fb4f3Stomee<br>
505fb3fb4f3StomeeTo quickly familiarize yourself with the Java DTrace API, take a look at
506fb3fb4f3Stomeethe overview <a href="JavaDTraceAPI.html">diagram</a>.<br>
507fb3fb4f3Stomee<br>
508fb3fb4f3Stomee<a href="#Quick_Start_Guide_to_the_Java_DTrace_API_">Back to top</a><br>
509fb3fb4f3Stomee<br>
510fb3fb4f3Stomee</body>
511fb3fb4f3Stomee</html>
512