Commit | Line | Data |
---|---|---|
5d10d135 ASL |
1 | /******************************************************************************* |
2 | * Copyright (c) 2009 Ericsson | |
3 | * | |
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 | |
8 | * | |
9 | * Contributors: | |
10 | * William Bourque (wbourque@gmail.com) - Initial API and implementation | |
11 | *******************************************************************************/ | |
12 | ||
13 | package org.eclipse.linuxtools.lttng.trace; | |
14 | ||
3fbd810a | 15 | import org.eclipse.linuxtools.lttng.LttngException; |
5d10d135 ASL |
16 | import org.eclipse.linuxtools.lttng.event.LttngEvent; |
17 | import org.eclipse.linuxtools.lttng.event.LttngEventContent; | |
6d848cce FC |
18 | import org.eclipse.linuxtools.lttng.event.LttngEventField; |
19 | import org.eclipse.linuxtools.lttng.event.LttngEventFormat; | |
5d10d135 | 20 | import org.eclipse.linuxtools.lttng.event.LttngEventReference; |
5d10d135 | 21 | import org.eclipse.linuxtools.lttng.event.LttngEventType; |
5d10d135 ASL |
22 | import org.eclipse.linuxtools.lttng.event.LttngTimestamp; |
23 | import org.eclipse.linuxtools.lttng.jni.JniEvent; | |
88144d4a | 24 | import org.eclipse.linuxtools.lttng.jni.JniTime; |
5d10d135 | 25 | import org.eclipse.linuxtools.lttng.jni.JniTrace; |
6d848cce | 26 | import org.eclipse.linuxtools.tmf.event.TmfEvent; |
3fbd810a | 27 | import org.eclipse.linuxtools.tmf.event.TmfEventSource; |
5d10d135 ASL |
28 | import org.eclipse.linuxtools.tmf.event.TmfTimeRange; |
29 | import org.eclipse.linuxtools.tmf.event.TmfTimestamp; | |
5d10d135 | 30 | import org.eclipse.linuxtools.tmf.trace.TmfTrace; |
8d2e2848 | 31 | import org.eclipse.linuxtools.tmf.trace.TmfTraceContext; |
5d10d135 | 32 | |
3fbd810a FC |
33 | |
34 | class LTTngTraceException extends LttngException { | |
35 | static final long serialVersionUID = -1636648737081868146L; | |
36 | ||
37 | public LTTngTraceException(String errMsg) { | |
38 | super(errMsg); | |
39 | } | |
40 | } | |
41 | ||
5d10d135 | 42 | /** |
6d848cce FC |
43 | * <b><u>LTTngTrace</u></b> |
44 | * <p> | |
5d10d135 ASL |
45 | * LTTng trace implementation. It accesses the C trace handling library |
46 | * (seeking, reading and parsing) through the JNI component. | |
47 | */ | |
88144d4a | 48 | public class LTTngTrace extends TmfTrace { |
6d848cce FC |
49 | |
50 | private final static boolean IS_PARSING_NEEDED_DEFAULT = true; | |
51 | private final static int CHECKPOINT_PAGE_SIZE = 1000; | |
52 | ||
53 | // Reference to the current LttngEvent | |
54 | private LttngEvent currentLttngEvent = null; | |
5d10d135 ASL |
55 | |
56 | // Reference to our JNI trace | |
57 | private JniTrace currentJniTrace = null; | |
58 | ||
5d10d135 | 59 | /** |
6d848cce FC |
60 | * Default Constructor |
61 | * <p> | |
62 | * @param path Path to a <b>directory</b> that contain an LTTng trace. | |
5d10d135 | 63 | * |
6d848cce | 64 | * @exception Exception Trace opening failed (most likely FileNotFoundException) |
5d10d135 | 65 | * |
6d848cce | 66 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace |
5d10d135 ASL |
67 | */ |
68 | public LTTngTrace(String path) throws Exception { | |
6d848cce | 69 | this(path, true); |
5d10d135 ASL |
70 | } |
71 | ||
72 | /** | |
6d848cce | 73 | * Default constructor, with control over the indexing |
5d10d135 ASL |
74 | * <p> |
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. | |
5d10d135 | 77 | * |
6d848cce | 78 | * @exception Exception Trace opening failed (most likely FileNotFoundException) |
5d10d135 | 79 | * |
6d848cce | 80 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace |
5d10d135 | 81 | */ |
6d848cce FC |
82 | public LTTngTrace(String path, boolean waitForCompletion) throws Exception { |
83 | super(path, CHECKPOINT_PAGE_SIZE, waitForCompletion); | |
5d10d135 | 84 | try { |
3fbd810a | 85 | currentJniTrace = new JniTrace(path); |
5d10d135 | 86 | } |
3fbd810a FC |
87 | catch (Exception e) { |
88 | throw new LTTngTraceException(e.getMessage()); | |
88144d4a | 89 | } |
6d848cce FC |
90 | TmfTimestamp startTime = new LttngTimestamp(currentJniTrace.getStartTimeFromTimestampCurrentCounter().getTime()); |
91 | setTimeRange(new TmfTimeRange(startTime, startTime)); | |
92 | indexStream(); | |
5d10d135 ASL |
93 | } |
94 | ||
3fbd810a FC |
95 | /* |
96 | * Copy constructor is forbidden for LttngEvenmStream | |
5d10d135 | 97 | * |
3fbd810a FC |
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. | |
5d10d135 | 101 | */ |
3fbd810a FC |
102 | private LTTngTrace(LTTngTrace oldStream) throws Exception { |
103 | super(null); | |
104 | throw new Exception("Copy constructor should never be use with a LTTngTrace!"); | |
9aae0442 ASL |
105 | } |
106 | ||
3fbd810a FC |
107 | /** |
108 | * Parse the next event in the trace | |
5d10d135 | 109 | * |
3fbd810a FC |
110 | * @return TmfEvent The parsed event, or null if none available. |
111 | * | |
112 | * | |
113 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace | |
114 | */ | |
115 | @Override | |
35c72307 | 116 | public TmfEvent parseEvent(TmfTraceContext context) { |
3fbd810a | 117 | |
35c72307 FC |
118 | JniEvent jniEvent; |
119 | LttngTimestamp timestamp = null; | |
120 | ||
121 | synchronized (currentJniTrace) { | |
122 | seekLocation(context.getLocation()); | |
123 | jniEvent = currentJniTrace.readNextEvent(); | |
124 | currentLttngEvent = (jniEvent != null) ? convertJniEventToTmf(jniEvent, true) : null; | |
125 | timestamp = (LttngTimestamp) getCurrentLocation(); | |
126 | } | |
127 | context.setLocation(timestamp); | |
128 | context.setTimestamp(timestamp); | |
129 | context.incrIndex(); | |
130 | ||
131 | return currentLttngEvent; | |
5d10d135 ASL |
132 | } |
133 | ||
3fbd810a | 134 | /* |
6d848cce FC |
135 | * Method to convert a JniEvent into a LttngEvent.<br> |
136 | * <br> | |
5d10d135 ASL |
137 | * Note : This method will call LttngEvent convertEventJniToTmf(JniEvent, boolean) |
138 | * with a default value for isParsingNeeded | |
139 | * | |
6d848cce | 140 | * @param newEvent The JniEvent to convert |
3fbd810a | 141 | * |
6d848cce | 142 | * @return LttngEvent The converted event |
3fbd810a | 143 | * |
6d848cce | 144 | * @see org.eclipse.linuxtools.lttng.jni.JniEvent |
5d10d135 | 145 | */ |
3fbd810a | 146 | public LttngEvent convertJniEventToTmf(JniEvent newEvent) { |
6d848cce FC |
147 | LttngEvent event = null; |
148 | if (newEvent != null) | |
149 | event = convertJniEventToTmf(newEvent, IS_PARSING_NEEDED_DEFAULT); | |
150 | return event; | |
5d10d135 ASL |
151 | } |
152 | ||
3fbd810a | 153 | /* |
6d848cce | 154 | * Method tp convert a JniEvent into a LttngEvent |
5d10d135 | 155 | * |
6d848cce | 156 | * @param jniEvent The JniEvent to convert |
5d10d135 | 157 | * @param isParsingNeeded A boolean value telling if the event should be parsed or not. |
3fbd810a | 158 | * |
6d848cce | 159 | * @return LttngEvent The converted event |
3fbd810a | 160 | * |
6d848cce | 161 | * @see org.eclipse.linuxtools.lttng.jni.JniEvent |
5d10d135 | 162 | */ |
3fbd810a FC |
163 | public LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) { |
164 | ||
165 | // *** FIXME *** | |
166 | // Format seems weird to me... we need to revisit Format/Fields/Content to find a better ways | |
167 | // | |
168 | // Generate fields | |
169 | String[] labels = new String[jniEvent.requestEventMarker().getMarkerFieldsHashMap().size()]; | |
170 | labels = jniEvent.requestEventMarker().getMarkerFieldsHashMap().keySet().toArray( labels ); | |
171 | ||
172 | // We need a format for content and fields | |
173 | LttngEventFormat eventFormat = new LttngEventFormat(labels); | |
6d848cce FC |
174 | String content = ""; |
175 | LttngEventField[] fields = null; | |
176 | ||
3fbd810a | 177 | if (isParsingNeeded == true) { |
6d848cce FC |
178 | fields = eventFormat.parse(jniEvent.parseAllFields()); |
179 | for (int y = 0; y < fields.length; y++) { | |
180 | content += fields[y].toString() + " "; | |
181 | } | |
88144d4a ASL |
182 | } |
183 | ||
3fbd810a FC |
184 | LttngEvent event = null; |
185 | try { | |
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(), | |
192 | eventFormat), | |
193 | new LttngEventContent(eventFormat, content, fields), | |
194 | new LttngEventReference(jniEvent.getParentTracefile().getTracefilePath(), this.getName()), | |
195 | jniEvent); | |
196 | } | |
197 | catch (LttngException e) { | |
198 | System.out.println("ERROR : Event creation returned :" + e.getMessage() ); | |
5d10d135 | 199 | } |
88144d4a | 200 | |
3fbd810a | 201 | return event; |
5d10d135 ASL |
202 | } |
203 | ||
5d10d135 | 204 | /** |
6d848cce | 205 | * Seek (move) to a certain location in the trace. |
3fbd810a FC |
206 | * <p> |
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. | |
5d10d135 | 209 | * |
3fbd810a FC |
210 | * @param location a TmfTimestamp of a position in the trace |
211 | * | |
212 | * @return StreamContext pointing the position in the trace JUST AFTER the seek location | |
5d10d135 | 213 | */ |
d2fe33b6 | 214 | public TmfTraceContext seekLocation(Object location) { |
6d848cce | 215 | |
35c72307 FC |
216 | LttngTimestamp timestamp = null; |
217 | ||
218 | // If location is null, interpret this as a request to get back to the beginning of the trace | |
6d848cce FC |
219 | // Change the location, the seek will happen below |
220 | if (location == null) { | |
221 | location = getStartTime(); | |
5d10d135 | 222 | } |
35c72307 | 223 | |
3fbd810a FC |
224 | if (location instanceof TmfTimestamp) { |
225 | long value = ((TmfTimestamp) location).getValue(); | |
6d848cce | 226 | if (value != currentJniTrace.getCurrentEventTimestamp().getTime()) { |
35c72307 FC |
227 | synchronized (currentJniTrace) { |
228 | currentJniTrace.seekToTime(new JniTime(value)); | |
229 | timestamp = (LttngTimestamp) getCurrentLocation(); | |
230 | } | |
6d848cce | 231 | } |
5d10d135 ASL |
232 | } |
233 | else { | |
6d848cce | 234 | System.out.println("ERROR : Location not instance of TmfTimestamp"); |
5d10d135 | 235 | } |
3fbd810a | 236 | |
35c72307 | 237 | return new TmfTraceContext(timestamp, timestamp, 0); |
3fbd810a FC |
238 | } |
239 | ||
240 | /** | |
241 | * Return location (timestamp) of our current position in the trace. | |
242 | * | |
243 | * @return LttngTimestamp The time JUST AFTER the current event or AFTER endTime if no more event is available. | |
244 | */ | |
245 | @Override | |
246 | public Object getCurrentLocation() { | |
247 | ||
248 | LttngTimestamp returnedLocation = null; | |
249 | JniEvent tmpJniEvent = currentJniTrace.findNextEvent(); | |
250 | ||
251 | if ( tmpJniEvent != null ) { | |
35c72307 | 252 | returnedLocation = new LttngTimestamp(tmpJniEvent.getEventTime().getTime()); |
3fbd810a FC |
253 | } |
254 | else { | |
255 | returnedLocation = new LttngTimestamp( getEndTime().getValue() + 1 ); | |
256 | } | |
257 | ||
258 | return returnedLocation; | |
259 | } | |
260 | ||
261 | /** | |
262 | * Return a reference to the current LttngTrace we are reading from. | |
263 | * | |
264 | * @return JniTrace | |
265 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace | |
266 | */ | |
267 | public JniTrace getCurrentJniTrace() { | |
268 | return currentJniTrace; | |
269 | } | |
270 | ||
271 | ||
272 | /** | |
273 | * Return a reference to the current LttngEvent we have in memory. | |
274 | * | |
275 | * @return LttngEvent | |
276 | * @see org.eclipse.linuxtools.lttng.event.LttngEvent | |
277 | */ | |
278 | public LttngEvent getCurrentEvent() { | |
279 | return currentLttngEvent; | |
280 | } | |
281 | ||
282 | ||
283 | @Override | |
cc6eec3e | 284 | public String toString() { |
3fbd810a FC |
285 | String returnedData=""; |
286 | ||
287 | returnedData += "Path :" + getPath() + " "; | |
288 | returnedData += "Trace:" + currentJniTrace + " "; | |
289 | returnedData += "Event:" + currentLttngEvent; | |
290 | ||
291 | return returnedData; | |
292 | } | |
293 | ||
294 | ||
6d848cce FC |
295 | // // !!! THIS MAIN IS FOR TESTING ONLY !!! |
296 | // public static void main(String[] args) { | |
297 | // | |
3fbd810a | 298 | // LTTngTrace testStream = null; |
6d848cce | 299 | // try { |
3fbd810a FC |
300 | // |
301 | // System.out.println("JAVA.LIBRARY.PATH : " + System.getProperty("java.library.path")); | |
302 | // | |
303 | // Map<String,String> testEnv = System.getenv(); | |
304 | // | |
305 | // String new_key = null; | |
306 | // String new_data = null; | |
307 | // Iterator<String> iterator = testEnv.keySet().iterator(); | |
308 | // | |
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 ); | |
314 | // } | |
315 | // | |
316 | // testStream = new LTTngTrace("/home/william/trace1", true); | |
6d848cce FC |
317 | // |
318 | // System.out.println("NB Events : " + testStream.getNbEvents()); | |
319 | // System.out.println("Beginning test run parsing event"); | |
320 | // | |
321 | // LttngEvent tmpEvent = null; | |
322 | // Random generator = new Random(); | |
323 | // | |
324 | // int number = 0; | |
325 | // long execStartTime = System.currentTimeMillis(); | |
326 | // for (int x = 0; x < 10; x++) { | |
327 | // number = generator.nextInt(testStream.getNbEvents()); | |
328 | // | |
329 | // tmpEvent = (LttngEvent) testStream.getEvent(new TmfTraceContext(null), number); | |
330 | // | |
331 | // | |
332 | // System.out.println("GETTING EVENT #" + number); | |
333 | // | |
334 | // // ***************** | |
335 | // // *** OLD EVIL WAY | |
336 | // TmfEventField[] tmpJoieFields = tmpEvent.getContent().getFields(); | |
337 | // for ( int pos = 0; pos< tmpJoieFields.length; pos++ ) | |
338 | // { | |
339 | // System.out.print(tmpJoieFields[pos].toString() + " "); | |
340 | // } | |
341 | // System.out.println(""); | |
342 | // // *** | |
343 | // // ***************** | |
344 | // | |
345 | // | |
346 | // // ***************** | |
347 | // // *** NEW CAST-O-RAMA WAY | |
348 | // TmfEventField[] tmpJoieFields2 = ( (LttngEventContent)tmpEvent.getContent()).getFields(tmpEvent); | |
349 | // for ( int pos = 0; pos< tmpJoieFields2.length; pos++ ) | |
350 | // { | |
351 | // System.out.print(tmpJoieFields2[pos].toString() + " "); | |
352 | // } | |
353 | // System.out.println(""); | |
354 | // // *** | |
355 | // // ***************** | |
356 | // } | |
357 | // long execEndTime = System.currentTimeMillis(); | |
358 | // System.out.println("Execution time: " + (execEndTime - execStartTime) + "ms"); | |
359 | // | |
360 | // | |
361 | // } catch (Exception e) { | |
362 | // System.out.println("FAILED WITH : " + e.getMessage() + "\n"); | |
363 | // } | |
364 | // | |
365 | // } | |
366 | ||
88144d4a | 367 | } |