Skip to content

Commit

Permalink
Make preagg standard metrics work with ikey and role name overrides (#…
Browse files Browse the repository at this point in the history
…2472)

* Make preagg standard metrics work with ikey overrides

* SEPARATE

* More

* Spotless

* Fix

* More

* More

* Fix

* Fix

* Fix

* Fix

* Fix

* Fix test

* Reuse
  • Loading branch information
trask authored Aug 30, 2022
1 parent a1fd5df commit 12da3c1
Show file tree
Hide file tree
Showing 37 changed files with 940 additions and 542 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
/*
* ApplicationInsights-Java
* Copyright (c) Microsoft Corporation
* All rights reserved.
*
* MIT License
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the ""Software""), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit
* persons to whom the Software is furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/

package com.microsoft.applicationinsights.agent.bootstrap;

import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_PRE_AGGREGATED;
import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_SYNTHETIC;

import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes;
import io.opentelemetry.instrumentation.api.instrumenter.UserAgents;
import javax.annotation.Nullable;

public class PreAggregatedStandardMetrics {

@Nullable private static volatile AttributeGetter attributeGetter;

public static void setAttributeGetter(AttributeGetter attributeGetter) {
PreAggregatedStandardMetrics.attributeGetter = attributeGetter;
}

public static void applyHttpClientView(
AttributesBuilder builder,
Context context,
Attributes startAttributes,
Attributes endAttributes) {

Span span = Span.fromContext(context);
applyCommon(builder, span);
}

public static void applyHttpServerView(
AttributesBuilder builder,
Context context,
Attributes startAttributes,
Attributes endAttributes) {

Span span = Span.fromContext(context);
applyCommon(builder, span);

// is_synthetic is only applied to server requests
builder.put(IS_SYNTHETIC, UserAgents.isBot(endAttributes, startAttributes));
}

public static void applyRpcClientView(
AttributesBuilder builder,
Context context,
Attributes startAttributes,
Attributes endAttributes) {

applyHttpClientView(builder, context, startAttributes, endAttributes);
}

public static void applyRpcServerView(
AttributesBuilder builder,
Context context,
Attributes startAttributes,
Attributes endAttributes) {

applyHttpServerView(builder, context, startAttributes, endAttributes);
}

private static void applyCommon(AttributesBuilder builder, Span span) {

// this is needed for detecting telemetry signals that will trigger pre-aggregated metrics via
// auto instrumentations
span.setAttribute(IS_PRE_AGGREGATED, true);

if (attributeGetter == null) {
return;
}
String connectionString =
attributeGetter.get(span, BootstrapSemanticAttributes.CONNECTION_STRING);
if (connectionString != null) {
builder.put(BootstrapSemanticAttributes.CONNECTION_STRING, connectionString);
} else {
// back compat support
String instrumentationKey =
attributeGetter.get(span, BootstrapSemanticAttributes.INSTRUMENTATION_KEY);
if (instrumentationKey != null) {
builder.put(BootstrapSemanticAttributes.INSTRUMENTATION_KEY, instrumentationKey);
}
}
String roleName = attributeGetter.get(span, BootstrapSemanticAttributes.ROLE_NAME);
if (roleName != null) {
builder.put(BootstrapSemanticAttributes.ROLE_NAME, roleName);
}
}

@FunctionalInterface
public interface AttributeGetter {
<T> T get(Span span, AttributeKey<T> key);
}

private PreAggregatedStandardMetrics() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,17 @@

public final class BootstrapSemanticAttributes {

// replaced by ai.preview.connection_string
@Deprecated
public static final AttributeKey<String> INSTRUMENTATION_KEY =
AttributeKey.stringKey("ai.preview.instrumentation_key");

public static final AttributeKey<String> CONNECTION_STRING =
AttributeKey.stringKey("ai.preview.connection_string");

public static final AttributeKey<String> ROLE_NAME =
AttributeKey.stringKey("ai.preview.service_name");

public static final AttributeKey<Boolean> IS_SYNTHETIC =
booleanKey("applicationinsights.internal.is_synthetic");
public static final AttributeKey<Boolean> IS_PRE_AGGREGATED =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,15 @@
* DEALINGS IN THE SOFTWARE.
*/

// Includes work from:
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter.http;

import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_PRE_AGGREGATED;
import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_SYNTHETIC;
import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyClientDurationAndSizeView;
import static java.util.logging.Level.FINE;

