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 | |
116 | public synchronized TmfEvent parseEvent(TmfTraceContext context) { | |
117 | ||
8d2e2848 | 118 | seekLocation(context.getLocation()); |
3fbd810a FC |
119 | JniEvent jniEvent = currentJniTrace.readNextEvent(); |
120 | currentLttngEvent = convertJniEventToTmf(jniEvent, true); | |
8d2e2848 FC |
121 | context = new TmfTraceContext((LttngTimestamp) getCurrentLocation(), |
122 | currentLttngEvent.getTimestamp(), context.getIndex() + 1); | |
3fbd810a | 123 | |
6d848cce | 124 | return currentLttngEvent; |
5d10d135 ASL |
125 | } |
126 | ||
3fbd810a | 127 | /* |
6d848cce FC |
128 | * Method to convert a JniEvent into a LttngEvent.<br> |
129 | * <br> | |
5d10d135 ASL |
130 | * Note : This method will call LttngEvent convertEventJniToTmf(JniEvent, boolean) |
131 | * with a default value for isParsingNeeded | |
132 | * | |
6d848cce | 133 | * @param newEvent The JniEvent to convert |
3fbd810a | 134 | * |
6d848cce | 135 | * @return LttngEvent The converted event |
3fbd810a | 136 | * |
6d848cce | 137 | * @see org.eclipse.linuxtools.lttng.jni.JniEvent |
5d10d135 | 138 | */ |
3fbd810a | 139 | public LttngEvent convertJniEventToTmf(JniEvent newEvent) { |
6d848cce FC |
140 | LttngEvent event = null; |
141 | if (newEvent != null) | |
142 | event = convertJniEventToTmf(newEvent, IS_PARSING_NEEDED_DEFAULT); | |
143 | return event; | |
5d10d135 ASL |
144 | } |
145 | ||
3fbd810a | 146 | /* |
6d848cce | 147 | * Method tp convert a JniEvent into a LttngEvent |
5d10d135 | 148 | * |
6d848cce | 149 | * @param jniEvent The JniEvent to convert |
5d10d135 | 150 | * @param isParsingNeeded A boolean value telling if the event should be parsed or not. |
3fbd810a | 151 | * |
6d848cce | 152 | * @return LttngEvent The converted event |
3fbd810a | 153 | * |
6d848cce | 154 | * @see org.eclipse.linuxtools.lttng.jni.JniEvent |
5d10d135 | 155 | */ |
3fbd810a FC |
156 | public LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) { |
157 | ||
158 | // *** FIXME *** | |
159 | // Format seems weird to me... we need to revisit Format/Fields/Content to find a better ways | |
160 | // | |
161 | // Generate fields | |
162 | String[] labels = new String[jniEvent.requestEventMarker().getMarkerFieldsHashMap().size()]; | |
163 | labels = jniEvent.requestEventMarker().getMarkerFieldsHashMap().keySet().toArray( labels ); | |
164 | ||
165 | // We need a format for content and fields | |
166 | LttngEventFormat eventFormat = new LttngEventFormat(labels); | |
6d848cce FC |
167 | String content = ""; |
168 | LttngEventField[] fields = null; | |
169 | ||
3fbd810a | 170 | if (isParsingNeeded == true) { |
6d848cce FC |
171 | fields = eventFormat.parse(jniEvent.parseAllFields()); |
172 | for (int y = 0; y < fields.length; y++) { | |
173 | content += fields[y].toString() + " "; | |
174 | } | |
88144d4a ASL |
175 | } |
176 | ||
3fbd810a FC |
177 | LttngEvent event = null; |
178 | try { | |
179 | event = new LttngEvent( | |
180 | new LttngTimestamp(jniEvent.getEventTime().getTime()), | |
181 | new TmfEventSource(jniEvent.requestEventSource() ), | |
182 | new LttngEventType(jniEvent.getParentTracefile().getTracefileName(), | |
183 | jniEvent.getParentTracefile().getCpuNumber(), | |
184 | jniEvent.requestEventMarker().getName(), | |
185 | eventFormat), | |
186 | new LttngEventContent(eventFormat, content, fields), | |
187 | new LttngEventReference(jniEvent.getParentTracefile().getTracefilePath(), this.getName()), | |
188 | jniEvent); | |
189 | } | |
190 | catch (LttngException e) { | |
191 | System.out.println("ERROR : Event creation returned :" + e.getMessage() ); | |
5d10d135 | 192 | } |
88144d4a | 193 | |
3fbd810a | 194 | return event; |
5d10d135 ASL |
195 | } |
196 | ||
5d10d135 | 197 | /** |
6d848cce | 198 | * Seek (move) to a certain location in the trace. |
3fbd810a FC |
199 | * <p> |
200 | * WARNING : No event is read by this function, it just seek to a certain time.<br> | |
201 | * Use "parseNextEvent()" or "readNextEvent()" to get the event we seeked to. | |
5d10d135 | 202 | * |
3fbd810a FC |
203 | * @param location a TmfTimestamp of a position in the trace |
204 | * | |
205 | * @return StreamContext pointing the position in the trace JUST AFTER the seek location | |
5d10d135 | 206 | */ |
3fbd810a | 207 | public TmfTraceContext seekLocation(Object location) { |
6d848cce FC |
208 | |
209 | // If location is null, interpret this as a request to get back to the beginning of the trace | |
210 | // Change the location, the seek will happen below | |
211 | if (location == null) { | |
212 | location = getStartTime(); | |
5d10d135 | 213 | } |
6d848cce | 214 | |
3fbd810a FC |
215 | if (location instanceof TmfTimestamp) { |
216 | long value = ((TmfTimestamp) location).getValue(); | |
6d848cce FC |
217 | if (value != currentJniTrace.getCurrentEventTimestamp().getTime()) { |
218 | currentJniTrace.seekToTime(new JniTime(value)); | |
219 | } | |
5d10d135 ASL |
220 | } |
221 | else { | |
6d848cce | 222 | System.out.println("ERROR : Location not instance of TmfTimestamp"); |
5d10d135 | 223 | } |
3fbd810a FC |
224 | |
225 | return new TmfTraceContext((LttngTimestamp) getCurrentLocation(), currentLttngEvent.getTimestamp(), 0); | |
226 | } | |
227 | ||
228 | /** | |
229 | * Return location (timestamp) of our current position in the trace. | |
230 | * | |
231 | * @return LttngTimestamp The time JUST AFTER the current event or AFTER endTime if no more event is available. | |
232 | */ | |
233 | @Override | |
234 | public Object getCurrentLocation() { | |
235 | ||
236 | LttngTimestamp returnedLocation = null; | |
237 | JniEvent tmpJniEvent = currentJniTrace.findNextEvent(); | |
238 | ||
239 | if ( tmpJniEvent != null ) { | |
240 | returnedLocation = new LttngTimestamp(tmpJniEvent.getEventTime().getTime() + 1); | |
241 | } | |
242 | else { | |
243 | returnedLocation = new LttngTimestamp( getEndTime().getValue() + 1 ); | |
244 | } | |
245 | ||
246 | return returnedLocation; | |
247 | } | |
248 | ||
249 | /** | |
250 | * Return a reference to the current LttngTrace we are reading from. | |
251 | * | |
252 | * @return JniTrace | |
253 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace | |
254 | */ | |
255 | public JniTrace getCurrentJniTrace() { | |
256 | return currentJniTrace; | |
257 | } | |
258 | ||
259 | ||
260 | /** | |
261 | * Return a reference to the current LttngEvent we have in memory. | |
262 | * | |
263 | * @return LttngEvent | |
264 | * @see org.eclipse.linuxtools.lttng.event.LttngEvent | |
265 | */ | |
266 | public LttngEvent getCurrentEvent() { | |
267 | return currentLttngEvent; | |
268 | } | |
269 | ||
270 | ||
271 | @Override | |
cc6eec3e | 272 | public String toString() { |
3fbd810a FC |
273 | String returnedData=""; |
274 | ||
275 | returnedData += "Path :" + getPath() + " "; | |
276 | returnedData += "Trace:" + currentJniTrace + " "; | |
277 | returnedData += "Event:" + currentLttngEvent; | |
278 | ||
279 | return returnedData; | |
280 | } | |
281 | ||
282 | ||
6d848cce FC |
283 | // // !!! THIS MAIN IS FOR TESTING ONLY !!! |
284 | // public static void main(String[] args) { | |
285 | // | |
3fbd810a | 286 | // LTTngTrace testStream = null; |
6d848cce | 287 | // try { |
3fbd810a FC |
288 | // |
289 | // System.out.println("JAVA.LIBRARY.PATH : " + System.getProperty("java.library.path")); | |
290 | // | |
291 | // Map<String,String> testEnv = System.getenv(); | |
292 | // | |
293 | // String new_key = null; | |
294 | // String new_data = null; | |
295 | // Iterator<String> iterator = testEnv.keySet().iterator(); | |
296 | // | |
297 | // System.out.println("ENV : " ); | |
298 | // while (iterator.hasNext()) { | |
299 | // new_key = iterator.next(); | |
300 | // new_data = testEnv.get(new_key); | |
301 | // System.out.println(" " + new_key + ":" + new_data ); | |
302 | // } | |
303 | // | |
304 | // testStream = new LTTngTrace("/home/william/trace1", true); | |
6d848cce FC |
305 | // |
306 | // System.out.println("NB Events : " + testStream.getNbEvents()); | |
307 | // System.out.println("Beginning test run parsing event"); | |
308 | // | |
309 | // LttngEvent tmpEvent = null; | |
310 | // Random generator = new Random(); | |
311 | // | |
312 | // int number = 0; | |
313 | // long execStartTime = System.currentTimeMillis(); | |
314 | // for (int x = 0; x < 10; x++) { | |
315 | // number = generator.nextInt(testStream.getNbEvents()); | |
316 | // | |
317 | // tmpEvent = (LttngEvent) testStream.getEvent(new TmfTraceContext(null), number); | |
318 | // | |
319 | // | |
320 | // System.out.println("GETTING EVENT #" + number); | |
321 | // | |
322 | // // ***************** | |
323 | // // *** OLD EVIL WAY | |
324 | // TmfEventField[] tmpJoieFields = tmpEvent.getContent().getFields(); | |
325 | // for ( int pos = 0; pos< tmpJoieFields.length; pos++ ) | |
326 | // { | |
327 | // System.out.print(tmpJoieFields[pos].toString() + " "); | |
328 | // } | |
329 | // System.out.println(""); | |
330 | // // *** | |
331 | // // ***************** | |
332 | // | |
333 | // | |
334 | // // ***************** | |
335 | // // *** NEW CAST-O-RAMA WAY | |
336 | // TmfEventField[] tmpJoieFields2 = ( (LttngEventContent)tmpEvent.getContent()).getFields(tmpEvent); | |
337 | // for ( int pos = 0; pos< tmpJoieFields2.length; pos++ ) | |
338 | // { | |
339 | // System.out.print(tmpJoieFields2[pos].toString() + " "); | |
340 | // } | |
341 | // System.out.println(""); | |
342 | // // *** | |
343 | // // ***************** | |
344 | // } | |
345 | // long execEndTime = System.currentTimeMillis(); | |
346 | // System.out.println("Execution time: " + (execEndTime - execStartTime) + "ms"); | |
347 | // | |
348 | // | |
349 | // } catch (Exception e) { | |
350 | // System.out.println("FAILED WITH : " + e.getMessage() + "\n"); | |
351 | // } | |
352 | // | |
353 | // } | |
354 | ||
88144d4a | 355 | } |