1
1
package datadog .trace .bootstrap ;
2
2
3
3
import datadog .json .JsonWriter ;
4
+ import datadog .trace .bootstrap .environment .EnvironmentVariables ;
4
5
import de .thetaphi .forbiddenapis .SuppressForbidden ;
5
6
import java .io .Closeable ;
6
7
import java .io .OutputStream ;
7
8
import java .util .ArrayList ;
9
+ import java .util .Collections ;
10
+ import java .util .LinkedHashMap ;
8
11
import java .util .List ;
12
+ import java .util .Map ;
9
13
10
14
/** Thread safe telemetry class used to relay information about tracer activation. */
11
15
public abstract class BootstrapInitializationTelemetry {
16
+ private static final int DEFAULT_MAX_TAGS = 5 ;
17
+
12
18
/** Returns a singleton no op instance of initialization telemetry */
13
19
public static BootstrapInitializationTelemetry noOpInstance () {
14
20
return NoOp .INSTANCE ;
@@ -88,7 +94,7 @@ public static final class JsonBased extends BootstrapInitializationTelemetry {
88
94
private final JsonSender sender ;
89
95
90
96
private final List <String > meta ;
91
- private final List <String > points ;
97
+ private final Map < String , List <String > > points ;
92
98
93
99
// one way false to true
94
100
private volatile boolean incomplete = false ;
@@ -97,7 +103,7 @@ public static final class JsonBased extends BootstrapInitializationTelemetry {
97
103
JsonBased (JsonSender sender ) {
98
104
this .sender = sender ;
99
105
this .meta = new ArrayList <>();
100
- this .points = new ArrayList <>();
106
+ this .points = new LinkedHashMap <>();
101
107
}
102
108
103
109
@ Override
@@ -118,8 +124,39 @@ public void onAbort(String reasonCode) {
118
124
@ Override
119
125
public void onError (Throwable t ) {
120
126
error = true ;
121
- onPoint ("library_entrypoint.error" , "error_type:" + t .getClass ().getName ());
122
127
setMetaInfo ("error" , "internal_error" , t .getMessage ());
128
+
129
+ List <String > causes = new ArrayList <>();
130
+
131
+ Throwable cause = t .getCause ();
132
+ while (cause != null ) {
133
+ causes .add ("error_type:" + cause .getClass ().getName ());
134
+ cause = cause .getCause ();
135
+ }
136
+ causes .add ("error_type:" + t .getClass ().getName ());
137
+
138
+ // Limit the number of tags to avoid overpopulating the JSON payload.
139
+ int maxTags = maxTags ();
140
+ int numCauses = causes .size ();
141
+ if (numCauses > maxTags ) {
142
+ causes = causes .subList (numCauses - maxTags , numCauses );
143
+ }
144
+
145
+ onPoint ("library_entrypoint.error" , causes );
146
+ }
147
+
148
+ private int maxTags () {
149
+ String maxTags = EnvironmentVariables .get ("DD_TELEMETRY_FORWARDER_MAX_TAGS" );
150
+
151
+ if (maxTags != null ) {
152
+ try {
153
+ return Integer .parseInt (maxTags );
154
+ } catch (Throwable ignore ) {
155
+ // Ignore and return default value.
156
+ }
157
+ }
158
+
159
+ return DEFAULT_MAX_TAGS ;
123
160
}
124
161
125
162
@ Override
@@ -159,9 +196,12 @@ private String mapResultClass(String reasonCode) {
159
196
}
160
197
161
198
private void onPoint (String name , String tag ) {
199
+ onPoint (name , Collections .singletonList (tag ));
200
+ }
201
+
202
+ private void onPoint (String name , List <String > tags ) {
162
203
synchronized (this .points ) {
163
- this .points .add (name );
164
- this .points .add (tag );
204
+ this .points .put (name , tags );
165
205
}
166
206
}
167
207
@@ -189,10 +229,14 @@ public void finish() {
189
229
190
230
writer .name ("points" ).beginArray ();
191
231
synchronized (this .points ) {
192
- for (int i = 0 ; i + 1 < this . points .size (); i = i + 2 ) {
232
+ for (Map . Entry < String , List < String >> entry : points .entrySet () ) {
193
233
writer .beginObject ();
194
- writer .name ("name" ).value (this .points .get (i ));
195
- writer .name ("tags" ).beginArray ().value (this .points .get (i + 1 )).endArray ();
234
+ writer .name ("name" ).value (entry .getKey ());
235
+ writer .name ("tags" ).beginArray ();
236
+ for (String tag : entry .getValue ()) {
237
+ writer .value (tag );
238
+ }
239
+ writer .endArray ();
196
240
writer .endObject ();
197
241
}
198
242
this .points .clear ();
0 commit comments