1 /*******************************************************************************
2 * Copyright (c) 2009 Ericsson
4 * All rights reserved. This program and the accompanying materials are
5 * made available under the terms of the Eclipse Public License v1.0 which
6 * accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * William Bourque (wbourque@gmail.com) - Initial API and implementation
11 *******************************************************************************/
13 package org
.eclipse
.linuxtools
.lttng
.trace
;
15 import org
.eclipse
.linuxtools
.lttng
.LttngException
;
16 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEvent
;
17 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEventContent
;
18 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEventField
;
19 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEventFormat
;
20 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEventReference
;
21 import org
.eclipse
.linuxtools
.lttng
.event
.LttngEventType
;
22 import org
.eclipse
.linuxtools
.lttng
.event
.LttngTimestamp
;
23 import org
.eclipse
.linuxtools
.lttng
.jni
.JniEvent
;
24 import org
.eclipse
.linuxtools
.lttng
.jni
.JniTime
;
25 import org
.eclipse
.linuxtools
.lttng
.jni
.JniTrace
;
26 import org
.eclipse
.linuxtools
.tmf
.event
.TmfEvent
;
27 import org
.eclipse
.linuxtools
.tmf
.event
.TmfEventSource
;
28 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimeRange
;
29 import org
.eclipse
.linuxtools
.tmf
.event
.TmfTimestamp
;
30 import org
.eclipse
.linuxtools
.tmf
.trace
.TmfTrace
;
31 import org
.eclipse
.linuxtools
.tmf
.trace
.TmfTraceContext
;
34 class LTTngTraceException
extends LttngException
{
35 static final long serialVersionUID
= -1636648737081868146L;
37 public LTTngTraceException(String errMsg
) {
43 * <b><u>LTTngTrace</u></b>
45 * LTTng trace implementation. It accesses the C trace handling library
46 * (seeking, reading and parsing) through the JNI component.
48 public class LTTngTrace
extends TmfTrace
{
50 private final static boolean IS_PARSING_NEEDED_DEFAULT
= true;
51 private final static int CHECKPOINT_PAGE_SIZE
= 1000;
53 // Reference to the current LttngEvent
54 private LttngEvent currentLttngEvent
= null;
56 // Reference to our JNI trace
57 private JniTrace currentJniTrace
= null;
62 * @param path Path to a <b>directory</b> that contain an LTTng trace.
64 * @exception Exception Trace opening failed (most likely FileNotFoundException)
66 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
68 public LTTngTrace(String path
) throws Exception
{
73 * Default constructor, with control over the indexing
75 * @param path Path to a <b>directory</b> that contain an LTTng trace.
76 * @param waitForCompletion Should we wait for indexign to complete before moving on.
78 * @exception Exception Trace opening failed (most likely FileNotFoundException)
80 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
82 public LTTngTrace(String path
, boolean waitForCompletion
) throws Exception
{
83 super(path
, CHECKPOINT_PAGE_SIZE
, waitForCompletion
);
85 currentJniTrace
= new JniTrace(path
);
88 throw new LTTngTraceException(e
.getMessage());
90 TmfTimestamp startTime
= new LttngTimestamp(currentJniTrace
.getStartTimeFromTimestampCurrentCounter().getTime());
91 setTimeRange(new TmfTimeRange(startTime
, startTime
));
96 * Copy constructor is forbidden for LttngEvenmStream
98 * Events are only valid for a very limited period of time and
99 * JNI library does not support multiple access at once (yet?).
100 * For this reason, copy constructor should NEVER be used here.
102 private LTTngTrace(LTTngTrace oldStream
) throws Exception
{
104 throw new Exception("Copy constructor should never be use with a LTTngTrace!");
108 * Parse the next event in the trace
110 * @return TmfEvent The parsed event, or null if none available.
113 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
116 public TmfEvent
parseEvent(TmfTraceContext context
) {
119 LttngTimestamp timestamp
= null;
121 synchronized (currentJniTrace
) {
122 seekLocation(context
.getLocation());
123 jniEvent
= currentJniTrace
.readNextEvent();
124 currentLttngEvent
= (jniEvent
!= null) ?
convertJniEventToTmf(jniEvent
, true) : null;
125 timestamp
= (LttngTimestamp
) getCurrentLocation();
127 context
.setLocation(timestamp
);
128 context
.setTimestamp(timestamp
);
131 return currentLttngEvent
;
135 * Method to convert a JniEvent into a LttngEvent.<br>
137 * Note : This method will call LttngEvent convertEventJniToTmf(JniEvent, boolean)
138 * with a default value for isParsingNeeded
140 * @param newEvent The JniEvent to convert
142 * @return LttngEvent The converted event
144 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
146 public LttngEvent
convertJniEventToTmf(JniEvent newEvent
) {
147 LttngEvent event
= null;
148 if (newEvent
!= null)
149 event
= convertJniEventToTmf(newEvent
, IS_PARSING_NEEDED_DEFAULT
);
154 * Method tp convert a JniEvent into a LttngEvent
156 * @param jniEvent The JniEvent to convert
157 * @param isParsingNeeded A boolean value telling if the event should be parsed or not.
159 * @return LttngEvent The converted event
161 * @see org.eclipse.linuxtools.lttng.jni.JniEvent
163 public LttngEvent
convertJniEventToTmf(JniEvent jniEvent
, boolean isParsingNeeded
) {
166 // Format seems weird to me... we need to revisit Format/Fields/Content to find a better ways
169 String
[] labels
= new String
[jniEvent
.requestEventMarker().getMarkerFieldsHashMap().size()];
170 labels
= jniEvent
.requestEventMarker().getMarkerFieldsHashMap().keySet().toArray( labels
);
172 // We need a format for content and fields
173 LttngEventFormat eventFormat
= new LttngEventFormat(labels
);
175 LttngEventField
[] fields
= null;
177 if (isParsingNeeded
== true) {
178 fields
= eventFormat
.parse(jniEvent
.parseAllFields());
179 for (int y
= 0; y
< fields
.length
; y
++) {
180 content
+= fields
[y
].toString() + " ";
184 LttngEvent event
= null;
186 event
= new LttngEvent(
187 new LttngTimestamp(jniEvent
.getEventTime().getTime()),
188 new TmfEventSource(jniEvent
.requestEventSource() ),
189 new LttngEventType(jniEvent
.getParentTracefile().getTracefileName(),
190 jniEvent
.getParentTracefile().getCpuNumber(),
191 jniEvent
.requestEventMarker().getName(),
193 new LttngEventContent(eventFormat
, content
, fields
),
194 new LttngEventReference(jniEvent
.getParentTracefile().getTracefilePath(), this.getName()),
197 catch (LttngException e
) {
198 System
.out
.println("ERROR : Event creation returned :" + e
.getMessage() );
205 * Seek (move) to a certain location in the trace.
207 * WARNING : No event is read by this function, it just seek to a certain time.<br>
208 * Use "parseNextEvent()" or "readNextEvent()" to get the event we seeked to.
210 * @param location a TmfTimestamp of a position in the trace
212 * @return StreamContext pointing the position in the trace JUST AFTER the seek location
214 public TmfTraceContext
seekLocation(Object location
) {
216 LttngTimestamp timestamp
= null;
218 // If location is null, interpret this as a request to get back to the beginning of the trace
219 // Change the location, the seek will happen below
220 if (location
== null) {
221 location
= getStartTime();
224 if (location
instanceof TmfTimestamp
) {
225 long value
= ((TmfTimestamp
) location
).getValue();
226 if (value
!= currentJniTrace
.getCurrentEventTimestamp().getTime()) {
227 synchronized (currentJniTrace
) {
228 currentJniTrace
.seekToTime(new JniTime(value
));
229 timestamp
= (LttngTimestamp
) getCurrentLocation();
234 System
.out
.println("ERROR : Location not instance of TmfTimestamp");
237 return new TmfTraceContext(timestamp
, timestamp
, 0);
241 * Return location (timestamp) of our current position in the trace.
243 * @return LttngTimestamp The time JUST AFTER the current event or AFTER endTime if no more event is available.
246 public Object
getCurrentLocation() {
248 LttngTimestamp returnedLocation
= null;
249 JniEvent tmpJniEvent
= currentJniTrace
.findNextEvent();
251 if ( tmpJniEvent
!= null ) {
252 returnedLocation
= new LttngTimestamp(tmpJniEvent
.getEventTime().getTime());
255 returnedLocation
= new LttngTimestamp( getEndTime().getValue() + 1 );
258 return returnedLocation
;
262 * Return a reference to the current LttngTrace we are reading from.
265 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
267 public JniTrace
getCurrentJniTrace() {
268 return currentJniTrace
;
273 * Return a reference to the current LttngEvent we have in memory.
276 * @see org.eclipse.linuxtools.lttng.event.LttngEvent
278 public LttngEvent
getCurrentEvent() {
279 return currentLttngEvent
;
284 public String
toString() {
285 String returnedData
="";
287 returnedData
+= "Path :" + getPath() + " ";
288 returnedData
+= "Trace:" + currentJniTrace
+ " ";
289 returnedData
+= "Event:" + currentLttngEvent
;
295 // // !!! THIS MAIN IS FOR TESTING ONLY !!!
296 // public static void main(String[] args) {
298 // LTTngTrace testStream = null;
301 // System.out.println("JAVA.LIBRARY.PATH : " + System.getProperty("java.library.path"));
303 // Map<String,String> testEnv = System.getenv();
305 // String new_key = null;
306 // String new_data = null;
307 // Iterator<String> iterator = testEnv.keySet().iterator();
309 // System.out.println("ENV : " );
310 // while (iterator.hasNext()) {
311 // new_key = iterator.next();
312 // new_data = testEnv.get(new_key);
313 // System.out.println(" " + new_key + ":" + new_data );
316 // testStream = new LTTngTrace("/home/william/trace1", true);
318 // System.out.println("NB Events : " + testStream.getNbEvents());
319 // System.out.println("Beginning test run parsing event");
321 // LttngEvent tmpEvent = null;
322 // Random generator = new Random();
325 // long execStartTime = System.currentTimeMillis();
326 // for (int x = 0; x < 10; x++) {
327 // number = generator.nextInt(testStream.getNbEvents());
329 // tmpEvent = (LttngEvent) testStream.getEvent(new TmfTraceContext(null), number);
332 // System.out.println("GETTING EVENT #" + number);
334 // // *****************
335 // // *** OLD EVIL WAY
336 // TmfEventField[] tmpJoieFields = tmpEvent.getContent().getFields();
337 // for ( int pos = 0; pos< tmpJoieFields.length; pos++ )
339 // System.out.print(tmpJoieFields[pos].toString() + " ");
341 // System.out.println("");
343 // // *****************
346 // // *****************
347 // // *** NEW CAST-O-RAMA WAY
348 // TmfEventField[] tmpJoieFields2 = ( (LttngEventContent)tmpEvent.getContent()).getFields(tmpEvent);
349 // for ( int pos = 0; pos< tmpJoieFields2.length; pos++ )
351 // System.out.print(tmpJoieFields2[pos].toString() + " ");
353 // System.out.println("");
355 // // *****************
357 // long execEndTime = System.currentTimeMillis();
358 // System.out.println("Execution time: " + (execEndTime - execStartTime) + "ms");
361 // } catch (Exception e) {
362 // System.out.println("FAILED WITH : " + e.getMessage() + "\n");