Skip to content

Commit 02e574d

Browse files
committed
Support item count and operation name in azmonexporter
1 parent cde4925 commit 02e574d

File tree

24 files changed

+746
-607
lines changed

24 files changed

+746
-607
lines changed

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/configuration/Configuration.java

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,28 @@ public static class Sampling {
156156

157157
public static class SamplingPreview {
158158

159+
// this is not the default for now at least, because
160+
//
161+
// parent not-sampled -> child not-sampled (always, to avoid broken traces)
162+
// parent sampled -> child will still sample at its desired rate
163+
// note: this is just sample rate of child, not sample rate of parent times
164+
// sample rate of child, as both are using the same trace-id hash
165+
//
166+
// ??? if child sample rate is higher than the parent sample rate
167+
// parent sampled --> child sampled
168+
// parent not-sampled --> child not-sampled
169+
// which means that child has same effective sample rate as parent, and so its item count
170+
// will be wrong
171+
//
172+
// AND SO: if want to use parent-based sampler, then need to propagate the sample rate,
173+
// otherwise can end up with incorrect math
174+
//
175+
// Another (lesser) reason is because .NET SDK always propagates trace flags "00" (not
176+
// sampled)
177+
//
178+
// IMPORTANT if changing this default, we need to keep it at least on Azure Functions
179+
public boolean parentBased;
180+
159181
public List<SamplingOverride> overrides = new ArrayList<>();
160182
}
161183

@@ -261,10 +283,6 @@ public static class PreviewConfiguration {
261283
// world,
262284
// so safer to only allow single interval for now
263285
public int metricIntervalSeconds = 60;
264-
// ignoreRemoteParentNotSampled is sometimes needed because .NET SDK always propagates trace
265-
// flags "00" (not sampled)
266-
// in particular, it is always needed in Azure Functions worker
267-
public boolean ignoreRemoteParentNotSampled = DiagnosticsHelper.rpIntegrationChar() == 'f';
268286
public boolean captureControllerSpans;
269287
// this is just here to detect if using this old setting in order to give a helpful message
270288
@Deprecated public boolean httpMethodInOperationName;

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/AppIdSupplier.java

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
import com.azure.core.http.HttpResponse;
3030
import com.azure.monitor.opentelemetry.exporter.implementation.configuration.ConnectionString;
3131
import com.azure.monitor.opentelemetry.exporter.implementation.logging.NetworkFriendlyExceptions;
32-
import com.azure.monitor.opentelemetry.exporter.implementation.logging.WarningLogger;
32+
import com.azure.monitor.opentelemetry.exporter.implementation.logging.OperationLogger;
3333
import com.azure.monitor.opentelemetry.exporter.implementation.utils.ThreadPoolUtils;
3434
import com.microsoft.applicationinsights.agent.bootstrap.AiAppId;
3535
import com.microsoft.applicationinsights.agent.internal.httpclient.LazyHttpClient;
@@ -53,8 +53,8 @@ public class AppIdSupplier implements AiAppId.Supplier {
5353
Executors.newSingleThreadScheduledExecutor(
5454
ThreadPoolUtils.createDaemonThreadFactory(AppIdSupplier.class));
5555

56-
private static final WarningLogger warningLogger =
57-
new WarningLogger(GetAppIdTask.class, "Unable to retrieve appId");
56+
private static final OperationLogger operationLogger =
57+
new OperationLogger(GetAppIdTask.class, "Retrieving appId");
5858

5959
// guarded by taskLock
6060
private GetAppIdTask task;
@@ -147,7 +147,7 @@ public void run() {
147147
} catch (RuntimeException ex) {
148148
if (!NetworkFriendlyExceptions.logSpecialOneTimeFriendlyException(
149149
ex, url.toString(), friendlyExceptionThrown, logger)) {
150-
warningLogger.recordWarning("exception sending request to " + url, ex, APP_ID_ERROR);
150+
operationLogger.recordFailure("exception sending request to " + url, ex, APP_ID_ERROR);
151151
}
152152
backOff();
153153
return;
@@ -161,7 +161,7 @@ public void run() {
161161
String body = response.getBodyAsString().block();
162162
int statusCode = response.getStatusCode();
163163
if (statusCode != 200) {
164-
warningLogger.recordWarning(
164+
operationLogger.recordFailure(
165165
"received " + statusCode + " from " + url + "\nfull response:\n" + body,
166166
null,
167167
APP_ID_ERROR);
@@ -171,12 +171,12 @@ public void run() {
171171

172172
// check for case when breeze returns invalid value
173173
if (body == null || body.isEmpty()) {
174-
warningLogger.recordWarning("received empty body from " + url, null, APP_ID_ERROR);
174+
operationLogger.recordFailure("received empty body from " + url, null, APP_ID_ERROR);
175175
backOff();
176176
return;
177177
}
178178

179-
logger.debug("appId retrieved: {}", body);
179+
operationLogger.recordSuccess();
180180
appId = body;
181181
}
182182

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/InheritedAttributesLogProcessor.java

Lines changed: 1 addition & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121

2222
package com.microsoft.applicationinsights.agent.internal.init;
2323

24-
import com.azure.monitor.opentelemetry.exporter.implementation.AiOperationNameSpanProcessor;
2524
import com.microsoft.applicationinsights.agent.internal.configuration.Configuration;
2625
import com.microsoft.applicationinsights.agent.internal.processors.MyLogData;
2726
import io.opentelemetry.api.common.AttributeKey;
@@ -36,9 +35,6 @@
3635

3736
public class InheritedAttributesLogProcessor implements LogProcessor {
3837

39-
private static final AttributeKey<String> AI_OPERATION_NAME_KEY =
40-
AttributeKey.stringKey("applicationinsights.internal.operation_name");
41-
4238
private static final AttributeKey<String> INSTRUMENTATION_KEY_KEY =
4339
AttributeKey.stringKey("ai.preview.instrumentation_key");
4440

@@ -60,7 +56,6 @@ private static List<AttributeKey<?>> buildInheritedAttributesList(
6056
for (Configuration.InheritedAttribute inheritedAttribute : inheritedAttributes) {
6157
list.add(inheritedAttribute.getAttributeKey());
6258
}
63-
list.add(AI_OPERATION_NAME_KEY);
6459
list.add(INSTRUMENTATION_KEY_KEY);
6560
list.add(ROLE_NAME_KEY);
6661
return list;
@@ -78,12 +73,7 @@ public void emit(LogData log) {
7873
ReadableSpan readableSpan = (ReadableSpan) currentSpan;
7974
AttributesBuilder builder = log.getAttributes().toBuilder();
8075
for (AttributeKey<?> inheritedAttributeKey : inheritedAttributes) {
81-
Object value;
82-
if (inheritedAttributeKey == AI_OPERATION_NAME_KEY) {
83-
value = AiOperationNameSpanProcessor.getOperationName(readableSpan);
84-
} else {
85-
value = readableSpan.getAttribute(inheritedAttributeKey);
86-
}
76+
Object value = readableSpan.getAttribute(inheritedAttributeKey);
8777
if (value != null) {
8878
if (builder == null) {
8979
builder = log.getAttributes().toBuilder();

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/init/SecondEntryPoint.java

Lines changed: 9 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,8 @@
2323

2424
import static java.util.concurrent.TimeUnit.MINUTES;
2525

26-
import com.azure.monitor.opentelemetry.exporter.implementation.AiOperationNameSpanProcessor;
26+
import com.azure.monitor.opentelemetry.exporter.implementation.AzureMonitorLogProcessor;
27+
import com.azure.monitor.opentelemetry.exporter.implementation.AzureMonitorSpanProcessor;
2728
import com.azure.monitor.opentelemetry.exporter.implementation.LogDataMapper;
2829
import com.azure.monitor.opentelemetry.exporter.implementation.MetricDataMapper;
2930
import com.azure.monitor.opentelemetry.exporter.implementation.SpanDataMapper;
@@ -295,32 +296,22 @@ private static SdkTracerProviderBuilder configureTracing(
295296
// and the default for DelegatingSampler is to not sample anything)
296297
}
297298

298-
// operation name span processor is only applied on span start, so doesn't need to be chained
299-
// with the batch span processor
300-
tracerProvider.addSpanProcessor(new AiOperationNameSpanProcessor());
301-
// inherited attributes span processor is only applied on span start, so doesn't need to be
302-
// chained with the batch span processor
299+
tracerProvider.addSpanProcessor(new AzureMonitorSpanProcessor());
303300
if (!configuration.preview.inheritedAttributes.isEmpty()) {
304301
tracerProvider.addSpanProcessor(
305302
new InheritedAttributesSpanProcessor(configuration.preview.inheritedAttributes));
306303
}
307-
// legacy span processor is only applied on span start, so doesn't need to be chained with the
308-
// batch span processor
309-
// it is used to pass legacy attributes from the context (extracted by the AiLegacyPropagator)
310-
// to the span attributes (since there is no way to update attributes on span directly from
311-
// propagator)
304+
// legacy span processor is used to pass legacy attributes from the context (extracted by the
305+
// AiLegacyPropagator) to the span attributes (since there is no way to update attributes on
306+
// span directly from propagator)
312307
if (configuration.preview.legacyRequestIdPropagation.enabled) {
313308
tracerProvider.addSpanProcessor(new AiLegacyHeaderSpanProcessor());
314309
}
315-
// instrumentation key overrides span processor is only applied on span start, so doesn't need
316-
// to be chained with the batch span processor
317310
if (!configuration.preview.instrumentationKeyOverrides.isEmpty()) {
318311
tracerProvider.addSpanProcessor(
319312
new InheritedInstrumentationKeySpanProcessor(
320313
configuration.preview.instrumentationKeyOverrides));
321314
}
322-
// role name overrides span processor is only applied on span start, so doesn't need
323-
// to be chained with the batch span processor
324315
if (!configuration.preview.roleNameOverrides.isEmpty()) {
325316
tracerProvider.addSpanProcessor(
326317
new InheritedRoleNameSpanProcessor(configuration.preview.roleNameOverrides));
@@ -439,12 +430,10 @@ private static SdkLogEmitterProviderBuilder configureLogging(
439430
batchLogProcessor =
440431
BatchLogProcessor.builder(logExporter).setScheduleDelay(getBatchProcessorDelay()).build();
441432

442-
// inherited attributes log processor also handles operation name, ikey and role name attributes
443-
// and these all need access to Span.current(), so must be run before passing off to the
444-
// BatchLogProcessor
445433
return builder.addLogProcessor(
446-
new InheritedAttributesLogProcessor(
447-
configuration.preview.inheritedAttributes, batchLogProcessor));
434+
new AzureMonitorLogProcessor(
435+
new InheritedAttributesLogProcessor(
436+
configuration.preview.inheritedAttributes, batchLogProcessor)));
448437
}
449438

450439
private static LogExporter createLogExporter(

agent/agent-tooling/src/main/java/com/microsoft/applicationinsights/agent/internal/legacyheaders/DelegatingPropagator.java

Lines changed: 1 addition & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -21,12 +21,7 @@
2121

2222
package com.microsoft.applicationinsights.agent.internal.legacyheaders;
2323

24-
import com.azure.monitor.opentelemetry.exporter.implementation.utils.TelemetryUtil;
2524
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
26-
import io.opentelemetry.api.trace.Span;
27-
import io.opentelemetry.api.trace.SpanContext;
28-
import io.opentelemetry.api.trace.TraceFlags;
29-
import io.opentelemetry.api.trace.TraceState;
3025
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
3126
import io.opentelemetry.context.Context;
3227
import io.opentelemetry.context.propagation.TextMapGetter;
@@ -73,9 +68,7 @@ public void setUpStandardDelegate(
7368
propagators.add(AiLegacyPropagator.getInstance());
7469
}
7570

76-
// currently using modified W3CTraceContextPropagator because "ai-internal-sp" trace state
77-
// shouldn't be sent over the wire (at least not yet, and not with that name)
78-
propagators.add(new ModifiedW3cTraceContextPropagator());
71+
propagators.add(W3CTraceContextPropagator.getInstance());
7972
propagators.add(W3CBaggagePropagator.getInstance());
8073

8174
delegate = TextMapPropagator.composite(propagators);
@@ -95,75 +88,4 @@ public <C> void inject(Context context, @Nullable C carrier, TextMapSetter<C> se
9588
public <C> Context extract(Context context, @Nullable C carrier, TextMapGetter<C> getter) {
9689
return delegate.extract(context, carrier, getter);
9790
}
98-
99-
private static class ModifiedW3cTraceContextPropagator implements TextMapPropagator {
100-
101-
private final TextMapPropagator delegate = W3CTraceContextPropagator.getInstance();
102-
103-
@Override
104-
public Collection<String> fields() {
105-
return delegate.fields();
106-
}
107-
108-
@Override
109-
public <C> void inject(Context context, @Nullable C carrier, TextMapSetter<C> setter) {
110-
// do not propagate sampling percentage downstream YET
111-
SpanContext spanContext = Span.fromContext(context).getSpanContext();
112-
// sampling percentage should always be present, so no need to optimize with checking if
113-
// present
114-
TraceState traceState = spanContext.getTraceState();
115-
TraceState updatedTraceState;
116-
if (traceState.size() == 1
117-
&& traceState.get(TelemetryUtil.SAMPLING_PERCENTAGE_TRACE_STATE) != null) {
118-
// this is a common case, worth optimizing
119-
updatedTraceState = TraceState.getDefault();
120-
} else {
121-
updatedTraceState =
122-
traceState.toBuilder().remove(TelemetryUtil.SAMPLING_PERCENTAGE_TRACE_STATE).build();
123-
}
124-
SpanContext updatedSpanContext = new ModifiedSpanContext(spanContext, updatedTraceState);
125-
delegate.inject(Context.root().with(Span.wrap(updatedSpanContext)), carrier, setter);
126-
}
127-
128-
@Override
129-
public <C> Context extract(Context context, @Nullable C carrier, TextMapGetter<C> getter) {
130-
return delegate.extract(context, carrier, getter);
131-
}
132-
}
133-
134-
private static class ModifiedSpanContext implements SpanContext {
135-
136-
private final SpanContext delegate;
137-
private final TraceState traceState;
138-
139-
private ModifiedSpanContext(SpanContext delegate, TraceState traceState) {
140-
this.delegate = delegate;
141-
this.traceState = traceState;
142-
}
143-
144-
@Override
145-
public String getTraceId() {
146-
return delegate.getTraceId();
147-
}
148-
149-
@Override
150-
public String getSpanId() {
151-
return delegate.getSpanId();
152-
}
153-
154-
@Override
155-
public TraceFlags getTraceFlags() {
156-
return delegate.getTraceFlags();
157-
}
158-
159-
@Override
160-
public TraceState getTraceState() {
161-
return traceState;
162-
}
163-
164-
@Override
165-
public boolean isRemote() {
166-
return delegate.isRemote();
167-
}
168-
}
16991
}

0 commit comments

Comments
 (0)