da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<!--
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw Copyright 2007 Sun Microsystems, Inc. All rights reserved.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw Use is subject to license terms.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ident "%Z%%M% %I% %E% SMI"
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw CDDL HEADER START
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw The contents of this file are subject to the terms of the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw Common Development and Distribution License (the "License").
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw You may not use this file except in compliance with the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw or http://www.opensolaris.org/os/licensing.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw See the License for the specific language governing permissions
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw and limitations under the License.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw When distributing Covered Code, include this CDDL HEADER in each
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw file and include the License file at usr/src/OPENSOLARIS.LICENSE.
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw If applicable, add the following below this CDDL HEADER, with the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw fields enclosed by brackets "[]" replaced with your own identifying
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego information: Portions Copyright [yyyy] [name of copyright owner]
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw CDDL HEADER END
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw-->
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<html>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<head>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <meta content="text/html; charset=ISO-8859-1" http-equiv="content-type">
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <title>Quick Start Guide to the Java DTrace API</title>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw</head>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<body>
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan Wright<h1><a name="Quick_Start_Guide_to_the_Java_DTrace_API_"></a>Quick Start
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwGuide</h1>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<h1><small><small>to the</small> Java DTrace API</small></h1>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<hr style="width: 100%; height: 2px;">
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<h2>Contents</h2>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<ul>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li><a href="#Hello_World">"hello, world" Example</a></li>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <ul>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li><a href="#Writing_a_Simple_Consumer">Writing a Simple Consumer</a></li>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb <li><a href="#Running_hello.d_Script">Running the <tt>hello.d</tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb Script</a></li>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb </ul>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li><a href="#Aggregations">Aggregations</a></li>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw <li><a href="#Target_Process">Target Process ID</a></li>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb <li><a href="#Closing_Consumers">Closing Consumers</a></li>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb <li><a href="#Learning_DTrace">Learning More</a><br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb </li>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb</ul>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<h2><a name="Hello_World"></a>"hello, world" Example</h2>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwTo demonstrate how to use the Java DTrace API, let's write a simple Java
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbprogram that runs a D script, in this case <tt>hello.d</tt> (prints
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb"hello, world" and exits). You will need root permission to use the
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbJava DTrace API (just as you do to use the <tt>dtrace(1M)</tt> command).
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbYou may want to eliminate this inconvenience by adding the following
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbline to <tt>/etc/user_attr</tt>:
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<tt><i>user-name</i>::::defaultpriv=basic,dtrace_kernel,dtrace_proc</tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego<i>(Substitute your user name.)</i> See the <a
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbhref=http://docs.sun.com/app/docs/doc/817-6223/6mlkidln0?a=view>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<b>Security</b></a> chapter of the <i>Solaris Dynamic Tracing Guide</i>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbfor more information.
c8ec8eea9849cac239663c46be8a7f5d2ba7ca00jose borrego<br>
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego<h4><a name="Writing_a_Simple_Consumer"></a>Writing a Simple Consumer</h4>
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregoCreating a DTrace <a
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregohref="/api/org/opensolaris/os/dtrace/Consumer.html">consumer</a>
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borregois easy:
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego<pre><tt>
2c2961f8403049d948b9f3e6c35d6488b6b7e1aajose borrego Consumer consumer = new LocalConsumer();
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb</tt></pre>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbBefore you can do anything with the consumer, you must first open it.
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbThen you simply compile and enable one or more D programs and run it:
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<pre><tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb consumer.open();
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb consumer.compile(program);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.enable();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.go(); // runs in a background thread
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw</tt></pre>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwTo get the data generated by DTrace, you also need to add a <a
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwhref="/api/org/opensolaris/os/dtrace/ConsumerListener.html">listener</a>:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<pre><tt>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.addConsumerListener(new ConsumerAdapter() {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw public void dataReceived(DataEvent e) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw System.out.println(e.getProbeData());
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw });
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw</tt></pre>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwHere is a simple example that runs a given D script:<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<b>Java program (<a href="/examples/TestAPI.java">TestAPI.java</a>)</b>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<pre><tt><font color=#aaaaaa>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw import org.opensolaris.os.dtrace.*;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw import java.io.File;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw public class TestAPI {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw public static void
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw main(String[] args)
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (args.length &lt; 1) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw System.err.println("Usage: java TestAPI &lt;script&gt; [ macroargs... ]");
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw System.exit(2);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw File file = new File(args[0]);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw String[] macroArgs = new String[args.length - 1];
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw System.arraycopy(args, 1, macroArgs, 0, (args.length - 1));</font>
193974072f41a843678abf5f61979c748687e66bSherry Moore
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw Consumer consumer = new LocalConsumer();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.addConsumerListener(new ConsumerAdapter() {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw public void dataReceived(DataEvent e) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw System.out.println(e.getProbeData());
193974072f41a843678abf5f61979c748687e66bSherry Moore }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw });
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<font color=#aaaaaa>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw try {</font>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.open();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.compile(file, macroArgs);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.enable();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.go();<font color=#aaaaaa>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } catch (Exception e) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw e.printStackTrace();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw System.exit(1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }</font>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb</tt></pre>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwCompile the test program as follows:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<pre><tt>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw javac -cp /usr/share/lib/java/dtrace.jar TestAPI.java
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw</tt></pre>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<br>
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego<h4><a name="Running_hello.d_Script"></a>Running the <tt>hello.d</tt> Script</h4>
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borregoNow we need a D script for the program to run. The following is a
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borregosimple example that prints "hello, world" and exits:<br>
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego<b>D script (<a href="/examples/hello.d">hello.d</a>)</b>
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego<pre><tt>
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego dtrace:::BEGIN
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego {
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego trace("hello, world");
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego exit(0);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw</tt></pre>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwRun as follows:<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<pre><tt>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw java -cp .:/usr/share/lib/java/dtrace.jar TestAPI hello.d
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw</tt></pre>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwThe output should look like this:
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<pre><tt>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw org.opensolaris.os.dtrace.ProbeData[epid = 1, cpu = 1,
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego enabledProbeDescription = dtrace:::BEGIN, flow = null, records =
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego ["hello, world", 0]]
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego</tt></pre>
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego<br>
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borregoThere is one record in the <a
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borregohref="/api/org/opensolaris/os/dtrace/ProbeData.html"><tt>ProbeData</tt></a>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwfor each action in the D script. The first record is generated by the
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<tt>trace()</tt> action. The second is generated by the <tt>exit()</tt>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwaction. For prettier output, you could change the <tt>ConsumerAdapter <a
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb href="/api/org/opensolaris/os/dtrace/ConsumerAdapter.html#dataReceived%28org.opensolaris.os.dtrace.DataEvent%29">dataReceived()</a></tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbimplementation as follows:
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<pre><tt><font color=#aaaaaa>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.addConsumerListener(new ConsumerAdapter() {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw public void dataReceived(DataEvent e) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw // System.out.println(e.getProbeData());</font>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ProbeData data = e.getProbeData();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw java.util.List &lt; Record &gt; records = data.getRecords();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw for (Record r : records) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw if (r instanceof ExitRecord) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } else {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb System.out.println(r);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }<font color=#aaaaaa>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw });</font>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw</tt></pre>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<h2><a name="Aggregations"></a>Aggregations</h2>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwThe example Java program can just as easily run a more complex script,
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwsuch as an aggregation:<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<b>D script (<a href="/examples/syscall.d">syscall.d</a>)</b>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<pre><tt>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw syscall:::entry
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb / execname == $$1 /
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw @[probefunc] = count();
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb profile:::tick-1sec
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw printa(@);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb clear(@);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan Wright</tt></pre>
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan Wright<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwThe above script uses the <tt>$$1</tt> macro variable as a placeholder
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbfor whatever executable you'd like to trace. See the <a
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbhref=http://docs.sun.com/app/docs/doc/817-6223/6mlkidliq?a=view><b>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbMacro Arguments</b></a> section of the <b>Scripting</b> chapter of the
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan Wright<i>Solaris Dynamic Tracing Guide</i>. Using two dollar signs (<tt>$$1</tt>)
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan Wrightinstead of one (<tt>$1</tt>) forces expansion of the macro variable to
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan Wrighttype string.<br>
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan Wright<br>
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan WrightTo run the example Java program using the above D script, you need to
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan Wrightspecify an argument to the <tt>execname</tt> placeholder, such as
94fff7907278e4540aa7abee2b1b0ea71d36f7faAlan Wright"java":<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<pre><tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb java -cp .:/usr/share/lib/java/dtrace.jar TestAPI syscall.d java
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb</tt></pre>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbA data record generated by the <tt>printa()</tt> action is printed to
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbthe console once every second. It contains counts of system calls by
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbfunction name made by java. No record is generated by the
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<tt>clear()</tt> action.<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbIf you omit the argument to the <tt>execname</tt> placeholder, the
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbprogram fails to compile and the API throws the following exception:
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<pre><tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb org.opensolaris.os.dtrace.DTraceException: failed to compile script
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb syscall.d: line 2: macro argument $$1 is not defined
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb at org.opensolaris.os.dtrace.LocalConsumer._compileFile(Native Method)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb at org.opensolaris.os.dtrace.LocalConsumer.compile(LocalConsumer.java:342)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb at TestAPI.main(TestAPI.java:26)
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb</tt></pre>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbA DTrace script may have more than one aggregation. In that case, each
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbaggregation needs a distinct name:<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<b>D script (<a href="/examples/intrstat.d">intrstat.d</a>)</b>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<pre><tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sdt:::interrupt-start
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb self-&gt;ts = vtimestamp;
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb sdt:::interrupt-complete
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw / self-&gt;ts &amp;&amp; arg0 /
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw this-&gt;devi = (struct dev_info *)arg0;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb @counts[stringof(`devnamesp[this-&gt;devi-&gt;devi_major].dn_name),
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb this-&gt;devi-&gt;devi_instance, cpu] = count();
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb @times[stringof(`devnamesp[this-&gt;devi-&gt;devi_major].dn_name),
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw this-&gt;devi-&gt;devi_instance, cpu] = sum(vtimestamp - self-&gt;ts);
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb self-&gt;ts = 0;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb }
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw</tt></pre>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbThe <tt>@counts</tt> and <tt>@times</tt> aggregations both accumulate
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbvalues for each unique combination of device name, device instance, and
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbCPU (a three-element tuple). In this example we drop the <tt>tick</tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbprobe to demonstrate a more convenient way to get aggregation data
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbwithout the use of the <tt>printa()</tt> action. The <a
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borregohref="/api/org/opensolaris/os/dtrace/Consumer.html#getAggregate%28%29">
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego<tt>getAggregate()</tt></a> method allows us to get a read-consistent
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbsnapshot of all aggregations at once on a programmatic interval.<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<b>Java program (<a href="/examples/TestAPI2.java">TestAPI2.java</a>)</b>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<pre><tt><font color=#aaaaaa>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb ...
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw try {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb consumer.open();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.compile(file, macroArgs);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.enable();
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw consumer.go();</font>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw Aggregate a;
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb do {
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb Thread.sleep(1000); // 1 second
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego a = consumer.getAggregate();
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego if (!a.asMap().isEmpty()) {
f9a15d2c042edba37d61b071eb7ea274eb2754d1jose borrego System.out.println(a);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb } while (consumer.isRunning());<font color=#aaaaaa>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw } catch (Exception e) {
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw e.printStackTrace();
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb System.exit(1);
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw }
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw ...</font>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb</tt></pre>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jbCompile and run:
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<pre><tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb javac -cp /usr/share/lib/java/dtrace.jar TestAPI2.java
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb</tt></pre>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<pre><tt>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb java -cp .:/usr/share/lib/java/dtrace.jar TestAPI2 intrstat.d
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb</tt></pre>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwTry removing the <tt>tick</tt> probe from the <tt>syscall.d</tt> example
faa1795a28a5c712eed6d0a3f84d98c368a316c6jband running it again with the above modification (<tt>TestAPI2</tt>).<br>
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb<br>
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwBy default, the requested aggregate includes every aggregation and
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amwaccumulates running totals. To display values per time interval
faa1795a28a5c712eed6d0a3f84d98c368a316c6jb(instead of running totals), clear the aggregations each time you call
da6c28aaf62fa55f0fdb8004aa40f88f23bf53f0amw<tt>getAggregate()</tt>. Clearing an aggregation resets all counts to
zero without removing any elements. The following modification to the
example above clears all aggregations:
<pre><tt><font color=#aaaaaa>
// a = consumer.getAggregate();</font>
a = consumer.getAggregate(null, null); // included, cleared
</tt></pre>
<br>
Each <tt>Set</tt> of aggregation names, <tt>included</tt> and
<tt>cleared</tt>, specifies <i>all</i> aggregations if <tt>null</tt> and
no aggregations if empty. Any subset is possible. However, if an
aggregation has ever been used in the <tt>printa()</tt> action, it is no
longer available to the <tt>getAggregate()</tt> method.<br>
<br>
Be aware that you cannot call <tt>getAggregate()</tt> on an interval
faster that the <tt>aggrate</tt> setting. See the <a
href=http://docs.sun.com/app/docs/doc/817-6223/6mlkidlis?a=view>
<b>Options and Tunables</b></a> chapter of the <i>Solaris Dynamic
Tracing Guide</i>. See also the <a
href=http://docs.sun.com/app/docs/doc/817-6223/6mlkidlhf?a=view>
<b>Minimizing Drops</b></a> section of the <b>Aggregations</b> chapter
for specific information about the <tt>aggrate</tt> option. The default
<tt>aggrate</tt> is once per second. Here's an example of how you might
double the <tt>aggrate</tt> to minimize drops:
<pre><tt>
consumer.setOption(Option.aggrate, Option.millis(500)); // every half second
</tt></pre>
<br>
Even a single drop terminates the consumer unless you override the <a
href="/api/org/opensolaris/os/dtrace/ConsumerAdapter.html#dataDropped%28org.opensolaris.os.dtrace.DropEvent%29">
<tt>dataDropped()</tt></a> method of <tt>ConsumerAdapter</tt> to handle
drops differently. To avoid drops, it is probably better to increase
the <tt>aggsize</tt> option, since increasing the <tt>aggrate</tt> makes
the consumer work harder. In most cases, the <tt>aggrate</tt> should
only be increased when you need to update a display of aggregation data
more frequently than once per second. Many runtime options, including
<tt>aggrate</tt>, can be changed dynamically while the consumer is
running.<br>
<br>
It's also worth mentioning that a D aggregation may omit square
brackets and aggregate only a single value:
<pre><tt>
@total = count();
</tt></pre>
<br>
The resulting singleton <a
href="/api/org/opensolaris/os/dtrace/Aggregation.html">
<tt>Aggregation</tt></a> has one record that may be obtained as follows:
<pre><tt>
Aggregate a = consumer.getAggregate();
Aggregation total = a.getAggregation("total");
AggregationRecord totalRecord = total.getRecord(Tuple.EMPTY);
</tt></pre>
<br>
<h2><a name="Target_Process"></a>Target Process ID</h2>
In addition to supporting macro arguments (see the <tt>syscall.d</tt>
aggregation example above), the Java DTrace API also supports the
<tt>$target</tt> macro variable. (See the <a
href=http://docs.sun.com/app/docs/doc/817-6223/6mlkidlir?a=view>
<b>Target Process ID</b></a> section of the <b>Scripting</b> chapter of
the <i>Solaris Dynamic Tracing Guide</i>.) This allows you to trace a
process from the very beginning of its execution, rather than sometime
after you manually obtain its process ID. The API does this by creating
a process that is initially suspended and allowed to start only after <a
href="/api/org/opensolaris/os/dtrace/Consumer.html#go%28%29">
<tt>go()</tt></a> has initiated tracing. For example, you can aggregate
all the system calls from start to finish made by the <tt>date</tt>
command:<br>
<b>D script (<a href="/examples/target.d">target.d</a>)</b>
<pre><tt>
syscall:::entry
/ pid == $target /
{
@[probefunc] = count();
}
</tt></pre>
<br>
A modified version of the <tt>TestAPI.java</tt> program adds the <a
href="/api/org/opensolaris/os/dtrace/Consumer.html#createProcess%28java.lang.String%29">
<tt>createProcess()</tt></a> call to execute the given command but
prevent it from starting until the consumer is running:<br>
<b>Java program (<a href="/examples/TestTarget.java">TestTarget.java</a>)</b>
<pre><tt><font color=#aaaaaa>
...
consumer.open();</font>
consumer.createProcess(command);<font color=#aaaaaa>
consumer.compile(file);
consumer.enable();
consumer.go();
...</font>
</tt></pre>
<br>
It also overrides the <a
href="/api/org/opensolaris/os/dtrace/ConsumerAdapter.html#processStateChanged%28org.opensolaris.os.dtrace.ProcessEvent%29">
<tt>processStateChanged()</tt></a> method of the
<tt>ConsumerAdapter</tt> to print a notification when the process has
ended:
<pre><tt><font color=#aaaaaa>
...
consumer.addConsumerListener(new ConsumerAdapter() {
public void dataReceived(DataEvent e) {
System.out.println(e.getProbeData());
}
public void consumerStopped(ConsumerEvent e) {
try {
Aggregate a = consumer.getAggregate();
for (Aggregation agg : a.asMap().values()) {
for (AggregationRecord rec : agg.asMap().values()) {
System.out.println(rec.getTuple() + " " +
rec.getValue());
}
}
} catch (Exception x) {
x.printStackTrace();
System.exit(1);
}
consumer.close();
}</font>
public void processStateChanged(ProcessEvent e) {
System.out.println(e.getProcessState());
}<font color=#aaaaaa>
});
...</font>
</tt></pre>
<br>
Compile and run:
<pre><tt>
javac -cp /usr/share/lib/java/dtrace.jar TestTarget.java
</tt></pre>
<pre><tt>
java -cp .:/usr/share/lib/java/dtrace.jar TestTarget target.d date
</tt></pre>
<br>
The consumer exits automatically when the target <tt>date</tt> process
completes.<br>
<h2><a name="Closing_Consumers"></a>Closing Consumers</h2>
An application using the Java DTrace API may run multiple consumers
simultaneously. When a consumer stops running, the programmer is
responsible for closing it in order to release the system resources it
holds. A consumer may stop running for any of the following reasons:
<ul>
<li>It was stopped explicitly by a call to its <a
href=/api/org/opensolaris/os/dtrace/Consumer.html#stop()>
<tt>stop()</tt></a> method</li>
<li>It encountered the <tt>exit()</tt> action</li>
<li>Its <tt>$target</tt> process or processes (if any) all completed</li>
<li>It encountered an exception</li>
</ul>
By default, an exception prints a stack trace to <tt>stderr</tt> before
notifying listeners that the consumer has stopped. You can define
different behavior by setting an <a
href=/api/org/opensolaris/os/dtrace/ExceptionHandler.html>
<tt>ExceptionHandler</tt></a>, but the consumer is still stopped.<br>
<br>
The same listener that receives probe data generated by DTrace is also
notified when the consumer stops. This is a good place to close the
consumer:
<pre><tt><font color=#aaaaaa>
consumer.addConsumerListener(new ConsumerAdapter() {
public void dataReceived(DataEvent e) {
System.out.println(e.getProbeData());
}</font>
public void consumerStopped(ConsumerEvent e) {
Consumer consumer = (Consumer)e.getSource();
consumer.close();
}
}<font color=#aaaaaa>
});</font>
</tt></pre>
<br>
This releases the resources held by the consumer in all cases, i.e.
after it exits for <i>any</i> of the reasons listed above.<br>
<br>
You can request the last aggregate snapshot made by a stopped consumer,
as long as it has not yet been closed:
<pre><tt>
Aggregate a = consumer.getAggregate();
</tt></pre>
<br>
Note however that any aggregation that has already appeared in a <a
href=/api/org/opensolaris/os/dtrace/PrintaRecord.html>
<tt>PrintaRecord</tt></a> as a result of the <tt>printa()</tt> action
action will not be included in the requested aggregate.
<h2><a name="Learning_DTrace"></a>Learning More</h2>
<br>
The <a href="http://www.opensolaris.org/os/community/dtrace/">
OpenSolaris DTrace page</a> has links to resources to help you learn
DTrace. In particular, you should read the <a
href="http://docs.sun.com/app/docs/doc/817-6223"><i>Solaris Dynamic Tracing
Guide</i></a>.<br>
<br>
Try the example Java programs on this page with other D scripts. You
need not remove <tt>#!/usr/sbin/dtrace -s</tt> from the top of an
executable script. You may want to remove <tt>profile:::tick*</tt>
clauses if you plan to use the <tt>Consumer</tt> <a
href="/api/org/opensolaris/os/dtrace/Consumer.html#getAggregate%28%29">
<tt>getAggregate()</tt></a> method and control the data interval
programmatically. If the script uses the pre-compiler, you will need to
call the <tt>Consumer</tt> <a
href="/api/org/opensolaris/os/dtrace/Consumer.html#setOption%28java.lang.String%29">
<tt>setOption()</tt></a> method with the <a
href="/api/org/opensolaris/os/dtrace/Option.html#cpp">
<tt>Option.cpp</tt></a> argument.<br>
<br>
To quickly familiarize yourself with the Java DTrace API, take a look at
the overview <a href="JavaDTraceAPI.html">diagram</a>.<br>
<br>
<a href="#Quick_Start_Guide_to_the_Java_DTrace_API_">Back to top</a><br>
<br>
</body>
</html>