Skip to content

Commit 08c2a78

Browse files
authored
provides support for TracingMetadata (#824)
* provides support for TracingMetadata Signed-off-by: Oleh Dokuka <[email protected]> * improves docs Signed-off-by: Oleh Dokuka <[email protected]>
1 parent a0e741c commit 08c2a78

File tree

3 files changed

+491
-0
lines changed

3 files changed

+491
-0
lines changed
Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*
2+
* Copyright 2015-2020 the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.rsocket.metadata;
18+
19+
/**
20+
* Represents decoded tracing metadata which is fully compatible with <a
21+
* href="https://github.com/openzipkin/b3-propagation/">Zipkin B3 propagation</a>
22+
*
23+
* @since 1.0
24+
*/
25+
public final class TracingMetadata {
26+
27+
final long traceIdHigh;
28+
final long traceId;
29+
private final boolean hasParentId;
30+
final long parentId;
31+
final long spanId;
32+
final boolean isEmpty;
33+
final boolean isNotSampled;
34+
final boolean isSampled;
35+
final boolean isDebug;
36+
37+
TracingMetadata(
38+
long traceIdHigh,
39+
long traceId,
40+
long spanId,
41+
boolean hasParentId,
42+
long parentId,
43+
boolean isEmpty,
44+
boolean isNotSampled,
45+
boolean isSampled,
46+
boolean isDebug) {
47+
this.traceIdHigh = traceIdHigh;
48+
this.traceId = traceId;
49+
this.spanId = spanId;
50+
this.hasParentId = hasParentId;
51+
this.parentId = parentId;
52+
this.isEmpty = isEmpty;
53+
this.isNotSampled = isNotSampled;
54+
this.isSampled = isSampled;
55+
this.isDebug = isDebug;
56+
}
57+
58+
/** When non-zero, the trace containing this span uses 128-bit trace identifiers. */
59+
public long traceIdHigh() {
60+
return traceIdHigh;
61+
}
62+
63+
/** Unique 8-byte identifier for a trace, set on all spans within it. */
64+
public long traceId() {
65+
return traceId;
66+
}
67+
68+
/** Indicates if the parent's {@link #spanId} or if this the root span in a trace. */
69+
public final boolean hasParent() {
70+
return hasParentId;
71+
}
72+
73+
/** Returns the parent's {@link #spanId} where zero implies absent. */
74+
public long parentId() {
75+
return parentId;
76+
}
77+
78+
/**
79+
* Unique 8-byte identifier of this span within a trace.
80+
*
81+
* <p>A span is uniquely identified in storage by ({@linkplain #traceId}, {@linkplain #spanId}).
82+
*/
83+
public long spanId() {
84+
return spanId;
85+
}
86+
87+
/** Indicates that trace IDs should be accepted for tracing. */
88+
public boolean isSampled() {
89+
return isSampled;
90+
}
91+
92+
/** Indicates that trace IDs should be force traced. */
93+
public boolean isDebug() {
94+
return isDebug;
95+
}
96+
97+
/** Includes that there is sampling information and no trace IDs. */
98+
public boolean isEmpty() {
99+
return isEmpty;
100+
}
101+
102+
/**
103+
* Indicated that sampling decision is present. If {@code false} means that decision is unknown
104+
* and says explicitly that {@link #isDebug()} and {@link #isSampled()} also returns {@code
105+
* false}.
106+
*/
107+
public boolean isDecided() {
108+
return isNotSampled || isDebug || isSampled;
109+
}
110+
}
Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
package io.rsocket.metadata;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.buffer.ByteBufAllocator;
5+
6+
/**
7+
* Represents codes for tracing metadata which is fully compatible with <a
8+
* href="https://github.com/openzipkin/b3-propagation/">Zipkin B3 propagation</a>
9+
*
10+
* @since 1.0
11+
*/
12+
public class TracingMetadataCodec {
13+
14+
static final int FLAG_EXTENDED_TRACE_ID_SIZE = 0b0000_1000;
15+
static final int FLAG_INCLUDE_PARENT_ID = 0b0000_0100;
16+
static final int FLAG_NOT_SAMPLED = 0b0001_0000;
17+
static final int FLAG_SAMPLED = 0b0010_0000;
18+
static final int FLAG_DEBUG = 0b0100_0000;
19+
static final int FLAG_IDS_SET = 0b1000_0000;
20+
21+
public static ByteBuf encodeEmpty(ByteBufAllocator allocator, Flags flag) {
22+
23+
return encode(allocator, true, 0, 0, false, 0, 0, false, flag);
24+
}
25+
26+
public static ByteBuf encode128(
27+
ByteBufAllocator allocator,
28+
long traceIdHigh,
29+
long traceId,
30+
long spanId,
31+
long parentId,
32+
Flags flag) {
33+
34+
return encode(allocator, false, traceIdHigh, traceId, true, spanId, parentId, true, flag);
35+
}
36+
37+
public static ByteBuf encode128(
38+
ByteBufAllocator allocator, long traceIdHigh, long traceId, long spanId, Flags flag) {
39+
40+
return encode(allocator, false, traceIdHigh, traceId, true, spanId, 0, false, flag);
41+
}
42+
43+
public static ByteBuf encode64(
44+
ByteBufAllocator allocator, long traceId, long spanId, long parentId, Flags flag) {
45+
46+
return encode(allocator, false, 0, traceId, false, spanId, parentId, true, flag);
47+
}
48+
49+
public static ByteBuf encode64(
50+
ByteBufAllocator allocator, long traceId, long spanId, Flags flag) {
51+
return encode(allocator, false, 0, traceId, false, spanId, 0, false, flag);
52+
}
53+
54+
static ByteBuf encode(
55+
ByteBufAllocator allocator,
56+
boolean isEmpty,
57+
long traceIdHigh,
58+
long traceId,
59+
boolean extendedTraceId,
60+
long spanId,
61+
long parentId,
62+
boolean includesParent,
63+
Flags flag) {
64+
int size =
65+
1
66+
+ (isEmpty
67+
? 0
68+
: (Long.BYTES
69+
+ Long.BYTES
70+
+ (extendedTraceId ? Long.BYTES : 0)
71+
+ (includesParent ? Long.BYTES : 0)));
72+
final ByteBuf buffer = allocator.buffer(size);
73+
74+
int byteFlags = 0;
75+
switch (flag) {
76+
case NOT_SAMPLE:
77+
byteFlags |= FLAG_NOT_SAMPLED;
78+
break;
79+
case SAMPLE:
80+
byteFlags |= FLAG_SAMPLED;
81+
break;
82+
case DEBUG:
83+
byteFlags |= FLAG_DEBUG;
84+
break;
85+
}
86+
87+
if (isEmpty) {
88+
return buffer.writeByte(byteFlags);
89+
}
90+
91+
byteFlags |= FLAG_IDS_SET;
92+
93+
if (extendedTraceId) {
94+
byteFlags |= FLAG_EXTENDED_TRACE_ID_SIZE;
95+
}
96+
97+
if (includesParent) {
98+
byteFlags |= FLAG_INCLUDE_PARENT_ID;
99+
}
100+
101+
buffer.writeByte(byteFlags);
102+
103+
if (extendedTraceId) {
104+
buffer.writeLong(traceIdHigh);
105+
}
106+
107+
buffer.writeLong(traceId).writeLong(spanId);
108+
109+
if (includesParent) {
110+
buffer.writeLong(parentId);
111+
}
112+
113+
return buffer;
114+
}
115+
116+
public static TracingMetadata decode(ByteBuf byteBuf) {
117+
byteBuf.markReaderIndex();
118+
try {
119+
byte flags = byteBuf.readByte();
120+
boolean isNotSampled = (flags & FLAG_NOT_SAMPLED) == FLAG_NOT_SAMPLED;
121+
boolean isSampled = (flags & FLAG_SAMPLED) == FLAG_SAMPLED;
122+
boolean isDebug = (flags & FLAG_DEBUG) == FLAG_DEBUG;
123+
boolean isIDSet = (flags & FLAG_IDS_SET) == FLAG_IDS_SET;
124+
125+
if (!isIDSet) {
126+
return new TracingMetadata(0, 0, 0, false, 0, true, isNotSampled, isSampled, isDebug);
127+
}
128+
129+
boolean extendedTraceId =
130+
(flags & FLAG_EXTENDED_TRACE_ID_SIZE) == FLAG_EXTENDED_TRACE_ID_SIZE;
131+
132+
long traceIdHigh;
133+
if (extendedTraceId) {
134+
traceIdHigh = byteBuf.readLong();
135+
} else {
136+
traceIdHigh = 0;
137+
}
138+
139+
long traceId = byteBuf.readLong();
140+
long spanId = byteBuf.readLong();
141+
142+
boolean includesParent = (flags & FLAG_INCLUDE_PARENT_ID) == FLAG_INCLUDE_PARENT_ID;
143+
144+
long parentId;
145+
if (includesParent) {
146+
parentId = byteBuf.readLong();
147+
} else {
148+
parentId = 0;
149+
}
150+
151+
return new TracingMetadata(
152+
traceIdHigh,
153+
traceId,
154+
spanId,
155+
includesParent,
156+
parentId,
157+
false,
158+
isNotSampled,
159+
isSampled,
160+
isDebug);
161+
} finally {
162+
byteBuf.resetReaderIndex();
163+
}
164+
}
165+
166+
public enum Flags {
167+
UNDECIDED,
168+
NOT_SAMPLE,
169+
SAMPLE,
170+
DEBUG
171+
}
172+
}

0 commit comments

Comments
 (0)