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 // FIXME: LTTng hack - start
238 // return new TmfTraceContext(timestamp, timestamp, 0); // Original
239 return new TmfTraceContext(timestamp
, timestamp
, -1); // Hacked
240 // FIXME: LTTng hack - end
244 * Return location (timestamp) of our current position in the trace.
246 * @return LttngTimestamp The time JUST AFTER the current event or AFTER endTime if no more event is available.
249 public Object
getCurrentLocation() {
251 LttngTimestamp returnedLocation
= null;
252 JniEvent tmpJniEvent
= currentJniTrace
.findNextEvent();
254 if ( tmpJniEvent
!= null ) {
255 returnedLocation
= new LttngTimestamp(tmpJniEvent
.getEventTime().getTime());
258 returnedLocation
= new LttngTimestamp( getEndTime().getValue() + 1 );
261 return returnedLocation
;
265 * Return a reference to the current LttngTrace we are reading from.
268 * @see org.eclipse.linuxtools.lttng.jni.JniTrace
270 public JniTrace
getCurrentJniTrace() {
271 return currentJniTrace
;
276 * Return a reference to the current LttngEvent we have in memory.
279 * @see org.eclipse.linuxtools.lttng.event.LttngEvent
281 public LttngEvent
getCurrentEvent() {
282 return currentLttngEvent
;
287 public String
toString() {
288 String returnedData
="";
290 returnedData
+= "Path :" + getPath() + " ";
291 returnedData
+= "Trace:" + currentJniTrace
+ " ";
292 returnedData
+= "Event:" + currentLttngEvent
;
298 // // !!! THIS MAIN IS FOR TESTING ONLY !!!
299 // public static void main(String[] args) {
301 // LTTngTrace testStream = null;
304 // System.out.println("JAVA.LIBRARY.PATH : " + System.getProperty("java.library.path"));
306 // Map<String,String> testEnv = System.getenv();
308 // String new_key = null;
309 // String new_data = null;
310 // Iterator<String> iterator = testEnv.keySet().iterator();
312 // System.out.println("ENV : " );
313 // while (iterator.hasNext()) {
314 // new_key = iterator.next();
315 // new_data = testEnv.get(new_key);
316 // System.out.println(" " + new_key + ":" + new_data );
319 // testStream = new LTTngTrace("/home/william/trace1", true);
321 // System.out.println("NB Events : " + testStream.getNbEvents());
322 // System.out.println("Beginning test run parsing event");
324 // LttngEvent tmpEvent = null;
325 // Random generator = new Random();
328 // long execStartTime = System.currentTimeMillis();
329 // for (int x = 0; x < 10; x++) {
330 // number = generator.nextInt(testStream.getNbEvents());
332 // tmpEvent = (LttngEvent) testStream.getEvent(new TmfTraceContext(null), number);
335 // System.out.println("GETTING EVENT #" + number);
337 // // *****************
338 // // *** OLD EVIL WAY
339 // TmfEventField[] tmpJoieFields = tmpEvent.getContent().getFields();
340 // for ( int pos = 0; pos< tmpJoieFields.length; pos++ )
342 // System.out.print(tmpJoieFields[pos].toString() + " ");
344 // System.out.println("");
346 // // *****************
349 // // *****************
350 // // *** NEW CAST-O-RAMA WAY
351 // TmfEventField[] tmpJoieFields2 = ( (LttngEventContent)tmpEvent.getContent()).getFields(tmpEvent);
352 // for ( int pos = 0; pos< tmpJoieFields2.length; pos++ )
354 // System.out.print(tmpJoieFields2[pos].toString() + " ");
356 // System.out.println("");
358 // // *****************
360 // long execEndTime = System.currentTimeMillis();
361 // System.out.println("Execution time: " + (execEndTime - execStartTime) + "ms");
364 // } catch (Exception e) {
365 // System.out.println("FAILED WITH : " + e.getMessage() + "\n");