diff --git a/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource/EcsResource.java b/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource/EcsResource.java index 8ee74bd47..de6d50afe 100644 --- a/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource/EcsResource.java +++ b/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource/EcsResource.java @@ -192,9 +192,8 @@ static void parseResponse( DockerImage parsedImage = DockerImage.parse(value); if (parsedImage != null) { attrBuilders.put(CONTAINER_IMAGE_NAME, parsedImage.getRepository()); - // TODO: CONTAINER_IMAGE_TAG has been replaced with CONTAINER_IMAGE_TAGS attrBuilders.put( - io.opentelemetry.semconv.ResourceAttributes.CONTAINER_IMAGE_TAG, + io.opentelemetry.contrib.aws.resource.IncubatingAttributes.CONTAINER_IMAGE_TAGS, parsedImage.getTag()); } break; diff --git a/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource/IncubatingAttributes.java b/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource/IncubatingAttributes.java index c973b50f5..91349a677 100644 --- a/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource/IncubatingAttributes.java +++ b/aws-resources/src/main/java/io/opentelemetry/contrib/aws/resource/IncubatingAttributes.java @@ -26,6 +26,8 @@ private IncubatingAttributes() {} public static final AttributeKey CLOUD_REGION = AttributeKey.stringKey("cloud.region"); public static final AttributeKey CLOUD_RESOURCE_ID = AttributeKey.stringKey("cloud.resource_id"); + public static final AttributeKey> CONTAINER_IMAGE_TAGS = + AttributeKey.stringArrayKey("container.image.tags"); public static final class CloudPlatformIncubatingValues { public static final String AWS_EC2 = "aws_ec2"; diff --git a/aws-resources/src/test/java/io/opentelemetry/contrib/aws/resource/EcsResourceTest.java b/aws-resources/src/test/java/io/opentelemetry/contrib/aws/resource/EcsResourceTest.java index a2ad79d00..3df9f30e7 100644 --- a/aws-resources/src/test/java/io/opentelemetry/contrib/aws/resource/EcsResourceTest.java +++ b/aws-resources/src/test/java/io/opentelemetry/contrib/aws/resource/EcsResourceTest.java @@ -24,7 +24,9 @@ import static io.opentelemetry.semconv.incubating.CloudIncubatingAttributes.CLOUD_RESOURCE_ID; import static io.opentelemetry.semconv.incubating.ContainerIncubatingAttributes.CONTAINER_ID; import static io.opentelemetry.semconv.incubating.ContainerIncubatingAttributes.CONTAINER_IMAGE_NAME; +import static io.opentelemetry.semconv.incubating.ContainerIncubatingAttributes.CONTAINER_IMAGE_TAGS; import static io.opentelemetry.semconv.incubating.ContainerIncubatingAttributes.CONTAINER_NAME; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.entry; import static org.mockito.Mockito.when; @@ -52,8 +54,6 @@ class EcsResourceTest { @Mock private SimpleHttpClient mockHttpClient; - // Suppression is required for CONTAINER_IMAGE_TAG until we are ready to upgrade. - @SuppressWarnings("deprecation") @Test void testCreateAttributesV3() throws IOException { Map mockSysEnv = new HashMap<>(); @@ -78,7 +78,7 @@ void testCreateAttributesV3() throws IOException { entry(CONTAINER_NAME, "ecs-nginx-5-nginx-curl-ccccb9f49db0dfe0d901"), entry(CONTAINER_ID, "43481a6ce4842eec8fe72fc28500c6b52edcc0917f105b83379f88cac1ff3946"), entry(CONTAINER_IMAGE_NAME, "nrdlngr/nginx-curl"), - entry(io.opentelemetry.semconv.ResourceAttributes.CONTAINER_IMAGE_TAG, "latest"), + entry(CONTAINER_IMAGE_TAGS, singletonList("latest")), entry(AWS_ECS_CLUSTER_ARN, "arn:aws:ecs:us-east-2:012345678910:cluster/default"), entry( AttributeKey.stringKey("aws.ecs.container.image.id"), @@ -90,8 +90,6 @@ void testCreateAttributesV3() throws IOException { entry(AWS_ECS_TASK_REVISION, "5")); } - // Suppression is required for CONTAINER_IMAGE_TAG until we are ready to upgrade. - @SuppressWarnings("deprecation") @Test void testCreateAttributesV4() throws IOException { Map mockSysEnv = new HashMap<>(); @@ -119,7 +117,7 @@ void testCreateAttributesV4() throws IOException { entry(CONTAINER_NAME, "ecs-curltest-26-curl-cca48e8dcadd97805600"), entry(CONTAINER_ID, "ea32192c8553fbff06c9340478a2ff089b2bb5646fb718b4ee206641c9086d66"), entry(CONTAINER_IMAGE_NAME, "111122223333.dkr.ecr.us-west-2.amazonaws.com/curltest"), - entry(io.opentelemetry.semconv.ResourceAttributes.CONTAINER_IMAGE_TAG, "latest"), + entry(CONTAINER_IMAGE_TAGS, singletonList("latest")), entry( AttributeKey.stringKey("aws.ecs.container.image.id"), "sha256:d691691e9652791a60114e67b365688d20d19940dde7c4736ea30e660d8d3553"), @@ -127,17 +125,14 @@ void testCreateAttributesV4() throws IOException { entry( AWS_ECS_CONTAINER_ARN, "arn:aws:ecs:us-west-2:111122223333:container/0206b271-b33f-47ab-86c6-a0ba208a70a9"), - entry(AWS_LOG_GROUP_NAMES, Collections.singletonList("/ecs/metadata")), + entry(AWS_LOG_GROUP_NAMES, singletonList("/ecs/metadata")), entry( AWS_LOG_GROUP_ARNS, - Collections.singletonList( - "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata")), - entry( - AWS_LOG_STREAM_NAMES, - Collections.singletonList("ecs/curl/8f03e41243824aea923aca126495f665")), + singletonList("arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata")), + entry(AWS_LOG_STREAM_NAMES, singletonList("ecs/curl/8f03e41243824aea923aca126495f665")), entry( AWS_LOG_STREAM_ARNS, - Collections.singletonList( + singletonList( "arn:aws:logs:us-west-2:111122223333:log-group:/ecs/metadata:log-stream:ecs/curl/8f03e41243824aea923aca126495f665")), entry( AWS_ECS_TASK_ARN, diff --git a/dependencyManagement/build.gradle.kts b/dependencyManagement/build.gradle.kts index 9f344d415..cb83c7ade 100644 --- a/dependencyManagement/build.gradle.kts +++ b/dependencyManagement/build.gradle.kts @@ -2,7 +2,7 @@ plugins { `java-platform` } -val otelInstrumentationVersion = "2.12.0-alpha" +val otelInstrumentationVersion = "2.13.0-alpha" val semconvVersion = "1.30.0" javaPlatform { diff --git a/inferred-spans/src/test/java/io/opentelemetry/contrib/inferredspans/internal/util/OtelReflectionUtils.java b/inferred-spans/src/test/java/io/opentelemetry/contrib/inferredspans/internal/util/OtelReflectionUtils.java index 36a442cd5..45fe3043f 100644 --- a/inferred-spans/src/test/java/io/opentelemetry/contrib/inferredspans/internal/util/OtelReflectionUtils.java +++ b/inferred-spans/src/test/java/io/opentelemetry/contrib/inferredspans/internal/util/OtelReflectionUtils.java @@ -7,7 +7,6 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.events.GlobalEventLoggerProvider; import io.opentelemetry.api.trace.TracerProvider; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.trace.SdkTracerProvider; @@ -42,7 +41,6 @@ public static void shutdownAndResetGlobalOtel() { OpenTelemetrySdk sdk = (OpenTelemetrySdk) readField(otel, "delegate"); sdk.close(); GlobalOpenTelemetry.resetForTest(); - GlobalEventLoggerProvider.resetForTest(); } } diff --git a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/JmxConnectionTest.java b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/JmxConnectionTest.java index 462af5087..9c813398b 100644 --- a/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/JmxConnectionTest.java +++ b/jmx-scraper/src/integrationTest/java/io/opentelemetry/contrib/jmxscraper/JmxConnectionTest.java @@ -9,6 +9,7 @@ import java.nio.file.Path; import java.security.cert.X509Certificate; +import java.util.concurrent.TimeUnit; import java.util.function.Function; import org.junit.jupiter.api.AfterAll; import org.junit.jupiter.api.BeforeAll; @@ -191,18 +192,17 @@ private static void checkConnectionLogs(JmxScraperContainer scraper, boolean exp } private static void waitTerminated(GenericContainer container) { - int retries = 10; - while (retries > 0 && container.isRunning()) { - retries--; + long retryUntil = System.currentTimeMillis() + TimeUnit.SECONDS.toMillis(10); + while (container.isRunning() && System.currentTimeMillis() < retryUntil) { try { - Thread.sleep(100); + TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { throw new RuntimeException(e); } } - assertThat(retries) + assertThat(container.isRunning()) .describedAs("container should stop when testing connection") - .isNotEqualTo(0); + .isFalse(); } private static JmxScraperContainer scraperContainer() { diff --git a/processors/src/main/java/io/opentelemetry/contrib/eventbridge/EventToSpanEventBridge.java b/processors/src/main/java/io/opentelemetry/contrib/eventbridge/EventToSpanEventBridge.java index 18c533ced..c048b7939 100644 --- a/processors/src/main/java/io/opentelemetry/contrib/eventbridge/EventToSpanEventBridge.java +++ b/processors/src/main/java/io/opentelemetry/contrib/eventbridge/EventToSpanEventBridge.java @@ -17,6 +17,7 @@ import io.opentelemetry.sdk.logs.LogRecordProcessor; import io.opentelemetry.sdk.logs.ReadWriteLogRecord; import io.opentelemetry.sdk.logs.data.LogRecordData; +import io.opentelemetry.sdk.logs.data.internal.ExtendedLogRecordData; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.nio.charset.StandardCharsets; @@ -56,7 +57,6 @@ public final class EventToSpanEventBridge implements LogRecordProcessor { private static final Logger logger = Logger.getLogger(EventToSpanEventBridge.class.getName()); - private static final AttributeKey EVENT_NAME = AttributeKey.stringKey("event.name"); private static final AttributeKey LOG_RECORD_OBSERVED_TIME_UNIX_NANO = AttributeKey.longKey("log.record.observed_time_unix_nano"); private static final AttributeKey LOG_RECORD_SEVERITY_NUMBER = @@ -76,7 +76,10 @@ public static EventToSpanEventBridge create() { @Override public void onEmit(Context context, ReadWriteLogRecord logRecord) { LogRecordData logRecordData = logRecord.toLogRecordData(); - String eventName = logRecordData.getAttributes().get(EVENT_NAME); + if (!(logRecordData instanceof ExtendedLogRecordData)) { + return; + } + String eventName = ((ExtendedLogRecordData) logRecordData).getEventName(); if (eventName == null) { return; } @@ -99,8 +102,7 @@ public void onEmit(Context context, ReadWriteLogRecord logRecord) { } private static Attributes toSpanEventAttributes(LogRecordData logRecord) { - AttributesBuilder builder = - logRecord.getAttributes().toBuilder().removeIf(key -> key.equals(EVENT_NAME)); + AttributesBuilder builder = logRecord.getAttributes().toBuilder(); builder.put(LOG_RECORD_OBSERVED_TIME_UNIX_NANO, logRecord.getObservedTimestampEpochNanos()); diff --git a/processors/src/test/java/io/opentelemetry/contrib/eventbridge/EventToSpanEventBridgeTest.java b/processors/src/test/java/io/opentelemetry/contrib/eventbridge/EventToSpanEventBridgeTest.java index b45e36b44..6e6ed3cb4 100644 --- a/processors/src/test/java/io/opentelemetry/contrib/eventbridge/EventToSpanEventBridgeTest.java +++ b/processors/src/test/java/io/opentelemetry/contrib/eventbridge/EventToSpanEventBridgeTest.java @@ -9,9 +9,11 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey; import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat; +import io.opentelemetry.api.common.AttributeKey; import io.opentelemetry.api.common.Attributes; +import io.opentelemetry.api.common.KeyValue; import io.opentelemetry.api.common.Value; -import io.opentelemetry.api.incubator.events.EventLogger; +import io.opentelemetry.api.incubator.logs.ExtendedLogger; import io.opentelemetry.api.logs.Severity; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; @@ -22,7 +24,6 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; import io.opentelemetry.sdk.logs.SdkLoggerProvider; -import io.opentelemetry.sdk.logs.internal.SdkEventLoggerProvider; import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter; import io.opentelemetry.sdk.testing.time.TestClock; import io.opentelemetry.sdk.trace.IdGenerator; @@ -46,14 +47,13 @@ class EventToSpanEventBridgeTest { .addSpanProcessor(SimpleSpanProcessor.create(spanExporter)) .build(); private final TestClock testClock = TestClock.create(); - private final SdkEventLoggerProvider eventLoggerProvider = - SdkEventLoggerProvider.create( - SdkLoggerProvider.builder() - .setClock(testClock) - .addLogRecordProcessor(EventToSpanEventBridge.create()) - .build()); + private final SdkLoggerProvider loggerProvider = + SdkLoggerProvider.builder() + .setClock(testClock) + .addLogRecordProcessor(EventToSpanEventBridge.create()) + .build(); private final Tracer tracer = tracerProvider.get("tracer"); - private final EventLogger eventLogger = eventLoggerProvider.get("event-logger"); + private final ExtendedLogger logger = (ExtendedLogger) loggerProvider.get("event-logger"); private static Sampler onlyServerSpans() { return new Sampler() { @@ -85,15 +85,18 @@ void withRecordingSpan_BridgesEvent() { // others. We create a recording span by setting kind to SERVER. Span span = tracer.spanBuilder("span").setSpanKind(SpanKind.SERVER).startSpan(); try (Scope unused = span.makeCurrent()) { - eventLogger - .builder("my.event-name") + logger + .logRecordBuilder() + .setEventName("my.event-name") .setTimestamp(100, TimeUnit.NANOSECONDS) .setSeverity(Severity.DEBUG) - .put("foo", "bar") - .put("number", 1) - .put("map", Value.of(Collections.singletonMap("key", Value.of("value")))) - .setAttributes(Attributes.builder().put("color", "red").build()) - .setAttributes(Attributes.builder().put("shape", "square").build()) + .setBody( + Value.of( + KeyValue.of("number", Value.of(1)), + KeyValue.of("foo", Value.of("bar")), + KeyValue.of("map", Value.of(Collections.singletonMap("key", Value.of("value")))))) + .setAttribute(AttributeKey.stringKey("color"), "red") + .setAttribute(AttributeKey.stringKey("shape"), "square") .emit(); } finally { span.end(); @@ -134,15 +137,18 @@ void nonRecordingSpan_doesNotBridgeEvent() { // others. We create a non-recording span by setting kind to INTERNAL. Span span = tracer.spanBuilder("span").setSpanKind(SpanKind.INTERNAL).startSpan(); try (Scope unused = span.makeCurrent()) { - eventLogger - .builder("my.event-name") + logger + .logRecordBuilder() + .setEventName("my.event-name") .setTimestamp(100, TimeUnit.NANOSECONDS) .setSeverity(Severity.DEBUG) - .put("foo", "bar") - .put("number", 1) - .put("map", Value.of(Collections.singletonMap("key", Value.of("value")))) - .setAttributes(Attributes.builder().put("color", "red").build()) - .setAttributes(Attributes.builder().put("shape", "square").build()) + .setBody( + Value.of( + KeyValue.of("number", Value.of(1)), + KeyValue.of("foo", Value.of("bar")), + KeyValue.of("map", Value.of(Collections.singletonMap("key", Value.of("value")))))) + .setAttribute(AttributeKey.stringKey("color"), "red") + .setAttribute(AttributeKey.stringKey("shape"), "square") .emit(); } finally { span.end(); @@ -158,8 +164,9 @@ void differentSpanContext_doesNotBridgeEvent() { // others. We create a recording span by setting kind to SERVER. Span span = tracer.spanBuilder("span").setSpanKind(SpanKind.SERVER).startSpan(); try (Scope unused = span.makeCurrent()) { - eventLogger - .builder("my.event-name") + logger + .logRecordBuilder() + .setEventName("my.event-name") // Manually override the context .setContext( Span.wrap( @@ -171,11 +178,13 @@ void differentSpanContext_doesNotBridgeEvent() { .storeInContext(Context.current())) .setTimestamp(100, TimeUnit.NANOSECONDS) .setSeverity(Severity.DEBUG) - .put("foo", "bar") - .put("number", 1) - .put("map", Value.of(Collections.singletonMap("key", Value.of("value")))) - .setAttributes(Attributes.builder().put("color", "red").build()) - .setAttributes(Attributes.builder().put("shape", "square").build()) + .setBody( + Value.of( + KeyValue.of("number", Value.of(1)), + KeyValue.of("foo", Value.of("bar")), + KeyValue.of("map", Value.of(Collections.singletonMap("key", Value.of("value")))))) + .setAttribute(AttributeKey.stringKey("color"), "red") + .setAttribute(AttributeKey.stringKey("shape"), "square") .emit(); } finally { span.end(); @@ -187,15 +196,18 @@ void differentSpanContext_doesNotBridgeEvent() { @Test void noSpan_doesNotBridgeEvent() { - eventLogger - .builder("my.event-name") + logger + .logRecordBuilder() + .setEventName("my.event-name") .setTimestamp(100, TimeUnit.NANOSECONDS) .setSeverity(Severity.DEBUG) - .put("foo", "bar") - .put("number", 1) - .put("map", Value.of(Collections.singletonMap("key", Value.of("value")))) - .setAttributes(Attributes.builder().put("color", "red").build()) - .setAttributes(Attributes.builder().put("shape", "square").build()) + .setBody( + Value.of( + KeyValue.of("number", Value.of(1)), + KeyValue.of("foo", Value.of("bar")), + KeyValue.of("map", Value.of(Collections.singletonMap("key", Value.of("value")))))) + .setAttribute(AttributeKey.stringKey("color"), "red") + .setAttribute(AttributeKey.stringKey("shape"), "square") .emit(); assertThat(spanExporter.getFinishedSpanItems()).isEmpty();