Skip to content

Commit 419c5d1

Browse files
committed
provides support for TracingMetadata
Signed-off-by: Oleh Dokuka <[email protected]>
1 parent d880f51 commit 419c5d1

File tree

3 files changed

+479
-0
lines changed

3 files changed

+479
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
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+
public final class TracingMetadata {
20+
21+
final long traceIdHigh;
22+
final long traceId;
23+
private final boolean hasParentId;
24+
final long parentId;
25+
final long spanId;
26+
final boolean isEmpty;
27+
final boolean isNotSampled;
28+
final boolean isSampled;
29+
final boolean isDebug;
30+
31+
TracingMetadata(
32+
long traceIdHigh,
33+
long traceId,
34+
long spanId,
35+
boolean hasParentId,
36+
long parentId,
37+
boolean isEmpty,
38+
boolean isNotSampled,
39+
boolean isSampled,
40+
boolean isDebug) {
41+
this.traceIdHigh = traceIdHigh;
42+
this.traceId = traceId;
43+
this.spanId = spanId;
44+
this.hasParentId = hasParentId;
45+
this.parentId = parentId;
46+
this.isEmpty = isEmpty;
47+
this.isNotSampled = isNotSampled;
48+
this.isSampled = isSampled;
49+
this.isDebug = isDebug;
50+
}
51+
52+
/** When non-zero, the trace containing this span uses 128-bit trace identifiers. */
53+
public long traceIdHigh() {
54+
return traceIdHigh;
55+
}
56+
57+
/** Unique 8-byte identifier for a trace, set on all spans within it. */
58+
public long traceId() {
59+
return traceId;
60+
}
61+
62+
/** Indicates if the parent's {@link #spanId} or if this the root span in a trace. */
63+
public final boolean hasParent() {
64+
return hasParentId;
65+
}
66+
67+
/** Returns the parent's {@link #spanId} where zero implies absent. */
68+
public long parentId() {
69+
return parentId;
70+
}
71+
72+
/**
73+
* Unique 8-byte identifier of this span within a trace.
74+
*
75+
* <p>A span is uniquely identified in storage by ({@linkplain #traceId}, {@linkplain #spanId}).
76+
*/
77+
public long spanId() {
78+
return spanId;
79+
}
80+
81+
/** Indicates that trace IDs should be accepted for tracing. */
82+
public boolean isSampled() {
83+
return isSampled;
84+
}
85+
86+
/** Indicates that trace IDs should be force traced. */
87+
public boolean isDebug() {
88+
return isDebug;
89+
}
90+
91+
/** Includes that there is sampling information and no trace IDs. */
92+
public boolean isEmpty() {
93+
return isEmpty;
94+
}
95+
96+
/**
97+
* Indicated that sampling decision is present. If {@code false} means that decision is unknown
98+
* and says explicitly that {@link #isDebug()} and {@link #isSampled()} also returns {@code
99+
* false}.
100+
*/
101+
public boolean isDecided() {
102+
return isNotSampled || isDebug || isSampled;
103+
}
104+
}
Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
package io.rsocket.metadata;
2+
3+
import io.netty.buffer.ByteBuf;
4+
import io.netty.buffer.ByteBufAllocator;
5+
6+
public class TracingMetadataCodec {
7+
8+
static final int FLAG_EXTENDED_TRACE_ID_SIZE = 0b0000_1000;
9+
static final int FLAG_INCLUDE_PARENT_ID = 0b0000_0100;
10+
static final int FLAG_NOT_SAMPLED = 0b0001_0000;
11+
static final int FLAG_SAMPLED = 0b0010_0000;
12+
static final int FLAG_DEBUG = 0b0100_0000;
13+
static final int FLAG_IDS_SET = 0b1000_0000;
14+
15+
public static ByteBuf encodeEmpty(ByteBufAllocator allocator, Flags flag) {
16+
17+
return encode(allocator, true, 0, 0, false, 0, 0, false, flag);
18+
}
19+
20+
public static ByteBuf encode128(
21+
ByteBufAllocator allocator,
22+
long traceIdHigh,
23+
long traceId,
24+
long spanId,
25+
long parentId,
26+
Flags flag) {
27+
28+
return encode(allocator, false, traceIdHigh, traceId, true, spanId, parentId, true, flag);
29+
}
30+
31+
public static ByteBuf encode128(
32+
ByteBufAllocator allocator, long traceIdHigh, long traceId, long spanId, Flags flag) {
33+
34+
return encode(allocator, false, traceIdHigh, traceId, true, spanId, 0, false, flag);
35+
}
36+
37+
public static ByteBuf encode64(
38+
ByteBufAllocator allocator, long traceId, long spanId, long parentId, Flags flag) {
39+
40+
return encode(allocator, false, 0, traceId, false, spanId, parentId, true, flag);
41+
}
42+
43+
public static ByteBuf encode64(
44+
ByteBufAllocator allocator, long traceId, long spanId, Flags flag) {
45+
return encode(allocator, false, 0, traceId, false, spanId, 0, false, flag);
46+
}
47+
48+
static ByteBuf encode(
49+
ByteBufAllocator allocator,
50+
boolean isEmpty,
51+
long traceIdHigh,
52+
long traceId,
53+
boolean extendedTraceId,
54+
long spanId,
55+
long parentId,
56+
boolean includesParent,
57+
Flags flag) {
58+
int size =
59+
1
60+
+ (isEmpty
61+
? 0
62+
: (Long.BYTES
63+
+ Long.BYTES
64+
+ (extendedTraceId ? Long.BYTES : 0)
65+
+ (includesParent ? Long.BYTES : 0)));
66+
final ByteBuf buffer = allocator.buffer(size);
67+
68+
int byteFlags = 0;
69+
switch (flag) {
70+
case NOT_SAMPLE:
71+
byteFlags |= FLAG_NOT_SAMPLED;
72+
break;
73+
case SAMPLE:
74+
byteFlags |= FLAG_SAMPLED;
75+
break;
76+
case DEBUG:
77+
byteFlags |= FLAG_DEBUG;
78+
break;
79+
}
80+
81+
if (isEmpty) {
82+
return buffer.writeByte(byteFlags);
83+
}
84+
85+
byteFlags |= FLAG_IDS_SET;
86+
87+
if (extendedTraceId) {
88+
byteFlags |= FLAG_EXTENDED_TRACE_ID_SIZE;
89+
}
90+
91+
if (includesParent) {
92+
byteFlags |= FLAG_INCLUDE_PARENT_ID;
93+
}
94+
95+
buffer.writeByte(byteFlags);
96+
97+
if (extendedTraceId) {
98+
buffer.writeLong(traceIdHigh);
99+
}
100+
101+
buffer.writeLong(traceId).writeLong(spanId);
102+
103+
if (includesParent) {
104+
buffer.writeLong(parentId);
105+
}
106+
107+
return buffer;
108+
}
109+
110+
public static TracingMetadata decode(ByteBuf byteBuf) {
111+
byteBuf.markReaderIndex();
112+
try {
113+
byte flags = byteBuf.readByte();
114+
boolean isNotSampled = (flags & FLAG_NOT_SAMPLED) == FLAG_NOT_SAMPLED;
115+
boolean isSampled = (flags & FLAG_SAMPLED) == FLAG_SAMPLED;
116+
boolean isDebug = (flags & FLAG_DEBUG) == FLAG_DEBUG;
117+
boolean isIDSet = (flags & FLAG_IDS_SET) == FLAG_IDS_SET;
118+
119+
if (!isIDSet) {
120+
return new TracingMetadata(0, 0, 0, false, 0, true, isNotSampled, isSampled, isDebug);
121+
}
122+
123+
boolean extendedTraceId =
124+
(flags & FLAG_EXTENDED_TRACE_ID_SIZE) == FLAG_EXTENDED_TRACE_ID_SIZE;
125+
126+
long traceIdHigh;
127+
if (extendedTraceId) {
128+
traceIdHigh = byteBuf.readLong();
129+
} else {
130+
traceIdHigh = 0;
131+
}
132+
133+
long traceId = byteBuf.readLong();
134+
long spanId = byteBuf.readLong();
135+
136+
boolean includesParent = (flags & FLAG_INCLUDE_PARENT_ID) == FLAG_INCLUDE_PARENT_ID;
137+
138+
long parentId;
139+
if (includesParent) {
140+
parentId = byteBuf.readLong();
141+
} else {
142+
parentId = 0;
143+
}
144+
145+
return new TracingMetadata(
146+
traceIdHigh,
147+
traceId,
148+
spanId,
149+
includesParent,
150+
parentId,
151+
false,
152+
isNotSampled,
153+
isSampled,
154+
isDebug);
155+
} finally {
156+
byteBuf.resetReaderIndex();
157+
}
158+
}
159+
160+
public enum Flags {
161+
UNDECIDED,
162+
NOT_SAMPLE,
163+
SAMPLE,
164+
DEBUG
165+
}
166+
}

0 commit comments

Comments
 (0)