forked from open-telemetry/opentelemetry-java
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathTraceId.java
169 lines (154 loc) · 5.53 KB
/
TraceId.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
/*
* Copyright 2019, OpenTelemetry Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package io.opentelemetry.trace;
import io.opentelemetry.internal.Utils;
import javax.annotation.concurrent.Immutable;
/**
* Helper methods for dealing with a trace identifier. A valid trace identifier is a 16-byte array
* with at least one non-zero byte. In base-16 representation, a 32 character hex String, where at
* least one of the characters is not a '0'.
*
* @since 0.1.0
*/
@Immutable
public final class TraceId {
private static final ThreadLocal<char[]> charBuffer = new ThreadLocal<>();
private static final int SIZE_IN_BYTES = 16;
private static final int HEX_SIZE = 2 * BigendianEncoding.LONG_BASE16;
private static final String INVALID = "00000000000000000000000000000000";
private TraceId() {}
/**
* Returns the size in bytes of the {@code TraceId}.
*
* @return the size in bytes of the {@code TraceId}.
* @since 0.1.0
*/
public static int getSize() {
return SIZE_IN_BYTES;
}
/**
* Returns the length of the base16 (hex) representation of the {@code TraceId}.
*
* @since 0.8.0
*/
public static int getHexLength() {
return HEX_SIZE;
}
/**
* Returns the invalid {@code TraceId}. All bytes are '\0'.
*
* @return the invalid {@code TraceId}.
* @since 0.1.0
*/
public static String getInvalid() {
return INVALID;
}
/**
* Constructs a {@code TraceId} whose representation is specified by two long values representing
* the lower and higher parts.
*
* <p>There is no restriction on the specified values, other than the already established validity
* rules applying to {@code TraceId}. Specifying 0 for both values will effectively make the new
* {@code TraceId} invalid.
*
* <p>This is equivalent to calling {@link #bytesToHex(byte[])} with the specified values stored
* as big-endian.
*
* @param idHi the higher part of the {@code TraceId}.
* @param idLo the lower part of the {@code TraceId}.
* @since 0.1.0
*/
public static String fromLongs(long idHi, long idLo) {
char[] chars = getTemporaryBuffer();
BigendianEncoding.longToBase16String(idHi, chars, 0);
BigendianEncoding.longToBase16String(idLo, chars, 16);
return new String(chars);
}
private static char[] getTemporaryBuffer() {
char[] chars = charBuffer.get();
if (chars == null) {
chars = new char[HEX_SIZE];
charBuffer.set(chars);
}
return chars;
}
/**
* Returns a {@code TraceId} built from a lowercase base16 representation.
*
* @param src the lowercase base16 representation.
* @param srcOffset the offset in the buffer where the representation of the {@code TraceId}
* begins.
* @return a {@code TraceId} built from a lowercase base16 representation.
* @throws NullPointerException if {@code src} is null.
* @throws IllegalArgumentException if not enough characters in the {@code src} from the {@code
* srcOffset}.
* @since 0.1.0
*/
public static byte[] bytesFromHex(String src, int srcOffset) {
Utils.checkNotNull(src, "src");
return BigendianEncoding.bytesFromBase16(src, srcOffset, HEX_SIZE);
}
/**
* Copies the lowercase base16 representations of the {@code TraceId} into the {@code dest}
* beginning at the {@code destOffset} offset.
*
* @param dest the destination buffer.
* @param destOffset the starting offset in the destination buffer.
* @throws IndexOutOfBoundsException if {@code destOffset + 2 * TraceId.getSize()} is greater than
* {@code dest.length}.
* @since 0.1.0
*/
public static void copyHexInto(byte[] traceId, char[] dest, int destOffset) {
BigendianEncoding.longToBase16String(
BigendianEncoding.longFromByteArray(traceId, 0), dest, destOffset);
BigendianEncoding.longToBase16String(
BigendianEncoding.longFromByteArray(traceId, 8), dest, destOffset + 16);
}
/**
* Returns whether the {@code TraceId} is valid. A valid trace identifier is a 16-byte array with
* at least one non-zero byte.
*
* @return {@code true} if the {@code TraceId} is valid.
* @since 0.1.0
*/
public static boolean isValid(CharSequence traceId) {
return (traceId.length() == HEX_SIZE)
&& !INVALID.contentEquals(traceId)
&& BigendianEncoding.isValidBase16String(traceId);
}
/**
* Returns the lowercase base16 encoding of this {@code TraceId}.
*
* @return the lowercase base16 encoding of this {@code TraceId}.
* @since 0.1.0
*/
public static String bytesToHex(byte[] traceId) {
char[] chars = new char[HEX_SIZE];
copyHexInto(traceId, chars, 0);
return new String(chars);
}
/**
* Returns the rightmost 8 bytes of the trace-id as a long value. This is used in
* ProbabilitySampler.
*
* <p>This method is marked as internal and subject to change.
*
* @return the rightmost 8 bytes of the trace-id as a long value.
*/
public static long getTraceIdRandomPart(CharSequence traceId) {
return BigendianEncoding.longFromBase16String(traceId, BigendianEncoding.LONG_BASE16);
}
}