blob: 02c05c9b90485aefa772c91a741f1dff1655edf6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2018 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.incubator.internal.opentracing.core.analysis.spanlife;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiConsumer;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.incubator.internal.opentracing.core.event.IOpenTracingConstants;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.tmf.core.event.ITmfEvent;
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 life state provider
*
* @author Katherine Nadeau
*
*/
public class SpanLifeStateProvider extends AbstractTmfStateProvider {
/**
* Quark name for open tracing spans
*/
public static final String OPEN_TRACING_ATTRIBUTE = "openTracingSpans"; //$NON-NLS-1$
/**
* Quark name for ust spans
*/
public static final String UST_ATTRIBUTE = "ustSpans"; //$NON-NLS-1$
private final Map<String, Integer> fSpanMap;
private final Map<String, BiConsumer<ITmfEvent, ITmfStateSystemBuilder>> fHandlers;
/**
* Constructor
*
* @param trace
* the trace to follow
*/
public SpanLifeStateProvider(ITmfTrace trace) {
super(trace, SpanLifeAnalysis.ID);
fSpanMap = new HashMap<>();
fHandlers = new HashMap<>();
fHandlers.put("OpenTracingSpan", this::handleSpan); //$NON-NLS-1$
fHandlers.put("jaeger_ust:start_span", this::handleStart); //$NON-NLS-1$
fHandlers.put("jaeger_ust:end_span", this::handleEnd); //$NON-NLS-1$
}
@Override
public int getVersion() {
return 3;
}
@Override
public @NonNull ITmfStateProvider getNewInstance() {
return new SpanLifeStateProvider(getTrace());
}
@Override
protected void eventHandle(@NonNull ITmfEvent event) {
ITmfStateSystemBuilder ss = getStateSystemBuilder();
if (ss == null) {
return;
}
BiConsumer<ITmfEvent, ITmfStateSystemBuilder> handler = fHandlers.get(event.getType().getName());
if (handler != null) {
handler.accept(event, ss);
}
}
private void handleSpan(ITmfEvent event, ITmfStateSystemBuilder ss) {
long timestamp = event.getTimestamp().toNanos();
Long duration = event.getContent().getFieldValue(Long.class, IOpenTracingConstants.DURATION);
if (duration == null) {
return;
}
String traceId = event.getContent().getFieldValue(String.class, IOpenTracingConstants.TRACE_ID);
int traceQuark = ss.getQuarkAbsoluteAndAdd(traceId);
int openTracingSpansQuark = ss.getQuarkRelativeAndAdd(traceQuark, OPEN_TRACING_ATTRIBUTE);
Boolean errorTag = Boolean.parseBoolean(event.getContent().getFieldValue(String.class, IOpenTracingConstants.TAGS + "/error")); //$NON-NLS-1$
String processName = event.getContent().getFieldValue(String.class, IOpenTracingConstants.PROCESS_NAME);
int spanQuark;
String name = String.valueOf(TmfTraceUtils.resolveAspectOfNameForEvent(event.getTrace(), "Name", event)); //$NON-NLS-1$
String spanId = event.getContent().getFieldValue(String.class, IOpenTracingConstants.SPAN_ID);
String refId = event.getContent().getFieldValue(String.class, IOpenTracingConstants.REFERENCES + "/CHILD_OF"); //$NON-NLS-1$
if (refId == null) {
spanQuark = ss.getQuarkRelativeAndAdd(openTracingSpansQuark, name + '/' + spanId + '/' + errorTag + '/' + processName);
} else {
Integer parentQuark = fSpanMap.get(refId);
if (parentQuark == null) {
return;
}
spanQuark = ss.getQuarkRelativeAndAdd(parentQuark, name + '/' + spanId + '/' + errorTag + '/' + processName);
}
ss.modifyAttribute(timestamp, name, spanQuark);
Map<Long, Map<String, String>> logs = event.getContent().getFieldValue(Map.class, IOpenTracingConstants.LOGS);
if (logs != null) {
// We put all the logs in the state system under the LOGS attribute
Integer logsQuark = ss.getQuarkRelativeAndAdd(traceQuark, IOpenTracingConstants.LOGS);
for (Map.Entry<Long, Map<String, String>> log : logs.entrySet()) {
List<String> logString = new ArrayList<>();
for (Map.Entry<String, String> entry : log.getValue().entrySet()) {
logString.add(entry.getKey() + ':' + entry.getValue());
}
// One attribute for each span where each state value is the logs at the
// timestamp
// corresponding to the start time of the state
Integer logQuark = ss.getQuarkRelativeAndAdd(logsQuark, spanId);
Long logTimestamp = log.getKey();
ss.modifyAttribute(logTimestamp, String.join("~", logString), logQuark); //$NON-NLS-1$
ss.modifyAttribute(logTimestamp + 1, (Object) null, logQuark);
}
}
ss.modifyAttribute(timestamp + duration, (Object) null, spanQuark);
if (spanId != null) {
fSpanMap.put(spanId, spanQuark);
}
}
private void handleStart(ITmfEvent event, ITmfStateSystemBuilder ss) {
String traceId = event.getContent().getFieldValue(String.class, "trace_id_low"); //$NON-NLS-1$
traceId = Long.toHexString(Long.decode(traceId));
int traceQuark = ss.getQuarkAbsoluteAndAdd(traceId);
int ustSpansQuark = ss.getQuarkRelativeAndAdd(traceQuark, UST_ATTRIBUTE);
String spanId = event.getContent().getFieldValue(String.class, "span_id"); //$NON-NLS-1$
spanId = Long.toHexString(Long.decode(spanId));
int spanQuark = ss.getQuarkRelativeAndAdd(ustSpansQuark, spanId);
long timestamp = event.getTimestamp().toNanos();
String name = event.getContent().getFieldValue(String.class, "op_name"); //$NON-NLS-1$
ss.modifyAttribute(timestamp, name, spanQuark);
}
private void handleEnd(ITmfEvent event, ITmfStateSystemBuilder ss) {
String traceId = event.getContent().getFieldValue(String.class, "trace_id_low"); //$NON-NLS-1$
traceId = Long.toHexString(Long.decode(traceId));
int traceQuark = ss.getQuarkAbsoluteAndAdd(traceId);
int ustSpansQuark = ss.getQuarkRelativeAndAdd(traceQuark, UST_ATTRIBUTE);
String spanId = event.getContent().getFieldValue(String.class, "span_id"); //$NON-NLS-1$
spanId = Long.toHexString(Long.decode(spanId));
int spanQuark = ss.getQuarkRelativeAndAdd(ustSpansQuark, spanId);
long timestamp = event.getTimestamp().toNanos();
ss.modifyAttribute(timestamp, (Object) null, spanQuark);
}
}