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