Skip to content

Commit 12da3c1

Browse files
authored
Make preagg standard metrics work with ikey and role name overrides (#2472)
* Make preagg standard metrics work with ikey overrides * SEPARATE * More * Spotless * Fix * More * More * Fix * Fix * Fix * Fix * Fix * Fix test * Reuse
1 parent a1fd5df commit 12da3c1

File tree

37 files changed

+940
-542
lines changed

37 files changed

+940
-542
lines changed
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
/*
2+
* ApplicationInsights-Java
3+
* Copyright (c) Microsoft Corporation
4+
* All rights reserved.
5+
*
6+
* MIT License
7+
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
8+
* software and associated documentation files (the ""Software""), to deal in the Software
9+
* without restriction, including without limitation the rights to use, copy, modify, merge,
10+
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit
11+
* persons to whom the Software is furnished to do so, subject to the following conditions:
12+
* The above copyright notice and this permission notice shall be included in all copies or
13+
* substantial portions of the Software.
14+
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
15+
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
16+
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
17+
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
18+
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
19+
* DEALINGS IN THE SOFTWARE.
20+
*/
21+
22+
package com.microsoft.applicationinsights.agent.bootstrap;
23+
24+
import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_PRE_AGGREGATED;
25+
import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_SYNTHETIC;
26+
27+
import io.opentelemetry.api.common.AttributeKey;
28+
import io.opentelemetry.api.common.Attributes;
29+
import io.opentelemetry.api.common.AttributesBuilder;
30+
import io.opentelemetry.api.trace.Span;
31+
import io.opentelemetry.context.Context;
32+
import io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes;
33+
import io.opentelemetry.instrumentation.api.instrumenter.UserAgents;
34+
import javax.annotation.Nullable;
35+
36+
public class PreAggregatedStandardMetrics {
37+
38+
@Nullable private static volatile AttributeGetter attributeGetter;
39+
40+
public static void setAttributeGetter(AttributeGetter attributeGetter) {
41+
PreAggregatedStandardMetrics.attributeGetter = attributeGetter;
42+
}
43+
44+
public static void applyHttpClientView(
45+
AttributesBuilder builder,
46+
Context context,
47+
Attributes startAttributes,
48+
Attributes endAttributes) {
49+
50+
Span span = Span.fromContext(context);
51+
applyCommon(builder, span);
52+
}
53+
54+
public static void applyHttpServerView(
55+
AttributesBuilder builder,
56+
Context context,
57+
Attributes startAttributes,
58+
Attributes endAttributes) {
59+
60+
Span span = Span.fromContext(context);
61+
applyCommon(builder, span);
62+
63+
// is_synthetic is only applied to server requests
64+
builder.put(IS_SYNTHETIC, UserAgents.isBot(endAttributes, startAttributes));
65+
}
66+
67+
public static void applyRpcClientView(
68+
AttributesBuilder builder,
69+
Context context,
70+
Attributes startAttributes,
71+
Attributes endAttributes) {
72+
73+
applyHttpClientView(builder, context, startAttributes, endAttributes);
74+
}
75+
76+
public static void applyRpcServerView(
77+
AttributesBuilder builder,
78+
Context context,
79+
Attributes startAttributes,
80+
Attributes endAttributes) {
81+
82+
applyHttpServerView(builder, context, startAttributes, endAttributes);
83+
}
84+
85+
private static void applyCommon(AttributesBuilder builder, Span span) {
86+
87+
// this is needed for detecting telemetry signals that will trigger pre-aggregated metrics via
88+
// auto instrumentations
89+
span.setAttribute(IS_PRE_AGGREGATED, true);
90+
91+
if (attributeGetter == null) {
92+
return;
93+
}
94+
String connectionString =
95+
attributeGetter.get(span, BootstrapSemanticAttributes.CONNECTION_STRING);
96+
if (connectionString != null) {
97+
builder.put(BootstrapSemanticAttributes.CONNECTION_STRING, connectionString);
98+
} else {
99+
// back compat support
100+
String instrumentationKey =
101+
attributeGetter.get(span, BootstrapSemanticAttributes.INSTRUMENTATION_KEY);
102+
if (instrumentationKey != null) {
103+
builder.put(BootstrapSemanticAttributes.INSTRUMENTATION_KEY, instrumentationKey);
104+
}
105+
}
106+
String roleName = attributeGetter.get(span, BootstrapSemanticAttributes.ROLE_NAME);
107+
if (roleName != null) {
108+
builder.put(BootstrapSemanticAttributes.ROLE_NAME, roleName);
109+
}
110+
}
111+
112+
@FunctionalInterface
113+
public interface AttributeGetter {
114+
<T> T get(Span span, AttributeKey<T> key);
115+
}
116+
117+
private PreAggregatedStandardMetrics() {}
118+
}

agent/agent-bootstrap/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/BootstrapSemanticAttributes.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,17 @@
2727

2828
public final class BootstrapSemanticAttributes {
2929

30+
// replaced by ai.preview.connection_string
31+
@Deprecated
32+
public static final AttributeKey<String> INSTRUMENTATION_KEY =
33+
AttributeKey.stringKey("ai.preview.instrumentation_key");
34+
35+
public static final AttributeKey<String> CONNECTION_STRING =
36+
AttributeKey.stringKey("ai.preview.connection_string");
37+
38+
public static final AttributeKey<String> ROLE_NAME =
39+
AttributeKey.stringKey("ai.preview.service_name");
40+
3041
public static final AttributeKey<Boolean> IS_SYNTHETIC =
3142
booleanKey("applicationinsights.internal.is_synthetic");
3243
public static final AttributeKey<Boolean> IS_PRE_AGGREGATED =

agent/agent-bootstrap/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpClientMetrics.java

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,15 @@
1919
* DEALINGS IN THE SOFTWARE.
2020
*/
2121

22+
// Includes work from:
23+
/*
24+
* Copyright The OpenTelemetry Authors
25+
* SPDX-License-Identifier: Apache-2.0
26+
*/
27+
2228
package io.opentelemetry.instrumentation.api.instrumenter.http;
2329

24-
import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_PRE_AGGREGATED;
25-
import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_SYNTHETIC;
30+
import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyClientDurationAndSizeView;
2631
import static java.util.logging.Level.FINE;
2732

2833
import com.google.auto.value.AutoValue;
@@ -31,12 +36,10 @@
3136
import io.opentelemetry.api.metrics.DoubleHistogram;
3237
import io.opentelemetry.api.metrics.LongHistogram;
3338
import io.opentelemetry.api.metrics.Meter;
34-
import io.opentelemetry.api.trace.Span;
3539
import io.opentelemetry.context.Context;
3640
import io.opentelemetry.context.ContextKey;
3741
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
3842
import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
39-
import io.opentelemetry.instrumentation.api.instrumenter.UserAgents;
4043
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
4144
import java.util.concurrent.TimeUnit;
4245
import java.util.logging.Logger;
@@ -109,25 +112,16 @@ public void onEnd(Context context, Attributes endAttributes, long endNanos) {
109112
context);
110113
return;
111114
}
112-
Attributes durationAndSizeAttributes =
113-
TemporaryMetricsView.applyClientDurationAndSizeView(state.startAttributes(), endAttributes);
114115

115-
// START APPLICATION INSIGHTS CODE
116+
// START APPLICATION INSIGHTS MODIFICATIONS: passing context
116117

117-
// this is needed for detecting telemetry signals that will trigger pre-aggregated metrics via
118-
// auto instrumentations
119-
Span.fromContext(context).setAttribute(IS_PRE_AGGREGATED, true);
120-
121-
Attributes durationAttributes =
122-
durationAndSizeAttributes.toBuilder()
123-
.put(IS_SYNTHETIC, UserAgents.isBot(endAttributes, state.startAttributes()))
124-
.build();
125-
126-
// END APPLICATION INSIGHTS CODE
118+
Attributes durationAndSizeAttributes =
119+
applyClientDurationAndSizeView(context, state.startAttributes(), endAttributes);
127120

128-
this.duration.record(
129-
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, durationAttributes, context);
121+
// END APPLICATION MODIFICATIONS CODE
130122

123+
duration.record(
124+
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, durationAndSizeAttributes, context);
131125
Long requestLength =
132126
getAttribute(
133127
SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH, endAttributes, state.startAttributes());

agent/agent-bootstrap/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/http/HttpServerMetrics.java

Lines changed: 15 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,16 @@
1919
* DEALINGS IN THE SOFTWARE.
2020
*/
2121

22+
// Includes work from:
23+
/*
24+
* Copyright The OpenTelemetry Authors
25+
* SPDX-License-Identifier: Apache-2.0
26+
*/
27+
2228
package io.opentelemetry.instrumentation.api.instrumenter.http;
2329

24-
import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_PRE_AGGREGATED;
25-
import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_SYNTHETIC;
30+
import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyActiveRequestsView;
31+
import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyServerDurationAndSizeView2;
2632
import static java.util.logging.Level.FINE;
2733

2834
import com.google.auto.value.AutoValue;
@@ -32,12 +38,10 @@
3238
import io.opentelemetry.api.metrics.LongHistogram;
3339
import io.opentelemetry.api.metrics.LongUpDownCounter;
3440
import io.opentelemetry.api.metrics.Meter;
35-
import io.opentelemetry.api.trace.Span;
3641
import io.opentelemetry.context.Context;
3742
import io.opentelemetry.context.ContextKey;
3843
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
3944
import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
40-
import io.opentelemetry.instrumentation.api.instrumenter.UserAgents;
4145
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
4246
import java.util.concurrent.TimeUnit;
4347
import java.util.logging.Logger;
@@ -103,7 +107,7 @@ private HttpServerMetrics(Meter meter) {
103107

104108
@Override
105109
public Context onStart(Context context, Attributes startAttributes, long startNanos) {
106-
activeRequests.add(1, TemporaryMetricsView.applyActiveRequestsView(startAttributes), context);
110+
activeRequests.add(1, applyActiveRequestsView(startAttributes), context);
107111

108112
return context.with(
109113
HTTP_SERVER_REQUEST_METRICS_STATE,
@@ -120,27 +124,17 @@ public void onEnd(Context context, Attributes endAttributes, long endNanos) {
120124
context);
121125
return;
122126
}
123-
activeRequests.add(
124-
-1, TemporaryMetricsView.applyActiveRequestsView(state.startAttributes()), context);
125-
Attributes durationAndSizeAttributes =
126-
TemporaryMetricsView.applyServerDurationAndSizeView(state.startAttributes(), endAttributes);
127+
activeRequests.add(-1, applyActiveRequestsView(state.startAttributes()), context);
127128

128-
// START APPLICATION INSIGHTS CODE
129+
// START APPLICATION INSIGHTS MODIFICATIONS: passing context
129130

130-
// this is needed for detecting telemetry signals that will trigger pre-aggregated metrics via
131-
// auto instrumentations
132-
Span.fromContext(context).setAttribute(IS_PRE_AGGREGATED, true);
133-
134-
Attributes durationAttributes =
135-
durationAndSizeAttributes.toBuilder()
136-
.put(IS_SYNTHETIC, UserAgents.isBot(endAttributes, state.startAttributes()))
137-
.build();
131+
Attributes durationAndSizeAttributes =
132+
applyServerDurationAndSizeView2(context, state.startAttributes(), endAttributes);
138133

139134
// END APPLICATION INSIGHTS CODE
140135

141-
this.duration.record(
142-
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, durationAttributes, context);
143-
136+
duration.record(
137+
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, durationAndSizeAttributes, context);
144138
Long requestLength =
145139
getAttribute(
146140
SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH, endAttributes, state.startAttributes());

0 commit comments

Comments
 (0)