Skip to content
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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -181,5 +181,16 @@ public boolean equals(@Nullable Object obj) {
Objects.equals(fParent, other.getParent()) &&
Objects.equals(getSymbol(), other.getSymbol()));
}

private long getChildIntersection(TmfTimeRange chlInt) {
Copy link
Contributor

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 ?

long intersection = 0;
for (TmfTimeRange childInterval:fChildrenIntervals ) {
TmfTimeRange intersect = chlInt.getIntersection(childInterval);
if (intersect!=null) {
intersection += (intersect.getEndTime().getValue())-(intersect.getStartTime().getValue());
}
}
return intersection;
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Copy link
Contributor

Choose a reason for hiding this comment

The 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,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@
class="org.eclipse.tracecompass.incubator.internal.opentracing.core.trace.OpenTracingExperiment">
</tracetype>
</module>
<module
Copy link
Contributor

Choose a reason for hiding this comment

The 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">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
package org.eclipse.tracecompass.incubator.internal.opentracing.core;

import org.eclipse.tracecompass.common.core.TraceCompassActivator;
import org.eclipse.tracecompass.incubator.concurrentstatesystem.core.SpanCustomValue;
import org.eclipse.tracecompass.internal.provisional.statesystem.core.statevalue.CustomStateValue;

/**
* Activator
Expand Down Expand Up @@ -39,6 +41,7 @@ public static TraceCompassActivator getInstance() {

@Override
protected void startActions() {
CustomStateValue.registerCustomFactory(SpanCustomValue.CUSTOM_TYPE_ID, SpanCustomValue.FACTORY);
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,209 @@
package org.eclipse.tracecompass.incubator.opentracing.core.analysis.callstack;
Copy link
Contributor

Choose a reason for hiding this comment

The 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 {
Copy link
Contributor

Choose a reason for hiding this comment

The 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$
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use CallStackStateProvider.PROCESSES.


/**
* Unknown process ID
*
* @since 2.0
*/
public static final int UNKNOWN_PID = -1;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use CallStackStateProvider.UNKNOWN_PID


/**
* Unknown name
*
* @since 2.0
*/
public static final String UNKNOWN = "UNKNOWN"; //$NON-NLS-1$
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should use CallStackStateProvider.UNKNOWN.



private static final int MAX_STACK_DEPTH = 100000;

private final Map<String, Integer> fStackDepthMap;
private TreeMap<Long, List<Integer>> fPrevEvent;
Copy link
Contributor

Choose a reason for hiding this comment

The 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<>();
Copy link
Contributor

Choose a reason for hiding this comment

The 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));
Copy link
Contributor

Choose a reason for hiding this comment

The 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");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing comment about non-exeternalized string //$NON-NLS-<n>$. Other strings in this file have the same issue.

if (fieldValue == null) {
fieldValue = event.getContent().getFieldValue(Long.class, "trace_id_low");
}

return fieldValue == null ? "eduroam" : Long.toHexString(fieldValue);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why eduroam ?

}

protected int getProcessId(ITmfEvent event) {
Long resolve = event.getContent().getFieldValue(Long.class, "trace_id");
return resolve == null ? -1 : resolve.intValue();
Copy link
Contributor

Choose a reason for hiding this comment

The 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;

Copy link
Contributor

Choose a reason for hiding this comment

The 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) {
Copy link
Contributor

Choose a reason for hiding this comment

The 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;
Copy link
Contributor

Choose a reason for hiding this comment

The 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 {
Copy link
Contributor

Choose a reason for hiding this comment

The 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();
}



}
Loading