eb15be80d871dc7fc03947d5fa68dbfdefd2573c
[deliverable/tracecompass.git] / org.eclipse.linuxtools.lttng / 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.ITmfTrace;
32 import org.eclipse.linuxtools.tmf.trace.TmfCheckpoint;
33 import org.eclipse.linuxtools.tmf.trace.TmfContext;
34 import org.eclipse.linuxtools.tmf.trace.TmfLocation;
35 import org.eclipse.linuxtools.tmf.trace.TmfTrace;
36
37 public class LTTngTextTrace extends TmfTrace<LttngEvent> implements ITmfTrace {
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
55 private boolean showDebug = false;
56
57 public LTTngTextTrace(String path) throws Exception {
58 this(path, false);
59 }
60
61 public LTTngTextTrace(String path, boolean skipIndexing) throws Exception {
62 super(path, LttngEvent.class, path, 1);
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
73 currentLttngEvent = new TextLttngEvent(this, eventTimestamp, eventSource, eventType, eventContent, eventReference);
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 {
80 fIndexPageSize = 1000;
81
82 // Skip indexing if asked
83 if ( skipIndexing == true ) {
84 fCheckpoints.add(new TmfCheckpoint(new LttngTimestamp(0L), new TmfLocation<Long>(0L)));
85 }
86 else {
87 indexTrace(true);
88 }
89
90 Long endTime = currentLttngEvent.getTimestamp().getValue();
91 positionToFirstEvent();
92
93 getNextEvent(new TmfContext(null, 0));
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
104 public LTTngTextTrace(LTTngTextTrace oldTrace) throws Exception {
105 this(oldTrace.getPath(), true);
106
107 // *** VERIFY ***
108 // Is this safe?
109 fCheckpoints = oldTrace.fCheckpoints;
110 }
111
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
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 (Exception 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)");
162 System.out.println("\tSkipping to : " + skipPosition);
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)");
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 private LttngEvent parseMyNextEvent(TmfContext context) {
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 "."
239 // We should check in a better way (string comparison and such) but it make the whole process to weight a lot more
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 }
246 return null;
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 //
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.
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 }
375 }
376 else {
377 fieldsMap = new HashMap<String, LttngEventField>();
378
379 markerName = "";
380 payload = "";
381
382 LttngEventField tmpField = new LttngEventField(eventContent, markerName, payload);
383 fieldsMap.put(markerName, tmpField);
384 }
385
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
397 returnedEvent = currentLttngEvent;
398 }
399 else if ( showDebug == true ) {
400 System.out.println("NULL READING");
401 System.out.println();
402 returnedEvent = null;
403 }
404 }
405 catch (Exception e) {
406 System.out.println("Pos is :" + nbCharRead);
407 if ( tmpContent != null ) {
408 System.out.println("Erroneous content is :" + tmpContent);
409 }
410
411 tmpContent = null;
412 e.printStackTrace();
413 returnedEvent = null;
414 }
415
416 return returnedEvent;
417 }
418
419 @Override
420 public ITmfLocation<?> getCurrentLocation() {
421 return new TmfLocation<Long>(nbCharRead);
422 }
423
424 @Override
425 public LttngEvent parseEvent(TmfContext context) {
426 context = seekLocation(context.getLocation());
427 return parseMyNextEvent(context);
428
429 }
430
431 public int getCpuNumber() {
432 return cpuNumber;
433 }
434 }
435
436
437 // Redefine event to override method we know won't work with a Text tracefile
438 class TextLttngEvent extends LttngEvent {
439
440 public TextLttngEvent( TmfTrace<LttngEvent> parent,
441 LttngTimestamp timestamp,
442 LttngEventSource source,
443 LttngEventType type,
444 LttngEventContent content,
445 LttngEventReference reference)
446 {
447 super(parent, timestamp, source, type, content, reference, null);
448 }
449
450 public TextLttngEvent(TextLttngEvent oldEvent) {
451 this(
452 oldEvent.getParentTrace(),
453 (LttngTimestamp)oldEvent.getTimestamp(),
454 (LttngEventSource)oldEvent.getSource(),
455 (LttngEventType)oldEvent.getType(),
456 (LttngEventContent)oldEvent.getContent(),
457 (LttngEventReference)oldEvent.getReference()
458 );
459 }
460
461 @Override
462 public JniEvent convertEventTmfToJni() {
463 System.out.println("WARNING : Cannot use convertEventTmfToJni() on a trace in text format.");
464 return null;
465 }
466
467 @Override
468 public void updateJniEventReference(JniEvent newJniEventReference) {
469 System.out.println("WARNING : Cannot use updateJniEventReference on a trace in text format. Using null.");
470 }
471 }
472
473
474 class TextLttngEventContent extends LttngEventContent {
475
476 public TextLttngEventContent() {
477 super();
478 }
479
480 public TextLttngEventContent(TextLttngEvent thisParent) {
481 super(thisParent, null);
482 }
483
484 public TextLttngEventContent(TextLttngEvent thisParent, HashMap<String, LttngEventField> thisContent) {
485 super(thisParent, thisContent);
486 }
487
488 public TextLttngEventContent(TextLttngEventContent oldContent) {
489 this( (TextLttngEvent)oldContent.fParentEvent, oldContent.getRawContent());
490 }
491
492 @Override
493 public LttngEventField[] getFields() {
494 return getRawContent().values().toArray(new LttngEventField[getRawContent().size()]);
495 }
496
497 @Override
498 public LttngEventField getField(String name) {
499 LttngEventField returnedField = getRawContent().get(name);
500
501 return returnedField;
502 }
503
504 @Override
505 public LttngEventField getField(int position) {
506 LttngEventField returnedField = null;
507 String label = null;
508 try {
509 label = fParentEvent.getType().getLabel(position);
510 returnedField = this.getField(label);
511 }
512 catch (TmfNoSuchFieldException e) {
513 System.out.println("Invalid field position requested : " + position + ", ignoring (getField).");
514 }
515
516 return returnedField;
517 }
518 }
This page took 0.043302 seconds and 4 git commands to generate.