import com.google.auto.value.AutoValue;
Expand All @@ -31,12 +36,10 @@
import io.opentelemetry.api.metrics.DoubleHistogram;
import io.opentelemetry.api.metrics.LongHistogram;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.UserAgents;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
Expand Down Expand Up @@ -109,25 +112,16 @@ public void onEnd(Context context, Attributes endAttributes, long endNanos) {
context);
return;
}
Attributes durationAndSizeAttributes =
TemporaryMetricsView.applyClientDurationAndSizeView(state.startAttributes(), endAttributes);

// START APPLICATION INSIGHTS CODE
// START APPLICATION INSIGHTS MODIFICATIONS: passing context

// this is needed for detecting telemetry signals that will trigger pre-aggregated metrics via
// auto instrumentations
Span.fromContext(context).setAttribute(IS_PRE_AGGREGATED, true);

Attributes durationAttributes =
durationAndSizeAttributes.toBuilder()
.put(IS_SYNTHETIC, UserAgents.isBot(endAttributes, state.startAttributes()))
.build();

// END APPLICATION INSIGHTS CODE
Attributes durationAndSizeAttributes =
applyClientDurationAndSizeView(context, state.startAttributes(), endAttributes);

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

duration.record(
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, durationAndSizeAttributes, context);
Long requestLength =
getAttribute(
SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH, endAttributes, state.startAttributes());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,16 @@
* DEALINGS IN THE SOFTWARE.
*/

// Includes work from:
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.instrumenter.http;

import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_PRE_AGGREGATED;
import static io.opentelemetry.instrumentation.api.instrumenter.BootstrapSemanticAttributes.IS_SYNTHETIC;
import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyActiveRequestsView;
import static io.opentelemetry.instrumentation.api.instrumenter.http.TemporaryMetricsView.applyServerDurationAndSizeView2;
import static java.util.logging.Level.FINE;

import com.google.auto.value.AutoValue;
Expand All @@ -32,12 +38,10 @@
import io.opentelemetry.api.metrics.LongHistogram;
import io.opentelemetry.api.metrics.LongUpDownCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.instrumentation.api.instrumenter.OperationListener;
import io.opentelemetry.instrumentation.api.instrumenter.OperationMetrics;
import io.opentelemetry.instrumentation.api.instrumenter.UserAgents;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.concurrent.TimeUnit;
import java.util.logging.Logger;
Expand Down Expand Up @@ -103,7 +107,7 @@ private HttpServerMetrics(Meter meter) {

@Override
public Context onStart(Context context, Attributes startAttributes, long startNanos) {
activeRequests.add(1, TemporaryMetricsView.applyActiveRequestsView(startAttributes), context);
activeRequests.add(1, applyActiveRequestsView(startAttributes), context);

return context.with(
HTTP_SERVER_REQUEST_METRICS_STATE,
Expand All @@ -120,27 +124,17 @@ public void onEnd(Context context, Attributes endAttributes, long endNanos) {
context);
return;
}
activeRequests.add(
-1, TemporaryMetricsView.applyActiveRequestsView(state.startAttributes()), context);
Attributes durationAndSizeAttributes =
TemporaryMetricsView.applyServerDurationAndSizeView(state.startAttributes(), endAttributes);
activeRequests.add(-1, applyActiveRequestsView(state.startAttributes()), context);

// START APPLICATION INSIGHTS CODE
// START APPLICATION INSIGHTS MODIFICATIONS: passing context

// this is needed for detecting telemetry signals that will trigger pre-aggregated metrics via
// auto instrumentations
Span.fromContext(context).setAttribute(IS_PRE_AGGREGATED, true);

Attributes durationAttributes =
durationAndSizeAttributes.toBuilder()
.put(IS_SYNTHETIC, UserAgents.isBot(endAttributes, state.startAttributes()))
.build();
Attributes durationAndSizeAttributes =
applyServerDurationAndSizeView2(context, state.startAttributes(), endAttributes);

// END APPLICATION INSIGHTS CODE

this.duration.record(
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, durationAttributes, context);

duration.record(
(endNanos - state.startTimeNanos()) / NANOS_PER_MS, durationAndSizeAttributes, context);
Long requestLength =
getAttribute(
SemanticAttributes.HTTP_REQUEST_CONTENT_LENGTH, endAttributes, state.startAttributes());
Expand Down
Loading

0 comments on commit 12da3c1

Please sign in to comment.