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