private TraceSpan.SpanKind getKind(Span span) { for (Log log : span.logs()) { if (Span.CLIENT_SEND.equals(log.getEvent()) || Span.CLIENT_RECV.equals(log.getEvent())) { return TraceSpan.SpanKind.RPC_CLIENT; } else if (Span.SERVER_RECV.equals(log.getEvent()) || Span.SERVER_SEND.equals(log.getEvent())) { return TraceSpan.SpanKind.RPC_SERVER; } } return TraceSpan.SpanKind.SPAN_KIND_UNSPECIFIED; }
public Map<String, String> extract(Span span, TraceSpan.SpanKind kind, String instanceId) { Map<String, String> labels = new HashMap<>(); for (Map.Entry<String, String> tag : span.tags().entrySet()) { labels.put(label(tag.getKey()), tag.getValue()); } for (Log log : span.logs()) { labels.put(label(log.getEvent()), formatTimestamp(log.getTimestamp())); } if (span.tags().containsKey(Span.SPAN_PEER_SERVICE_TAG_NAME)) { labels.put("/component", span.tags().get(Span.SPAN_PEER_SERVICE_TAG_NAME)); } if (span.getParents() == null || span.getParents().isEmpty()) { labels.put("/agent", this.agentName); } if ((kind == TraceSpan.SpanKind.RPC_CLIENT || kind == TraceSpan.SpanKind.RPC_SERVER) && StringUtils.hasText(instanceId)) { if (StringUtils.hasText(instanceId)) { labels.put(label(Span.INSTANCEID), instanceId); } } return labels; }
/** * There could be instrumentation delay between span creation and the * semantic start of the span (client send). When there's a difference, * spans look confusing. Ex users expect duration to be client * receive - send, but it is a little more than that. Rather than have * to teach each user about the possibility of instrumentation overhead, * we truncate absolute duration (span finish - create) to semantic * duration (client receive - send) */ private long calculateDurationInMicros(Span span) { Log clientSend = hasLog(Span.CLIENT_SEND, span); Log clientReceived = hasLog(Span.CLIENT_RECV, span); if (clientSend != null && clientReceived != null) { return (clientReceived.getTimestamp() - clientSend.getTimestamp()) * 1000; } return span.getAccumulatedMicros(); }
void processLogs(Span span, zipkin2.Span.Builder zipkinSpan) { for (Log log : span.logs()) { String event = log.getEvent(); long micros = log.getTimestamp() * 1000L; // don't add redundant annotations to the output if (event.length() == 2) { if (event.equals("cs")) { zipkinSpan.kind(zipkin2.Span.Kind.CLIENT); } else if (event.equals("sr")) { zipkinSpan.kind(zipkin2.Span.Kind.SERVER); } else if (event.equals("ss")) { zipkinSpan.kind(zipkin2.Span.Kind.SERVER); } else if (event.equals("cr")) { zipkinSpan.kind(zipkin2.Span.Kind.CLIENT); } else if (event.equals("ms")) { zipkinSpan.kind(zipkin2.Span.Kind.PRODUCER); } else if (event.equals("mr")) { zipkinSpan.kind(zipkin2.Span.Kind.CONSUMER); } else { zipkinSpan.addAnnotation(micros, event); } } else { zipkinSpan.addAnnotation(micros, event); } } }
private void writeStartEndTime(Span span, TraceSpan.Builder builder) { if (!span.isRemote()) { Log clientSend = findLog(span, Span.CLIENT_SEND); Log clientReceive = findLog(span, Span.CLIENT_RECV); if (clientSend != null) { builder.setStartTime(createTimestamp(clientSend.getTimestamp())); } else { builder.setStartTime(createTimestamp(span.getBegin())); } if (!span.isRunning()) { if (clientReceive != null) { builder.setEndTime(createTimestamp(clientReceive.getTimestamp())); } else { builder.setEndTime(createTimestamp(span.getEnd())); } } } }
private Log findLog(Span span, String event) { for (Log log : span.logs()) { if (event.equals(log.getEvent())) { return log; } } return null; }
private Log hasLog(String logName, Span span) { for (Log log : span.logs()) { if (logName.equals(log.getEvent())) { return log; } } return null; }