All Downloads are FREE. Search and download functionalities are using the official Maven repository.

zipkin2.reporter.brave.internal.ZipkinProto3Fields Maven / Gradle / Ivy

There is a newer version: 3.5.1
Show newest version
/*
 * Copyright The OpenZipkin Authors
 * SPDX-License-Identifier: Apache-2.0
 */
package zipkin2.reporter.brave.internal;

import brave.Tag;
import brave.handler.MutableSpan;
import zipkin2.reporter.brave.internal.Proto3Fields.BooleanField;
import zipkin2.reporter.brave.internal.Proto3Fields.IPv4Field;
import zipkin2.reporter.brave.internal.Proto3Fields.IPv6Field;
import zipkin2.reporter.brave.internal.Proto3Fields.Utf8Field;
import zipkin2.reporter.internal.Nullable;

import static zipkin2.reporter.brave.internal.Proto3Fields.Fixed64Field;
import static zipkin2.reporter.brave.internal.Proto3Fields.HexField;
import static zipkin2.reporter.brave.internal.Proto3Fields.LengthDelimitedField;
import static zipkin2.reporter.brave.internal.Proto3Fields.VarintField;
import static zipkin2.reporter.brave.internal.Proto3Fields.WIRETYPE_FIXED64;
import static zipkin2.reporter.brave.internal.Proto3Fields.WIRETYPE_LENGTH_DELIMITED;
import static zipkin2.reporter.brave.internal.Proto3Fields.WIRETYPE_VARINT;
import static zipkin2.reporter.brave.internal.Proto3Fields.sizeOfLengthDelimitedField;

