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