Implement TmfTrace changes - introduce TmfTraceException
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng.core / src / org / eclipse / linuxtools / internal / lttng / core / trace / LTTngTextTrace.java
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.internal.lttng.core.trace;
14
15 import java.io.BufferedReader;
16 import java.io.FileReader;
17 import java.io.IOException;
18 import java.util.HashMap;
19
20 import org.eclipse.core.resources.IResource;
21 import org.eclipse.linuxtools.internal.lttng.core.event.LttngEvent;
22 import org.eclipse.linuxtools.internal.lttng.core.event.LttngEventContent;
23 import org.eclipse.linuxtools.internal.lttng.core.event.LttngEventField;
24 import org.eclipse.linuxtools.internal.lttng.core.event.LttngEventType;
25 import org.eclipse.linuxtools.internal.lttng.core.event.LttngTimestamp;
26 import org.eclipse.linuxtools.lttng.jni.JniEvent;
27 import org.eclipse.linuxtools.tmf.core.event.TmfTimeRange;
28 import org.eclipse.linuxtools.tmf.core.trace.ITmfContext;
29 import org.eclipse.linuxtools.tmf.core.trace.ITmfEventParser;
30 import org.eclipse.linuxtools.tmf.core.trace.ITmfLocation;
31 import org.eclipse.linuxtools.tmf.core.trace.TmfContext;
32 import org.eclipse.linuxtools.tmf.core.trace.TmfLocation;
33 import org.eclipse.linuxtools.tmf.core.trace.TmfTrace;
34
35 public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfEventParser<LttngEvent> {
36 private LttngTimestamp eventTimestamp = null;
37 private String eventSource = null;
38 private LttngEventType eventType = null;
39 private TextLttngEventContent eventContent = null;
40 private String eventReference = null;
41 // The actual event
42 private TextLttngEvent currentLttngEvent = null;
43
44 private HashMap<String, LttngEventType> traceTypes = null;
45
46 private String tracepath = ""; //$NON-NLS-1$
47 private FileReader fr = null;
48 private BufferedReader br = null;
49 private Long nbCharRead = 0L;
50
51 private int cpuNumber = -1;
52
53 private final boolean showDebug = false;
54
55 public LTTngTextTrace(final IResource resource, final String path) throws Exception {
56 this(resource, path, true); // false);
57 }
58
59 public LTTngTextTrace(final IResource resource, final String path, final boolean skipIndexing) throws Exception {
60 // super(null, LttngEvent.class, path, 1, !skipIndexing);
61 super(null, LttngEvent.class, path, 1000);
62
63 tracepath = path;
64 traceTypes = new HashMap<String, LttngEventType>();
65
66 eventTimestamp = new LttngTimestamp();
67 eventSource = "Kernel Core"; //$NON-NLS-1$
68 eventType = new LttngEventType();
69 eventContent = new TextLttngEventContent(currentLttngEvent);
70 eventReference = getName();
71
72 currentLttngEvent = new TextLttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference);
73 eventContent.setEvent(currentLttngEvent);
74
75 if ( positionToFirstEvent() == false )
76 throw new IOException("Fail to position to the beginning of the trace"); //$NON-NLS-1$
77 else {
78 // fCacheSize = 1000;
79
80 // Skip indexing if asked
81 // if ( skipIndexing == true ) {
82 // fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L), new TmfLocation<Long>(0L)));
83 ITmfContext context = new TmfContext(new TmfLocation<Long>(0L), 0);
84 fIndexer.updateIndex(context, new LttngTimestamp(0L));
85 fParser = (ITmfEventParser) this;
86 // }
87 // else {
88 // indexTrace(true);
89 // }
90
91 final Long endTime = currentLttngEvent.getTimestamp().getValue();
92 positionToFirstEvent();
93
94 readNextEvent(new TmfContext(null, 0));
95 final Long starTime = currentLttngEvent.getTimestamp().getValue();
96 positionToFirstEvent();
97
98 setTimeRange( new TmfTimeRange( new LttngTimestamp(starTime),
99 new LttngTimestamp(endTime)
100 ) );
101 }
102 }
103
104
105 public LTTngTextTrace(final LTTngTextTrace oldTrace) throws Exception {
106 this(oldTrace.getResource(), oldTrace.getPath(), true);
107
108 // *** VERIFY ***
109 // Is this safe?
110 // fCheckpoints = oldTrace.fCheckpoints;
111 }
112
113 private boolean positionToFirstEvent() {
114
115 boolean isSuccessful = true;
116
117 try {
118 if ( br != null ) {
119 br.close();
120 fr.close();
121 }
122
123 fr = new FileReader(tracepath);
124 br = new BufferedReader(fr);
125
126 // Skip the 2 lines header
127 br.readLine();
128 br.readLine();
129
130 // Make sure the event time is consistent
131 eventTimestamp.setValue(0L);
132 }
133 catch (final IOException e) {
134 isSuccessful = false;
135 }
136
137 return isSuccessful;
138 }
139
140 private void skipToPosition(final TmfLocation<Long> skip) {
141 try {
142 long skipPosition = skip.getLocation();
143 if ( skipPosition < 0 )
144 skipPosition = 0L;
145
146 if ( showDebug == true ) {
147 System.out.println("skipToPosition(Long skipPosition)"); //$NON-NLS-1$
148 System.out.println("\tSkipping to : " + skipPosition); //$NON-NLS-1$
149 System.out.println();
150 }
151 positionToFirstEvent();
152 final long nbSkipped = br.skip(skipPosition);
153 if ( nbSkipped != skipPosition)
154 throw new IOException("Too few characters skipped, positionning failed! (skipToPosition)"); //$NON-NLS-1$
155
156 nbCharRead = skipPosition;
157 }
158 catch (final Exception e) {
159 e.printStackTrace();
160 }
161 }
162
163 @Override
164 @SuppressWarnings("unchecked")
165 public TmfContext seekEvent(ITmfLocation<?> location) {
166 if (location == null)
167 location = new TmfLocation<Long>(0L);
168
169 if (!((TmfLocation<Long>) location).getLocation().equals(nbCharRead))
170 skipToPosition((TmfLocation<Long>) location);
171
172 final TmfContext tmpTraceContext = new TmfContext(location, 0L);
173
174 return tmpTraceContext;
175 }
176
177 @Override
178 public TmfContext seekEvent(final double ratio) {
179 // TODO Auto-generated method stub
180 return null;
181 }
182
183 @Override
184 public double getLocationRatio(final ITmfLocation<?> location) {
185 // TODO Auto-generated method stub
186 return 0;
187 }
188
189 private LttngEvent parseMyNextEvent(final ITmfContext context) {
190
191 // All parsing variables declared here so to be able to print them into the catch if needed
192 String tmpContent = null;
193 int tmpCurIndex = 0;
194 int tmpPrevIndex = 0;
195
196 String tracefile = ""; //$NON-NLS-1$
197 long tmpCpu = 0;
198 String marker = ""; //$NON-NLS-1$
199
200 long tmpSecond = 0;
201 long tmpNanosecond = 0;
202
203 String parsedPayload = ""; //$NON-NLS-1$
204 String markerName = ""; //$NON-NLS-1$
205 Object payload = ""; //$NON-NLS-1$
206
207 HashMap<String, LttngEventField> fieldsMap = null;
208
209 LttngEvent returnedEvent = null;
210
211 try {
212 tmpContent = br.readLine();
213
214 if (tmpContent != null) {
215 // *** NOTE :
216 // -1 is the skip the end of line (\n)
217 nbCharRead += (tmpContent.length()+1);
218
219 if ( (currentLttngEvent != null) && (currentLttngEvent.getContent().getMapContent() != null) )
220 currentLttngEvent.getContent().emptyContent();
221
222 // Tracefile and marker are first in the file
223 // Sound like :
224 // kernel.syscall_entry:
225 tmpCurIndex = tmpContent.indexOf(".", tmpPrevIndex); //$NON-NLS-1$
226
227 // *** HACK ***
228 // Evil exit case here : the two last line of the text dump does not contain "."
229 // We should check in a better way (string comparison and such) but it make the whole process to weight a lot more
230 // Conclusion : this is ugly but fast.
231 if ( tmpCurIndex < 0 ) {
232 if ( showDebug == true ) {
233 System.out.println("END OF FILE."); //$NON-NLS-1$
234 System.out.println();
235 }
236 return null;
237 }
238
239 tracefile = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
240 /*System.out.println(tracefile);*/
241
242 tmpPrevIndex = tmpCurIndex;
243 tmpCurIndex = tmpContent.indexOf(":", tmpPrevIndex); //$NON-NLS-1$
244 marker = tmpContent.substring(tmpPrevIndex+1, tmpCurIndex ).trim();
245 /*System.out.println(marker);*/
246
247 // Timestamp is next but is presented in second.milisecond format, we have to split them
248 // Sound like :
249 // 952.162637168
250 tmpPrevIndex = tmpCurIndex+1;
251 tmpCurIndex = tmpContent.indexOf(".", tmpPrevIndex); //$NON-NLS-1$
252 tmpSecond = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() );
253 /*System.out.println(tmpSecond);*/
254
255 tmpPrevIndex = tmpCurIndex+1;
256 tmpCurIndex = tmpContent.indexOf(" ", tmpPrevIndex); //$NON-NLS-1$
257 tmpNanosecond = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() );
258 /*System.out.println(tmpNanosecond);*/
259
260 // We have enough information here to set the timestamp
261 eventTimestamp.setValue( (tmpSecond * 1000000000) + tmpNanosecond );
262 /*System.out.println(eventTimestamp.toString());*/
263
264 // Next field is the reference
265 // A long string enclosed by parenthesis and ending with a comma
266 // (/home/william/workspace/org.eclipse.linuxtools.lttng.tests/traceset/trace-618339events-1293lost-1cpu/kernel_0),
267 tmpPrevIndex = tmpCurIndex+1;
268 tmpCurIndex = tmpContent.indexOf("(", tmpPrevIndex); //$NON-NLS-1$
269 tmpPrevIndex = tmpCurIndex+1;
270 tmpCurIndex = tmpContent.indexOf("),", tmpPrevIndex); //$NON-NLS-1$
271 final String fullTracePath = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
272 /*System.out.println(fullTracePath);*/
273
274 final String traceName = fullTracePath.substring(fullTracePath.lastIndexOf("/")+1).trim(); //$NON-NLS-1$
275 /*System.out.println(traceName);*/
276 eventReference = traceName;
277 currentLttngEvent.setReference(traceName);
278
279
280 // The next few fields are relatives to the state system (pid, ppid, etc...) we need to skip them.
281 // They should be like the following :
282 // 4175, 4175, hal-acl-tool, , 4168,
283
284 // 1st comma
285 tmpPrevIndex = tmpCurIndex+1;
286 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
287 // 2nd comma
288 tmpPrevIndex = tmpCurIndex+1;
289 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
290 // 3rd comma
291 tmpPrevIndex = tmpCurIndex+1;
292 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
293 // 4th comma
294 tmpPrevIndex = tmpCurIndex+1;
295 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
296 // 5th comma
297 tmpPrevIndex = tmpCurIndex+1;
298 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
299 // 6th comma
300 tmpPrevIndex = tmpCurIndex+1;
301 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
302
303 // The next field is the CPU, in hexadecimal format
304 // Should be like :
305 // 0x0,
306 tmpPrevIndex = tmpCurIndex+1;
307 tmpCurIndex = tmpContent.indexOf("0x", tmpPrevIndex); //$NON-NLS-1$
308 tmpPrevIndex = tmpCurIndex+2;
309
310 tmpCurIndex = tmpContent.indexOf(",", tmpPrevIndex); //$NON-NLS-1$
311 tmpCpu = Long.parseLong( tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim() );
312
313 // Set the cpu number of trace if we found a "new" cpu
314 if ( cpuNumber < (tmpCpu + 1) )
315 cpuNumber = (int)(tmpCpu+1);
316
317
318 // The last field is the parsed content
319 // It is enclosed by { }
320 // Look like :
321 // SYSCALL { ip = 0xb7f05422, syscall_id = 221 [sys_fcntl64+0x0/0x79] }
322 //
323 // NOTE : it seems some state system events do not respect this format as they have no payload.
324 // We will create empty payload then.
325 final int tmpIndex = tmpContent.indexOf("{", tmpPrevIndex); //$NON-NLS-1$
326 if ( tmpIndex != -1 ) {
327 tmpPrevIndex = tmpCurIndex+1;
328 tmpCurIndex = tmpIndex;
329 tmpPrevIndex = tmpCurIndex+1;
330 tmpCurIndex = tmpContent.indexOf("}", tmpPrevIndex); //$NON-NLS-1$
331 parsedPayload = tmpContent.substring(tmpPrevIndex, tmpCurIndex ).trim();
332
333 // Now add each LttngField
334 boolean isDone = false;
335 int tmpIndexBegin = 0;
336 int tmpIndexEqual = 0;
337 int tmpIndexEnd = 0;
338
339 fieldsMap = new HashMap<String, LttngEventField>();
340
341 while ( isDone == false ) {
342 tmpIndexEqual = parsedPayload.indexOf("=", tmpIndexBegin); //$NON-NLS-1$
343 tmpIndexEnd = parsedPayload.indexOf(", ", tmpIndexEqual); //$NON-NLS-1$
344 if ( tmpIndexEnd == -1 ) {
345 tmpIndexEnd = parsedPayload.length();
346 isDone = true;
347 }
348
349 markerName = parsedPayload.substring(tmpIndexBegin, tmpIndexEqual-1 ).trim();
350 payload = parsedPayload.substring(tmpIndexEqual+1, tmpIndexEnd ).replace("\"", " ").trim(); //$NON-NLS-1$ //$NON-NLS-2$
351
352 // Try to cast the payload into the correct type
353 try {
354 payload = Long.parseLong((String)payload);
355 }
356 catch (final NumberFormatException e) { }
357
358 final LttngEventField tmpField = new LttngEventField(markerName, payload);
359 fieldsMap.put(markerName, tmpField);
360
361 tmpIndexBegin = tmpIndexEnd+1;
362 }
363 }
364 else {
365 fieldsMap = new HashMap<String, LttngEventField>();
366
367 markerName = ""; //$NON-NLS-1$
368 payload = ""; //$NON-NLS-1$
369
370 final LttngEventField tmpField = new LttngEventField(markerName, payload);
371 fieldsMap.put(markerName, tmpField);
372 }
373
374 eventContent = new TextLttngEventContent(currentLttngEvent, fieldsMap);
375
376 // We now have what we need for the type
377 final String tmpTypeKey = tracefile + "/" + tmpCpu + "/" + marker; //$NON-NLS-1$ //$NON-NLS-2$
378 if ( traceTypes.get(tmpTypeKey) == null )
379 traceTypes.put(tmpTypeKey, new LttngEventType(tracefile, tmpCpu, marker, 0, fieldsMap.keySet().toArray(new String[fieldsMap.size()] )) );
380
381 currentLttngEvent.setContent(eventContent);
382 currentLttngEvent.setType(traceTypes.get(tmpTypeKey));
383
384 returnedEvent = currentLttngEvent;
385 }
386 else if ( showDebug == true ) {
387 System.out.println("NULL READING"); //$NON-NLS-1$
388 System.out.println();
389 returnedEvent = null;
390 }
391 }
392 catch (final Exception e) {
393 System.out.println("Pos is :" + nbCharRead); //$NON-NLS-1$
394 if ( tmpContent != null )
395 System.out.println("Erroneous content is :" + tmpContent); //$NON-NLS-1$
396
397 tmpContent = null;
398 e.printStackTrace();
399 returnedEvent = null;
400 }
401
402 return returnedEvent;
403 }
404
405 @Override
406 public ITmfLocation<?> getCurrentLocation() {
407 return new TmfLocation<Long>(nbCharRead);
408 }
409
410 @Override
411 public LttngEvent parseEvent(ITmfContext context) {
412 context = seekEvent(context.getLocation());
413 return parseMyNextEvent(context);
414
415 }
416
417 public int getCpuNumber() {
418 return cpuNumber;
419 }
420
421 }
422
423
424 // Redefine event to override method we know won't work with a Text tracefile
425 class TextLttngEvent extends LttngEvent {
426
427 public TextLttngEvent( final TmfTrace<LttngEvent> parent,
428 final LttngTimestamp timestamp,
429 final String source,
430 final LttngEventType type,
431 final LttngEventContent content,
432 final String reference)
433 {
434 super(parent, timestamp, source, type, content, reference, null);
435 }
436
437 @SuppressWarnings("unchecked")
438 public TextLttngEvent(final TextLttngEvent oldEvent) {
439 this(
440 (TmfTrace<LttngEvent>) oldEvent.getTrace(),
441 (LttngTimestamp)oldEvent.getTimestamp(),
442 oldEvent.getSource(),
443 oldEvent.getType(),
444 oldEvent.getContent(),
445 oldEvent.getReference()
446 );
447 }
448
449 @Override
450 public JniEvent convertEventTmfToJni() {
451 // System.out.println("WARNING : Cannot use convertEventTmfToJni() on a trace in text format."); //$NON-NLS-1$
452 return null;
453 }
454
455 @Override
456 public void updateJniEventReference(final JniEvent newJniEventReference) {
457 // System.out.println("WARNING : Cannot use updateJniEventReference on a trace in text format. Using null."); //$NON-NLS-1$
458 }
459 }
460
461
462 class TextLttngEventContent extends LttngEventContent {
463
464 public TextLttngEventContent() {
465 super();
466 }
467
468 public TextLttngEventContent(final TextLttngEvent thisParent) {
469 super(thisParent, null);
470 }
471
472 public TextLttngEventContent(final TextLttngEvent thisParent, final HashMap<String, LttngEventField> thisContent) {
473 super(thisParent, thisContent);
474 }
475
476 public TextLttngEventContent(final TextLttngEventContent oldContent) {
477 this(((TextLttngEvent) oldContent.getEvent()), oldContent.getMapContent());
478 }
479
480 @Override
481 public LttngEventField[] getFields() {
482 return getMapContent().values().toArray(new LttngEventField[getMapContent().size()]);
483 }
484
485 @Override
486 public LttngEventField getField(final String name) {
487 final LttngEventField returnedField = getMapContent().get(name);
488
489 return returnedField;
490 }
491
492 @Override
493 public LttngEventField getField(final int position) {
494 LttngEventField returnedField = null;
495 String label = null;
496 // try {
497 label = getEvent().getType().getFieldName(position);
498 returnedField = this.getField(label);
499 // }
500 // catch (TmfNoSuchFieldException e) {
501 // System.out.println("Invalid field position requested : " + position + ", ignoring (getField)."); //$NON-NLS-1$ //$NON-NLS-2$
502 // }
503
504 return returnedField;
505 }
506 }
This page took 0.04184 seconds and 5 git commands to generate.