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