-
Notifications
You must be signed in to change notification settings - Fork 14
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
opentracing: Add flamegraph analysis to opentracing #14
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -12,12 +12,20 @@ Require-Bundle: org.eclipse.core.runtime, | |
org.eclipse.core.resources, | ||
org.eclipse.tracecompass.common.core, | ||
org.eclipse.tracecompass.tmf.core, | ||
org.eclipse.tracecompass.segmentstore.core;bundle-version="3.1.0", | ||
org.eclipse.tracecompass.incubator.callstack.core;bundle-version="0.1.4", | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Dependencies on org.eclipse.tracecompass.incubator.callstack.core and org.eclipse.tracecompass.incubator.analysis.core should be removed as these projects are mainly deprecated. Other dependencies should not include the bundle-version. |
||
org.eclipse.tracecompass.analysis.os.linux.core;bundle-version="8.2.0", | ||
org.eclipse.tracecompass.incubator.analysis.core;bundle-version="0.1.1", | ||
org.eclipse.tracecompass.analysis.counters.core;bundle-version="2.2.1", | ||
org.eclipse.tracecompass.analysis.timing.core;bundle-version="5.5.0", | ||
com.google.gson, | ||
com.google.guava, | ||
org.apache.commons.lang3, | ||
org.eclipse.tracecompass.ctf.core, | ||
org.eclipse.tracecompass.jsontrace.core, | ||
org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional | ||
org.eclipse.jdt.annotation;bundle-version="[2.0.0,3.0.0)";resolution:=optional, | ||
org.eclipse.tracecompass.datastore.core;bundle-version="1.3.0", | ||
org.eclipse.tracecompass.incubator.concurrentcallstack.core;bundle-version="0.1.0" | ||
Export-Package: org.eclipse.tracecompass.incubator.internal.opentracing.core;x-friends:="org.eclipse.tracecompass.incubator.opentracing.core.tests", | ||
org.eclipse.tracecompass.incubator.internal.opentracing.core.analysis.spanlife;x-friends:="org.eclipse.tracecompass.incubator.opentracing.core.tests,org.eclipse.tracecompass.incubator.opentracing.ui", | ||
org.eclipse.tracecompass.incubator.internal.opentracing.core.event, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,6 +40,18 @@ | |
class="org.eclipse.tracecompass.incubator.internal.opentracing.core.trace.OpenTracingExperiment"> | ||
</tracetype> | ||
</module> | ||
<module | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The indentation and the icon should be corrected. |
||
analysis_module="org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack.OpenTracingCallstackAnalysis" | ||
automatic="false" | ||
icon="icons/callstack_view.gif" | ||
id="org.eclipse.tracecompass.incubator.opentracing.analysis.callstack" | ||
name="Open Tracing Callstack"> | ||
<tracetype | ||
applies="true" | ||
class="org.eclipse.tracecompass.incubator.internal.opentracing.core.trace.OpenTracingTrace"> | ||
</tracetype> | ||
</module> | ||
|
||
</extension> | ||
<extension | ||
point="org.eclipse.tracecompass.tmf.core.dataprovider"> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,209 @@ | ||
package org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copyright header |
||
|
||
import java.util.Arrays; | ||
import java.util.HashMap; | ||
import java.util.List; | ||
import java.util.Map; | ||
import java.util.Objects; | ||
import java.util.TreeMap; | ||
|
||
import org.eclipse.jdt.annotation.NonNull; | ||
import org.eclipse.jdt.annotation.Nullable; | ||
import org.eclipse.tracecompass.incubator.callstack.core.instrumented.statesystem.InstrumentedCallStackAnalysis; | ||
import org.eclipse.tracecompass.incubator.internal.opentracing.core.event.IOpenTracingConstants; | ||
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder; | ||
import org.eclipse.tracecompass.statesystem.core.statevalue.TmfStateValue; | ||
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent; | ||
import org.eclipse.tracecompass.tmf.core.event.ITmfEventField; | ||
import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider; | ||
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; | ||
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace; | ||
import org.eclipse.tracecompass.tmf.core.trace.TmfTraceUtils; | ||
|
||
/** | ||
* Span Callstack state provider | ||
* | ||
* @author Fateme Faraji Daneshgar | ||
* | ||
*/ | ||
public class AsincCallStackStateProvider extends AbstractTmfStateProvider { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. AsincCallStackStateProvider -> AsyncCallStackStateProvider |
||
|
||
/** | ||
* Thread attribute | ||
* | ||
* @since 2.0 | ||
*/ | ||
public static final String PROCESSES = "Processes"; //$NON-NLS-1$ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should use |
||
|
||
/** | ||
* Unknown process ID | ||
* | ||
* @since 2.0 | ||
*/ | ||
public static final int UNKNOWN_PID = -1; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should use |
||
|
||
/** | ||
* Unknown name | ||
* | ||
* @since 2.0 | ||
*/ | ||
public static final String UNKNOWN = "UNKNOWN"; //$NON-NLS-1$ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should use |
||
|
||
|
||
private static final int MAX_STACK_DEPTH = 100000; | ||
|
||
private final Map<String, Integer> fStackDepthMap; | ||
private TreeMap<Long, List<Integer>> fPrevEvent; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ideally, we do not want to track any states outside of the state system as this makes it incompatible with certain backends. |
||
private int fStateQuark = 3; | ||
|
||
/** | ||
* Constructor | ||
* | ||
* @param trace | ||
* the trace to follow | ||
*/ | ||
public AsincCallStackStateProvider(@NonNull ITmfTrace trace) { | ||
super(trace, OpenTracingCallstackAnalysis.ID); | ||
// fSpanMap = new HashMap<>(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be removed. |
||
fStackDepthMap = new HashMap<>(); | ||
fPrevEvent = new TreeMap<>(); | ||
} | ||
|
||
@Override | ||
public int getVersion() { | ||
return 3; | ||
} | ||
|
||
@Override | ||
public @NonNull ITmfStateProvider getNewInstance() { | ||
return new AsincCallStackStateProvider(getTrace()); | ||
} | ||
|
||
@Override | ||
protected void eventHandle(@NonNull ITmfEvent event) { | ||
ITmfStateSystemBuilder ss = getStateSystemBuilder(); | ||
if (ss == null) { | ||
return; | ||
} | ||
handleSpan(event,ss); | ||
} | ||
|
||
private void handleSpan(ITmfEvent event, ITmfStateSystemBuilder ss) { | ||
long timestamp = event.getTimestamp().toNanos(); | ||
if (timestamp == getTrace().getStartTime().toNanos()) { | ||
timestamp++; | ||
} | ||
Long duration = event.getContent().getFieldValue(Long.class, IOpenTracingConstants.DURATION); | ||
if (duration == null) { | ||
return; | ||
} | ||
while (!(fPrevEvent.isEmpty()) && (fPrevEvent.firstKey() < timestamp)) { | ||
long prevTime = fPrevEvent.firstKey(); | ||
List<Integer> quarks = Objects.requireNonNull(fPrevEvent.get(fPrevEvent.firstKey())); | ||
ss.modifySpanAttribute(prevTime, (Object) null, quarks.get(0), quarks.get(1)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I have errors for this call on my side. |
||
fPrevEvent.remove(fPrevEvent.firstKey()); | ||
} | ||
|
||
String processName = event.getContent().getFieldValue(String.class, IOpenTracingConstants.TRACE_ID); | ||
|
||
int processId = getProcessId(event); | ||
if (processName == null) { | ||
processName = (processId == UNKNOWN_PID) ? UNKNOWN : Integer.toString(processId); | ||
} | ||
|
||
int pq = ss.getQuarkAbsoluteAndAdd(PROCESSES, processName); | ||
ss.updateOngoingState(TmfStateValue.newValueInt(processId), 1); | ||
|
||
String Opname = String.valueOf(TmfTraceUtils.resolveAspectOfNameForEvent(event.getTrace(), "Name", event)); //$NON-NLS-1$ | ||
String spanId = event.getContent().getFieldValue(String.class, IOpenTracingConstants.SPAN_ID); | ||
String parentId = event.getContent().getFieldValue(String.class, IOpenTracingConstants.REFERENCES + "/CHILD_OF"); //$NON-NLS-1$ | ||
|
||
int callStackQuark = ss.getQuarkRelativeAndAdd(pq, InstrumentedCallStackAnalysis.CALL_STACK); | ||
int stackDepth = getStackDepth(parentId); | ||
|
||
Object functionEntryName = functionEntry(spanId, parentId, Opname); | ||
stackDepth++; | ||
|
||
int spanQuark = ss.getQuarkRelativeAndAdd(callStackQuark, String.valueOf(stackDepth)); | ||
|
||
ss.modifySpanAttribute(timestamp, functionEntryName, fStateQuark, spanQuark); | ||
|
||
fStackDepthMap.put(spanId, stackDepth); | ||
|
||
List<Integer> quarksList = Arrays.asList(fStateQuark, spanQuark); | ||
fPrevEvent.put(timestamp + duration, quarksList); | ||
fStateQuark++; | ||
|
||
} | ||
|
||
protected @Nullable String getProcessName(ITmfEvent event) { | ||
|
||
Long fieldValue = event.getContent().getFieldValue(Long.class, "trace_id"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Missing comment about non-exeternalized string |
||
if (fieldValue == null) { | ||
fieldValue = event.getContent().getFieldValue(Long.class, "trace_id_low"); | ||
} | ||
|
||
return fieldValue == null ? "eduroam" : Long.toHexString(fieldValue); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why |
||
} | ||
|
||
protected int getProcessId(ITmfEvent event) { | ||
Long resolve = event.getContent().getFieldValue(Long.class, "trace_id"); | ||
return resolve == null ? -1 : resolve.intValue(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. -1 should be replaced by the UNKNOWN_PID constant. |
||
} | ||
|
||
private int getStackDepth(String parentId) { | ||
Integer stackDepth = fStackDepthMap.get(parentId); | ||
if (stackDepth == null) { | ||
stackDepth = 0; | ||
} | ||
if (stackDepth >= MAX_STACK_DEPTH) { | ||
/* | ||
* Limit stackDepth to 100000, to avoid having Attribute Trees grow | ||
* out of control due to buggy insertions | ||
*/ | ||
String message = " Stack limit reached, not pushing"; //$NON-NLS-1$ | ||
throw new IllegalStateException(" Quark:" + parentId + message); //$NON-NLS-1$ | ||
} | ||
return stackDepth; | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This empty space should be removed as well as other formatting issue in this file. |
||
} | ||
|
||
protected @Nullable Object functionEntry(String spanId, String parentId, String name) { | ||
return new SpanCustomValue(spanId, (parentId == null) ? "0" : parentId, name); | ||
|
||
} | ||
|
||
protected Map<String, String> MessageHashMapExtractor(ITmfEventField value) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is not used anywhere ? |
||
// split the string to creat key-value pairs | ||
Map<String, String> map = new HashMap<>(); | ||
// iterate over the pairs | ||
for (ITmfEventField field : value.getFields()) { | ||
Objects.requireNonNull(field); | ||
map.put(field.getName(), field.getValue().toString().trim()); | ||
} | ||
if (map.isEmpty()) { | ||
String valueString = (String) Objects.requireNonNull(value.getValue()); | ||
String[] values = valueString.split(","); | ||
for (String tuple : values) { | ||
String[] parts = tuple.split("="); | ||
map.put(parts[0], parts[1].trim()); | ||
} | ||
} | ||
return map; | ||
} | ||
|
||
@Override | ||
public void done() { | ||
ITmfStateSystemBuilder ss = getStateSystemBuilder(); | ||
if (ss == null) { | ||
return; | ||
} | ||
while (!(fPrevEvent.isEmpty())) { | ||
long prevTime = fPrevEvent.firstKey(); | ||
List<Integer> quarks = Objects.requireNonNull(fPrevEvent.get(fPrevEvent.firstKey())); | ||
ss.modifySpanAttribute(prevTime, (Object) null, quarks.get(0), quarks.get(1)); | ||
fPrevEvent.remove(fPrevEvent.firstKey()); | ||
} | ||
} | ||
|
||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Copyright header |
||
|
||
import java.util.Collections; | ||
import java.util.Objects; | ||
|
||
import org.eclipse.jdt.annotation.NonNull; | ||
import org.eclipse.tracecompass.tmf.core.analysis.requirements.TmfAbstractAnalysisRequirement; | ||
import org.eclipse.tracecompass.tmf.core.statesystem.ITmfStateProvider; | ||
|
||
/** | ||
* | ||
*/ | ||
public class OpenTracingCallstackAnalysis extends SpanCallStackAnalysis { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why is this class needed ? |
||
/** | ||
* ID | ||
*/ | ||
public static final @NonNull String ID = "org.eclipse.tracecompass.incubator.opentracing.analysis.callstack"; //$NON-NLS-1$ | ||
|
||
|
||
@Override | ||
protected ITmfStateProvider createStateProvider() { | ||
return new AsincCallStackStateProvider(Objects.requireNonNull(getTrace())); | ||
} | ||
|
||
|
||
@Override | ||
public @NonNull Iterable<@NonNull TmfAbstractAnalysisRequirement> getAnalysisRequirements() { | ||
return Collections.emptyList(); | ||
} | ||
|
||
|
||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This change should be removed as it does not seem to be used anywhere and changes deprecated classes ?