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 | /** |
07d9e2ee FC |
43 | * <b><u>LTTngTrace</u></b><p> |
44 | * | |
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 | /** |
07d9e2ee | 60 | * Default Constructor.<p> |
5d10d135 | 61 | * |
07d9e2ee FC |
62 | * @param path Path to a <b>directory</b> that contain an LTTng trace. |
63 | * | |
64 | * @exception Exception (most likely LTTngTraceException or FileNotFoundException) | |
5d10d135 | 65 | * |
6d848cce | 66 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace |
5d10d135 ASL |
67 | */ |
68 | public LTTngTrace(String path) throws Exception { | |
07d9e2ee FC |
69 | // Call with "wait for completion" true and "skip indexing" false |
70 | this(path, true, false); | |
5d10d135 ASL |
71 | } |
72 | ||
73 | /** | |
07d9e2ee FC |
74 | * Constructor, with control over the indexing. |
75 | * <p> | |
76 | * @param path Path to a <b>directory</b> that contain an LTTng trace. | |
77 | * @param waitForCompletion Should we wait for indexign to complete before moving on. | |
78 | * | |
79 | * @exception Exception (most likely LTTngTraceException or FileNotFoundException) | |
80 | * | |
81 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace | |
82 | */ | |
83 | public LTTngTrace(String path, boolean waitForCompletion) throws Exception { | |
84 | // Call with "skip indexing" false | |
85 | this(path, waitForCompletion, false); | |
86 | } | |
87 | ||
88 | /** | |
89 | * Default constructor, with control over the indexing and possibility to bypass indexation | |
5d10d135 ASL |
90 | * <p> |
91 | * @param path Path to a <b>directory</b> that contain an LTTng trace. | |
92 | * @param waitForCompletion Should we wait for indexign to complete before moving on. | |
07d9e2ee | 93 | * @param bypassIndexing Should we bypass indexing completly? This is should only be useful for unit testing. |
5d10d135 | 94 | * |
07d9e2ee | 95 | * @exception Exception (most likely LTTngTraceException or FileNotFoundException) |
5d10d135 | 96 | * |
6d848cce | 97 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace |
5d10d135 | 98 | */ |
07d9e2ee FC |
99 | public LTTngTrace(String path, boolean waitForCompletion, boolean bypassIndexing) throws Exception { |
100 | super(path, CHECKPOINT_PAGE_SIZE, true); | |
5d10d135 | 101 | try { |
3fbd810a | 102 | currentJniTrace = new JniTrace(path); |
5d10d135 | 103 | } |
3fbd810a FC |
104 | catch (Exception e) { |
105 | throw new LTTngTraceException(e.getMessage()); | |
88144d4a | 106 | } |
6d848cce FC |
107 | TmfTimestamp startTime = new LttngTimestamp(currentJniTrace.getStartTimeFromTimestampCurrentCounter().getTime()); |
108 | setTimeRange(new TmfTimeRange(startTime, startTime)); | |
07d9e2ee FC |
109 | |
110 | // Bypass indexing if asked | |
111 | if ( bypassIndexing == false ) { | |
112 | indexStream(); | |
113 | } | |
5d10d135 ASL |
114 | } |
115 | ||
3fbd810a FC |
116 | /* |
117 | * Copy constructor is forbidden for LttngEvenmStream | |
5d10d135 | 118 | * |
3fbd810a FC |
119 | * Events are only valid for a very limited period of time and |
120 | * JNI library does not support multiple access at once (yet?). | |
07d9e2ee | 121 | * For this reason, copy constructor should NEVER be used. |
5d10d135 | 122 | */ |
3fbd810a FC |
123 | private LTTngTrace(LTTngTrace oldStream) throws Exception { |
124 | super(null); | |
125 | throw new Exception("Copy constructor should never be use with a LTTngTrace!"); | |
9aae0442 ASL |
126 | } |
127 | ||
3fbd810a | 128 | /** |
07d9e2ee | 129 | * Parse the next event in the trace.<p> |
5d10d135 | 130 | * |
07d9e2ee | 131 | * @param context The actual context of the trace |
3fbd810a | 132 | * |
07d9e2ee | 133 | * @return The parsed event, or null if none available |
3fbd810a FC |
134 | * |
135 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace | |
136 | */ | |
137 | @Override | |
35c72307 | 138 | public TmfEvent parseEvent(TmfTraceContext context) { |
35c72307 FC |
139 | JniEvent jniEvent; |
140 | LttngTimestamp timestamp = null; | |
141 | ||
142 | synchronized (currentJniTrace) { | |
07d9e2ee | 143 | // Seek to the context's location |
35c72307 | 144 | seekLocation(context.getLocation()); |
07d9e2ee FC |
145 | |
146 | // Read an event from the JNI and convert it into a LttngEvent | |
35c72307 FC |
147 | jniEvent = currentJniTrace.readNextEvent(); |
148 | currentLttngEvent = (jniEvent != null) ? convertJniEventToTmf(jniEvent, true) : null; | |
07d9e2ee FC |
149 | |
150 | // Save timestamp | |
35c72307 FC |
151 | timestamp = (LttngTimestamp) getCurrentLocation(); |
152 | } | |
153 | context.setLocation(timestamp); | |
154 | context.setTimestamp(timestamp); | |
155 | context.incrIndex(); | |
156 | ||
157 | return currentLttngEvent; | |
5d10d135 ASL |
158 | } |
159 | ||
07d9e2ee FC |
160 | /** |
161 | * Method to convert a JniEvent into a LttngEvent.<p> | |
162 | * | |
5d10d135 ASL |
163 | * Note : This method will call LttngEvent convertEventJniToTmf(JniEvent, boolean) |
164 | * with a default value for isParsingNeeded | |
165 | * | |
07d9e2ee | 166 | * @param newEvent The JniEvent to convert into LttngEvent |
3fbd810a | 167 | * |
07d9e2ee | 168 | * @return The converted event |
3fbd810a | 169 | * |
6d848cce | 170 | * @see org.eclipse.linuxtools.lttng.jni.JniEvent |
5d10d135 | 171 | */ |
3fbd810a | 172 | public LttngEvent convertJniEventToTmf(JniEvent newEvent) { |
6d848cce FC |
173 | LttngEvent event = null; |
174 | if (newEvent != null) | |
175 | event = convertJniEventToTmf(newEvent, IS_PARSING_NEEDED_DEFAULT); | |
176 | return event; | |
5d10d135 ASL |
177 | } |
178 | ||
07d9e2ee | 179 | /** |
6d848cce | 180 | * Method tp convert a JniEvent into a LttngEvent |
5d10d135 | 181 | * |
07d9e2ee | 182 | * @param jniEvent The JniEvent to convert into LttngEvent |
5d10d135 | 183 | * @param isParsingNeeded A boolean value telling if the event should be parsed or not. |
3fbd810a | 184 | * |
07d9e2ee | 185 | * @return The converted event |
3fbd810a | 186 | * |
6d848cce | 187 | * @see org.eclipse.linuxtools.lttng.jni.JniEvent |
5d10d135 | 188 | */ |
3fbd810a FC |
189 | public LttngEvent convertJniEventToTmf(JniEvent jniEvent, boolean isParsingNeeded) { |
190 | ||
191 | // *** FIXME *** | |
192 | // Format seems weird to me... we need to revisit Format/Fields/Content to find a better ways | |
193 | // | |
194 | // Generate fields | |
195 | String[] labels = new String[jniEvent.requestEventMarker().getMarkerFieldsHashMap().size()]; | |
196 | labels = jniEvent.requestEventMarker().getMarkerFieldsHashMap().keySet().toArray( labels ); | |
197 | ||
198 | // We need a format for content and fields | |
199 | LttngEventFormat eventFormat = new LttngEventFormat(labels); | |
6d848cce FC |
200 | String content = ""; |
201 | LttngEventField[] fields = null; | |
202 | ||
3fbd810a | 203 | if (isParsingNeeded == true) { |
6d848cce FC |
204 | fields = eventFormat.parse(jniEvent.parseAllFields()); |
205 | for (int y = 0; y < fields.length; y++) { | |
206 | content += fields[y].toString() + " "; | |
207 | } | |
88144d4a ASL |
208 | } |
209 | ||
3fbd810a FC |
210 | LttngEvent event = null; |
211 | try { | |
212 | event = new LttngEvent( | |
213 | new LttngTimestamp(jniEvent.getEventTime().getTime()), | |
214 | new TmfEventSource(jniEvent.requestEventSource() ), | |
215 | new LttngEventType(jniEvent.getParentTracefile().getTracefileName(), | |
216 | jniEvent.getParentTracefile().getCpuNumber(), | |
217 | jniEvent.requestEventMarker().getName(), | |
218 | eventFormat), | |
219 | new LttngEventContent(eventFormat, content, fields), | |
220 | new LttngEventReference(jniEvent.getParentTracefile().getTracefilePath(), this.getName()), | |
221 | jniEvent); | |
222 | } | |
223 | catch (LttngException e) { | |
224 | System.out.println("ERROR : Event creation returned :" + e.getMessage() ); | |
5d10d135 | 225 | } |
88144d4a | 226 | |
3fbd810a | 227 | return event; |
5d10d135 ASL |
228 | } |
229 | ||
5d10d135 | 230 | /** |
07d9e2ee FC |
231 | * Seek (move) to a certain location in the trace.<p> |
232 | * | |
3fbd810a | 233 | * WARNING : No event is read by this function, it just seek to a certain time.<br> |
07d9e2ee | 234 | * Use "parseEvent()" or "getNextEvent()" to get the event we seeked to. |
5d10d135 | 235 | * |
3fbd810a FC |
236 | * @param location a TmfTimestamp of a position in the trace |
237 | * | |
07d9e2ee | 238 | * @return TmfTraceContext pointing the position in the trace at the seek location |
5d10d135 | 239 | */ |
d2fe33b6 | 240 | public TmfTraceContext seekLocation(Object location) { |
6d848cce | 241 | |
35c72307 FC |
242 | LttngTimestamp timestamp = null; |
243 | ||
244 | // If location is null, interpret this as a request to get back to the beginning of the trace | |
07d9e2ee | 245 | // in that case, just change the location, the seek will happen below |
6d848cce FC |
246 | if (location == null) { |
247 | location = getStartTime(); | |
5d10d135 | 248 | } |
35c72307 | 249 | |
3fbd810a FC |
250 | if (location instanceof TmfTimestamp) { |
251 | long value = ((TmfTimestamp) location).getValue(); | |
6d848cce | 252 | if (value != currentJniTrace.getCurrentEventTimestamp().getTime()) { |
35c72307 FC |
253 | synchronized (currentJniTrace) { |
254 | currentJniTrace.seekToTime(new JniTime(value)); | |
255 | timestamp = (LttngTimestamp) getCurrentLocation(); | |
256 | } | |
6d848cce | 257 | } |
5d10d135 ASL |
258 | } |
259 | else { | |
6d848cce | 260 | System.out.println("ERROR : Location not instance of TmfTimestamp"); |
5d10d135 | 261 | } |
98029bc9 FC |
262 | |
263 | // FIXME: LTTng hack - start | |
07d9e2ee | 264 | // return new TmfTraceContext(timestamp, timestamp, 0); // Original |
98029bc9 FC |
265 | return new TmfTraceContext(timestamp, timestamp, -1); // Hacked |
266 | // FIXME: LTTng hack - end | |
3fbd810a FC |
267 | } |
268 | ||
269 | /** | |
07d9e2ee | 270 | * Location (timestamp) of our current position in the trace.<p> |
3fbd810a | 271 | * |
07d9e2ee | 272 | * @return The time (in LttngTimestamp format) of the current event or AFTER endTime if no more event is available. |
3fbd810a FC |
273 | */ |
274 | @Override | |
275 | public Object getCurrentLocation() { | |
276 | ||
277 | LttngTimestamp returnedLocation = null; | |
278 | JniEvent tmpJniEvent = currentJniTrace.findNextEvent(); | |
279 | ||
280 | if ( tmpJniEvent != null ) { | |
35c72307 | 281 | returnedLocation = new LttngTimestamp(tmpJniEvent.getEventTime().getTime()); |
3fbd810a FC |
282 | } |
283 | else { | |
284 | returnedLocation = new LttngTimestamp( getEndTime().getValue() + 1 ); | |
285 | } | |
286 | ||
287 | return returnedLocation; | |
288 | } | |
289 | ||
290 | /** | |
07d9e2ee FC |
291 | * Reference to the current LttngTrace we are reading from.<p> |
292 | * | |
293 | * Note : This bypass the framework and should not be use, except for testing! | |
294 | * | |
295 | * @return Reference to the current LttngTrace | |
3fbd810a | 296 | * |
3fbd810a FC |
297 | * @see org.eclipse.linuxtools.lttng.jni.JniTrace |
298 | */ | |
299 | public JniTrace getCurrentJniTrace() { | |
300 | return currentJniTrace; | |
301 | } | |
302 | ||
303 | ||
304 | /** | |
305 | * Return a reference to the current LttngEvent we have in memory. | |
306 | * | |
07d9e2ee FC |
307 | * @return The current (last read) LttngEvent |
308 | * | |
3fbd810a FC |
309 | * @see org.eclipse.linuxtools.lttng.event.LttngEvent |
310 | */ | |
311 | public LttngEvent getCurrentEvent() { | |
312 | return currentLttngEvent; | |
313 | } | |
314 | ||
315 | ||
316 | @Override | |
cc6eec3e | 317 | public String toString() { |
3fbd810a FC |
318 | String returnedData=""; |
319 | ||
320 | returnedData += "Path :" + getPath() + " "; | |
321 | returnedData += "Trace:" + currentJniTrace + " "; | |
322 | returnedData += "Event:" + currentLttngEvent; | |
323 | ||
324 | return returnedData; | |
325 | } | |
326 | ||
07d9e2ee | 327 | } |