Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,23 @@

import java.time.OffsetDateTime;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import static java.util.Arrays.asList;

public abstract class AbstractTelemetryBuilder {

private static final int MAX_PROPERTY_KEY_LENGTH = 150;
private static final int MAX_PROPERTY_VALUE_LENGTH = 8192;

// gen_ai properties can contain large payloads (e.g. full conversation messages,
// tool definitions) that should not be truncated
private static final Set<String> TRUNCATION_EXEMPT_PROPERTY_KEYS = new HashSet<>(asList("gen_ai.input.messages",
"gen_ai.output.messages", "gen_ai.system_instructions", "gen_ai.tool.definitions", "gen_ai.tool.call.arguments",
"gen_ai.tool.call.result", "gen_ai.evaluation.explanation"));

protected static final int MAX_MEASUREMENT_KEY_LENGTH = 150;

protected static final int MAX_NAME_LENGTH = 1024;
Expand Down Expand Up @@ -79,7 +89,11 @@ public void addProperty(@Nullable String key, @Nullable String value) {
// TODO (trask) log
return;
}
getProperties().put(key, TelemetryTruncation.truncatePropertyValue(value, MAX_PROPERTY_VALUE_LENGTH, key));
if (TRUNCATION_EXEMPT_PROPERTY_KEYS.contains(key)) {
getProperties().put(key, value);
} else {
getProperties().put(key, TelemetryTruncation.truncatePropertyValue(value, MAX_PROPERTY_VALUE_LENGTH, key));
}
}

public TelemetryItem build() {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package com.azure.monitor.opentelemetry.autoconfigure.implementation.builders;

import com.azure.monitor.opentelemetry.autoconfigure.implementation.models.TelemetryItem;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;

import java.util.Map;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AbstractTelemetryBuilderTest {

@Test
public void regularPropertyIsTruncatedAt8192() {
MessageTelemetryBuilder builder = MessageTelemetryBuilder.create();
String longValue = repeat("a", 10000);
builder.addProperty("some.regular.property", longValue);

TelemetryItem item = builder.build();
Map<String, String> properties = getProperties(item);
assertEquals(8192, properties.get("some.regular.property").length());
}

@ParameterizedTest
@ValueSource(
strings = {
"gen_ai.input.messages",
"gen_ai.output.messages",
"gen_ai.system_instructions",
"gen_ai.tool.definitions",
"gen_ai.tool.call.arguments",
"gen_ai.tool.call.result",
"gen_ai.evaluation.explanation" })
public void genAiPropertyIsNotTruncated(String key) {
MessageTelemetryBuilder builder = MessageTelemetryBuilder.create();
String longValue = repeat("a", 50000);
builder.addProperty(key, longValue);

TelemetryItem item = builder.build();
Map<String, String> properties = getProperties(item);
assertEquals(50000, properties.get(key).length());
assertEquals(longValue, properties.get(key));
}

@SuppressWarnings("unchecked")
private static Map<String, String> getProperties(TelemetryItem item) {
if (item.getData() == null || item.getData().getBaseData() == null) {
return null;
}
Object baseData = item.getData().getBaseData();
try {
return (Map<String, String>) baseData.getClass().getMethod("getProperties").invoke(baseData);
} catch (Exception e) {
throw new RuntimeException(e);
}
}

private static String repeat(String s, int count) {
StringBuilder sb = new StringBuilder(s.length() * count);
for (int i = 0; i < count; i++) {
sb.append(s);
}
return sb.toString();
}
}