/**
 * Stripped version of {@linkplain zipkin2.internal.Proto3ZipkinFields}, without decoding logic.
 *
 * 

Also, brave has no structs for things like annotations or endpoints, so we have to flatten * some logic. * *

Finally, brave has more involved error logic, so this logic was derived from * {@link brave.internal.codec.ZipkinV2JsonWriter}. */ //@Immutable final class ZipkinProto3Fields { static class EndpointField extends Proto3Fields.Field { static final int SERVICE_NAME_KEY = (1 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int IPV4_KEY = (2 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int IPV6_KEY = (3 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int PORT_KEY = (4 << 3) | WIRETYPE_VARINT; static final Utf8Field SERVICE_NAME = new Utf8Field(SERVICE_NAME_KEY); static final IPv4Field IPV4 = new IPv4Field(IPV4_KEY); static final IPv6Field IPV6 = new IPv6Field(IPV6_KEY); static final VarintField PORT = new VarintField(PORT_KEY); EndpointField(int key) { super(key); assert wireType == WIRETYPE_LENGTH_DELIMITED; } int sizeInBytes(@Nullable String serviceName, @Nullable String ip, int port) { int sizeOfValue = sizeOfValue(serviceName, ip, port); // size is possibly zero, so don't write an empty field! return sizeOfValue > 0 ? sizeOfLengthDelimitedField(sizeOfValue) : 0; } static int sizeOfValue(@Nullable String serviceName, @Nullable String ip, int port) { int sizeInBytes = 0; sizeInBytes += SERVICE_NAME.sizeInBytes(serviceName); // MutableSpan unwraps any Ipv4 from a mapped or compatability mode IPv6. if (ip != null && ip.indexOf('.') != -1) { sizeInBytes += IPV4.sizeInBytes(ip); } else { sizeInBytes += IPV6.sizeInBytes(ip); } sizeInBytes += PORT.sizeInBytes(port); return sizeInBytes; } void write(WriteBuffer b, @Nullable String serviceName, @Nullable String ip, int port) { int sizeOfValue = sizeOfValue(serviceName, ip, port); if (sizeOfValue == 0) return; // special-case empty endpoint b.writeByte(key); b.writeVarint(sizeOfValue); // length prefix SERVICE_NAME.write(b, serviceName); // MutableSpan unwraps any Ipv4 from a mapped or compatability mode IPv6. if (ip != null && ip.indexOf('.') != -1) { IPV4.write(b, ip); } else { IPV6.write(b, ip); } PORT.write(b, port); } } static class AnnotationField extends Proto3Fields.Field { static final int TIMESTAMP_KEY = (1 << 3) | WIRETYPE_FIXED64; static final int VALUE_KEY = (2 << 3) | WIRETYPE_LENGTH_DELIMITED; static final Fixed64Field TIMESTAMP = new Fixed64Field(TIMESTAMP_KEY); static final Utf8Field VALUE = new Utf8Field(VALUE_KEY); AnnotationField(int key) { super(key); assert wireType == WIRETYPE_LENGTH_DELIMITED; } int sizeInBytes(long timestamp, String value) { int sizeOfValue = sizeOfValue(timestamp, value); return sizeOfLengthDelimitedField(sizeOfValue); } static int sizeOfValue(long timestamp, String value) { return TIMESTAMP.sizeInBytes(timestamp) + VALUE.sizeInBytes(value); } final void write(WriteBuffer b, long timestamp, String value) { int sizeOfValue = sizeOfValue(timestamp, value); b.writeByte(key); b.writeVarint(sizeOfValue); // length prefix TIMESTAMP.write(b, timestamp); VALUE.write(b, value); } } static final class TagField extends Proto3Fields.Field { // map in proto is a special field with key, value static final int KEY_KEY = (1 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int VALUE_KEY = (2 << 3) | WIRETYPE_LENGTH_DELIMITED; static final Utf8Field KEY = new Utf8Field(KEY_KEY); static final Utf8Field VALUE = new Utf8Field(VALUE_KEY); TagField(int key) { super(key); assert wireType == WIRETYPE_LENGTH_DELIMITED; } int sizeInBytes(String key, String value) { int sizeInBytes = sizeOfValue(key, value); return sizeOfLengthDelimitedField(sizeInBytes); } static int sizeOfValue(String key, String value) { return KEY.sizeInBytes(key) + VALUE.sizeInBytes(value); } void write(WriteBuffer b, String key, String value) { if (value == null) return; int sizeOfValue = sizeOfValue(key, value); b.writeByte(this.key); b.writeVarint(sizeOfValue); // length prefix KEY.write(b, key); VALUE.write(b, value); } } /** This is the only field in the ListOfSpans type */ static class SpanField extends LengthDelimitedField { static final int TRACE_ID_KEY = (1 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int PARENT_ID_KEY = (2 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int ID_KEY = (3 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int KIND_KEY = (4 << 3) | WIRETYPE_VARINT; static final int NAME_KEY = (5 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int TIMESTAMP_KEY = (6 << 3) | WIRETYPE_FIXED64; static final int DURATION_KEY = (7 << 3) | WIRETYPE_VARINT; static final int LOCAL_ENDPOINT_KEY = (8 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int REMOTE_ENDPOINT_KEY = (9 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int ANNOTATION_KEY = (10 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int TAG_KEY = (11 << 3) | WIRETYPE_LENGTH_DELIMITED; static final int DEBUG_KEY = (12 << 3) | WIRETYPE_VARINT; static final int SHARED_KEY = (13 << 3) | WIRETYPE_VARINT; static final HexField TRACE_ID = new HexField(TRACE_ID_KEY); static final HexField PARENT_ID = new HexField(PARENT_ID_KEY); static final HexField ID = new HexField(ID_KEY); static final VarintField KIND = new VarintField(KIND_KEY); static final Utf8Field NAME = new Utf8Field(NAME_KEY); static final Fixed64Field TIMESTAMP = new Fixed64Field(TIMESTAMP_KEY); static final VarintField DURATION = new VarintField(DURATION_KEY); static final EndpointField LOCAL_ENDPOINT = new EndpointField(LOCAL_ENDPOINT_KEY); static final EndpointField REMOTE_ENDPOINT = new EndpointField(REMOTE_ENDPOINT_KEY); static final AnnotationField ANNOTATION = new AnnotationField(ANNOTATION_KEY); static final TagField TAG = new TagField(TAG_KEY); static final BooleanField DEBUG = new BooleanField(DEBUG_KEY); static final BooleanField SHARED = new BooleanField(SHARED_KEY); final Tag errorTag; SpanField(Tag errorTag) { super((1 << 3) | WIRETYPE_LENGTH_DELIMITED); if (errorTag == null) throw new NullPointerException("errorTag == null"); this.errorTag = errorTag; } @Override int sizeOfValue(MutableSpan span) { int sizeInBytes = TRACE_ID.sizeInBytes(span.traceId()); sizeInBytes += PARENT_ID.sizeInBytes(span.parentId()); sizeInBytes += ID.sizeInBytes(span.id()); sizeInBytes += KIND.sizeInBytes(span.kind() != null ? 1 : 0); sizeInBytes += NAME.sizeInBytes(span.name()); if (span.startTimestamp() != 0L) { sizeInBytes += TIMESTAMP.sizeInBytes(span.startTimestamp()); if (span.finishTimestamp() != 0L) { sizeInBytes += DURATION.sizeInBytes(span.finishTimestamp() - span.startTimestamp()); } } sizeInBytes += LOCAL_ENDPOINT.sizeInBytes(span.localServiceName(), span.localIp(), span.localPort()); sizeInBytes += REMOTE_ENDPOINT.sizeInBytes(span.remoteServiceName(), span.remoteIp(), span.remotePort()); int annotationLength = span.annotationCount(); for (int i = 0; i < annotationLength; i++) { sizeInBytes += ANNOTATION.sizeInBytes(span.annotationTimestampAt(i), span.annotationValueAt(i)); } int tagCount = span.tagCount(); String errorValue = errorTag.value(span.error(), null); String errorTagName = errorValue != null ? errorTag.key() : null; boolean writeError = errorTagName != null; if (tagCount > 0 || writeError) { for (int i = 0; i < tagCount; i++) { String key = span.tagKeyAt(i); if (writeError && key.equals(errorTagName)) writeError = false; sizeInBytes += TAG.sizeInBytes(key, span.tagValueAt(i)); } if (writeError) { sizeInBytes += TAG.sizeInBytes(errorTagName, errorValue); } } sizeInBytes += DEBUG.sizeInBytes(Boolean.TRUE.equals(span.debug())); sizeInBytes += SHARED.sizeInBytes(Boolean.TRUE.equals(span.shared())); return sizeInBytes; } @Override void writeValue(WriteBuffer b, MutableSpan span) { TRACE_ID.write(b, span.traceId()); PARENT_ID.write(b, span.parentId()); ID.write(b, span.id()); KIND.write(b, toByte(span.kind())); NAME.write(b, span.name()); if (span.startTimestamp() != 0L) { TIMESTAMP.write(b, span.startTimestamp()); if (span.finishTimestamp() != 0L) { DURATION.write(b, span.finishTimestamp() - span.startTimestamp()); } } LOCAL_ENDPOINT.write(b, span.localServiceName(), span.localIp(), span.localPort()); REMOTE_ENDPOINT.write(b, span.remoteServiceName(), span.remoteIp(), span.remotePort()); int annotationLength = span.annotationCount(); for (int i = 0; i < annotationLength; i++) { ANNOTATION.write(b, span.annotationTimestampAt(i), span.annotationValueAt(i)); } int tagCount = span.tagCount(); String errorValue = errorTag.value(span.error(), null); String errorTagName = errorValue != null ? errorTag.key() : null; boolean writeError = errorTagName != null; if (tagCount > 0 || writeError) { for (int i = 0; i < tagCount; i++) { String key = span.tagKeyAt(i); if (writeError && key.equals(errorTagName)) writeError = false; TAG.write(b, key, span.tagValueAt(i)); } if (writeError) { TAG.write(b, errorTagName, errorValue); } } SpanField.DEBUG.write(b, Boolean.TRUE.equals(span.debug())); SpanField.SHARED.write(b, Boolean.TRUE.equals(span.shared())); } // in java, there's no zero index for unknown int toByte(brave.Span.Kind kind) { return kind != null ? kind.ordinal() + 1 : 0; } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy